<?xml version="1.0" encoding="UTF-8"?>
<!--
 Author: Finn Teegen
 Copyright (c) 2016-2017 Finn Teegen <fte@informatik.uni-kiel.de>
-->
<language id="curry" _name="Curry" version="2.0" _section="Source">
  <metadata>
    <property name="mimetypes">text/x-curry</property>
    <property name="globs">*.curry</property>
    <property name="line-comment-start">--</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="float"        _name="Float"        map-to="def:floating-point"/>
    <style id="decimal"      _name="Decimal"      map-to="def:decimal"/>
    <style id="octal"        _name="Octal"        map-to="def:base-n-integer"/>
    <style id="hexadecimal"  _name="Hex"          map-to="def:base-n-integer"/>
    <style id="binary"       _name="Bin"          map-to="def:base-n-integer"/>
  </styles>
  <definitions>
    <!-- See: https://www-ps.informatik.uni-kiel.de/currywiki/documentation/report -->
    <define-regex id="symbolchar">[~!@#$%^&amp;*+-=&lt;&gt;?./|\\:]</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"/>
      </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="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>
    <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
        b[0-1]+ |             # 'b' followed by binary 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="float" style-ref="float">
      <match extended="true">
          [0-9]+ \. [0-9]+ ([eE][+-]?[0-9]+)?
        | [0-9]+            [eE][+-]?[0-9]+
      </match>
    </context>
    <context id="hexadecimal" style-ref="hexadecimal">
      <match>0[xX][0-9a-fA-F]+</match>
    </context>
    <context id="octal" style-ref="octal">
      <match>0[oO][0-7]+</match>
    </context>
    <context id="decimal" style-ref="decimal">
      <match>[0-9]+</match>
    </context>
    <context id="binary" style-ref="binary">
      <match>0[bB][0-1]+</match>
    </context>
    <context id="keyword" style-ref="keyword">
      <keyword>case</keyword>
      <keyword>class</keyword>
      <keyword>data</keyword>
      <keyword>default</keyword>
      <keyword>deriving</keyword>
      <keyword>do</keyword>
      <keyword>else</keyword>
      <keyword>external</keyword>
      <keyword>fcase</keyword>
      <keyword>forall</keyword>
      <keyword>free</keyword>
      <keyword>hiding</keyword>
      <keyword>if</keyword>
      <keyword>import</keyword>
      <keyword>in</keyword>
      <keyword>infix</keyword>
      <keyword>infixl</keyword>
      <keyword>infixr</keyword>
      <keyword>instance</keyword>
      <keyword>let</keyword>
      <keyword>module</keyword>
      <keyword>newtype</keyword>
      <keyword>of</keyword>
      <keyword>qualified</keyword>
      <keyword>then</keyword>
      <keyword>type</keyword>
      <keyword>where</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="float"/>
        <context ref="hexadecimal"/>
        <context ref="octal"/>
        <context ref="decimal"/>
        <context ref="binary"/>
      </include>
    </context>
    <context id="curry" class="no-spell-check">
      <include>
        <context ref="c:preprocessor"/>
        <context ref="body"/>
      </include>
    </context>
  </definitions>
</language>
