<?xml version="1.0" encoding="UTF-8"?>
<!--

 Author: John J. Camilleri
 Copyright (C) 2011, John J. Camilleri
 Based on haskell.lang by Duncan Coutts <duncan@haskell.org> and Anders Carlsson <andersca@gnome.org>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.

 You should have received a copy of the GNU Library General Public
 License along with this library; if not, write to the
 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.

-->
<language id="gf" _name="Grammatical Framework" version="2.0" _section="Sources">
  <metadata>
    <property name="mimetypes">text/x-gf;text/plain</property>
    <property name="globs">*.gf</property>
  </metadata>

  <styles>
    <style id="preprocessor" _name="Preprocessor" map-to="def:preprocessor"/>
    <style id="comment"      _name="Comment"      map-to="def:comment"/>
    <style id="variable"     _name="Variable"                         />
    <style id="symbol"       _name="Symbol"                           />
    <style id="keyword"      _name="Keyword"      map-to="def:keyword"/>
    <style id="type"         _name="Data Type"    map-to="def:type"/>
    <style id="string"       _name="String"       map-to="def:string"/>
    <style id="character"    _name="Character"    map-to="def:character"/>
    <style id="char-escape"  _name="Escaped Character" map-to="def:special-char"/>
    <style id="decimal"      _name="Decimal"      map-to="def:decimal"/>
  </styles>

  <definitions>

    <define-regex id="symbolchar">[!#$%&amp;*+./&gt;=&lt;?@:\\^|~-]</define-regex>

    <context id="line-comment" style-ref="comment" end-at-line-end="true" class="comment" class-disabled="no-spell-check">
      <start>(?&lt;!\%{symbolchar})--+(?!\%{symbolchar})</start>
      <include>
        <context ref="def:in-comment"/>
        <context ref="haddock:line-paragraph"/>
        <context ref="haddock:directive"/>
      </include>
    </context>

    <context id="block-comment" style-ref="comment" class="comment" class-disabled="no-spell-check">
      <start>\{-</start>
      <end>-\}</end>
      <include>
        <context ref="def:in-comment"/>
        <context ref="haddock:block-paragraph"/>
        <context ref="haddock:directive"/>
        <context ref="block-comment"/>
      </include>
    </context>

    <context id="pragma" style-ref="preprocessor">
      <start>\{-#</start>
      <end>#-\}</end>
    </context>

    <context id="variable" style-ref="variable">
      <match>\b[a-z_][0-9a-zA-Z_'#]*</match>
    </context>

    <context id="type-or-constructor" style-ref="type">
      <match>\b[A-Z][0-9a-zA-Z._'#]*</match>
    </context>

    <!-- Must not extend parent context, or we end up matching
         "\end{code}" as part of the Haskell context, but when in
         literate haskell mode it should be terminating a code block. -->
    <context id="symbol" style-ref="symbol" extend-parent="false">
      <match>\%{symbolchar}+</match>
    </context>

    <context id="keysymbol" style-ref="keyword">
      <prefix>(?&lt;!\%{symbolchar})</prefix>
      <suffix>(?!\%{symbolchar})</suffix>
      <keyword>\.\.</keyword>
      <keyword>::</keyword>
      <keyword>=</keyword>
      <keyword>\|</keyword>
      <keyword>\</keyword>
      <keyword>-&gt;</keyword>
      <keyword>&lt;-</keyword>
      <keyword>@</keyword>
      <keyword>~</keyword>
      <keyword>=&gt;</keyword>
    </context>

    <define-regex id="escaped-character" extended="true">
        \\(                   # leading backslash
        [abfnrtv\\"\'&amp;] | # escaped character
         [0-9]+ |             # decimal digits
        o[0-7]+ |             # 'o' followed by octal digits
        x[0-9A-Fa-f]+ |       # 'x' followed by hex digits
        \^[A-Z@\[\\\]^_] |    # control character codes
        NUL | SOH | STX | ETX | EOT | ENQ | ACK |
        BEL | BS | HT | LF | VT | FF | CR | SO |
        SI | DLE | DC1 | DC2 | DC3 | DC4 | NAK |
        SYN | ETB | CAN | EM | SUB | ESC | FS | GS |
        RS | US | SP | DEL    # control char names
        )
    </define-regex>

    <context id="string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
      <start>"</start>
      <end>"</end>
      <include>
        <context ref="def:line-continue"/>
        <context style-ref="char-escape">
          <match>\%{escaped-character}</match>
        </context>
      </include>
    </context>

    <context id="char" style-ref="character" end-at-line-end="true">
      <start>'</start>
      <end>'</end>
      <include>
        <context style-ref="char-escape" once-only="true">
          <match>\%{escaped-character}</match>
        </context>
        <context once-only="true" extend-parent="false">
          <match>.</match>
        </context>
        <context style-ref="def:error" extend-parent="false">
          <match>.</match>
        </context>
      </include>
    </context>

    <context id="decimal" style-ref="decimal">
      <match>[0-9]+</match>
    </context>

    <context id="keyword" style-ref="keyword">
		<keyword>PType</keyword>
		<keyword>Str</keyword>
		<keyword>Strs</keyword>
		<keyword>Type</keyword>
		<keyword>abstract</keyword>
		<keyword>case</keyword>
		<keyword>cat</keyword>
		<keyword>concrete</keyword>
		<keyword>data</keyword>
		<keyword>def</keyword>
		<keyword>flags</keyword>
		<keyword>fun</keyword>
		<keyword>in</keyword>
		<keyword>incomplete</keyword>
		<keyword>instance</keyword>
		<keyword>interface</keyword>
		<keyword>let</keyword>
		<keyword>lin</keyword>
		<keyword>lincat</keyword>
		<keyword>lindef</keyword>
		<keyword>of</keyword>
		<keyword>open</keyword>
		<keyword>oper</keyword>
		<keyword>param</keyword>
		<keyword>pre</keyword>
		<keyword>printname</keyword>
		<keyword>resource</keyword>
		<keyword>strs</keyword>
		<keyword>table</keyword>
		<keyword>transfer</keyword>
		<keyword>variants</keyword>
		<keyword>where</keyword>
		<keyword>with</keyword>
    </context>

    <context id="body">
      <include>
        <context ref="line-comment"/>
        <context ref="pragma"/>
        <context ref="block-comment"/>
        <context ref="keyword"/>
        <context ref="variable"/>
        <context ref="type-or-constructor"/>
        <context ref="keysymbol"/>
        <context ref="symbol"/>
        <context ref="string"/>
        <context ref="char"/>
        <context ref="decimal"/>
      </include>
    </context>

    <context id="gf" class="no-spell-check">
      <include>
        <context ref="def:shebang"/>
        <context ref="c:if0-comment"/>
        <context ref="c:include"/>
        <context ref="c:preprocessor"/>
        <context ref="body"/>
      </include>
    </context>

  </definitions>
</language>