<?xml version="1.0" encoding="UTF-8"?>
<!--
 Authors: Jsoftware, Ric Sherlock 

 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="j" _name="J" version="2.0" _section="Sources">
    <metadata>
      <property name="mimetypes">text/x-j;text/x-jsrc</property>
      <property name="globs">*.ijs</property>
      <property name="line-comment-start">NB\.</property>
    </metadata>

    <styles>
      <style id="adverb"    _name="Adverb"            />
      <style id="comment"   _name="Comment"           />
      <style id="conjunction" _name="Conjunction"     />
      <style id="control"   _name="Control"           />
      <style id="error"     _name="Error"             />
      <style id="exparg"    _name="Explicit Argument" />
      <style id="global"    _name="Global"            />
      <style id="labtext"   _name="Lab Text"          />
      <style id="local"     _name="Local"             />
      <style id="noun"      _name="Noun"              />
      <style id="noundef"   _name="Explicit Noun Def" />
      <style id="number"    _name="Number"            />
      <style id="parens"    _name="Parens"            />
      <style id="primitive" _name="Primitive"         />
      <style id="string"    _name="String"            />
      <style id="verb"      _name="Verb"              />
    </styles>

    <definitions>
        <!-- Problems/shortcomings
        * How to target parens inside expdef
        * Matched vs unmatched parens coloring but how to do () and not {} and []
        -->

        <!-- NB. (Comments) -->
        <context id="comment" style-ref="comment" end-at-line-end="true">
          <start>\%[NB\.</start>
        </context>

        <!-- 'abcde' (Strings) -->  
        <context id="string" style-ref="string" end-at-line-end="true">
          <start>L?'</start><end>'</end>
        </context>

        <!-- Unbalanced single quotes -->
        <context id="error" style-ref="error">
          <match>'[^']*?$</match>
        </context>
          
        <!-- 2.34 (Numbers) -->
        <context id="number" style-ref="number">
          <match extended="true">\%[[_0-9][_0-9\.a-zA-Z]*\%]</match>
        </context>

        <!-- Nouns -->
        <context id="noun" style-ref="noun">
          <match extended="true">
            \%[(_\.|a\.|a:)(?![\.\:])
          </match>
        </context>

        <!-- Verbs -->
        <context id="verb" style-ref="verb">
          <match extended="true">
              ((_?[0-9]:)|
              (\%[p\.\.)|              
              (\%[[AcCeEiIjLopr]\.)|
              (\%[[ipqsux]:)|
              ({::)|
              ([&lt;&gt;\+\*\-\%\^\$\~\|\,\#\{\}&quot;\?]\.)|
              ([&lt;&gt;\_\+\*\-\%\$\~\|\,\;\#\/\\\[\{\}&quot;]:)|
              ([&lt;&gt;\=\+\*\-\%\^\$\|\,\;\#\!\[\]\{\?]))
              (?![\.\:])
            </match>
          </context>

        <!-- Adverbs -->
        <context id="adverb" style-ref="adverb">
          <match extended="true">
            (([\/\\]\.)| 
             (\%[[bfMt]\.)|
             (\%[t:)|
             ([\~\/\\\}]))
            (?![\.\:])
          </match>
        </context>

        <!-- Conjunctions -->
        <context id="conjunction" style-ref="conjunction">
          <match extended="true">
            ((\%[[dDHT]\.)|
             (\%[[DLS]:)|
             (&amp;\.:)|
             ([\;\!\@&amp;]\.)|
             ([\^\!\`\@&amp;]:)|
             ([\"\`\@&amp;])|
             (\s[\.\:][\.\:])|
             (\s[\.\:]))
            (?![\.\:])
          </match>
        </context>

        <!-- () (Parentheses) -->
        <context id="parens" style-ref="parens">
          <match>[\(\)]</match>
        </context>

        <!-- Explicit arguments -->
        <context id="exparg" style-ref="exparg">
          <match extended="true">\%[[nmuvxy](?![\w\.\:])</match>
        </context>

        <define-regex id="valid-name">[a-zA-Z][a-zA-Z0-9_]*</define-regex>
        <define-regex id="close-expdef">^\s*\)\s*$</define-regex>

        <!-- if. do. end. (Control words) -->
        <context id="control" style-ref="control">
          <prefix>\%[</prefix>
          <suffix>(?![\.\:])</suffix>
          <keyword>assert\.</keyword>
          <keyword>break\.</keyword>
          <keyword>continue\.</keyword>
          <keyword>return\.</keyword>
          <keyword>do\.</keyword>
          <keyword>if\.</keyword>
          <keyword>else\.</keyword>
          <keyword>elseif\.</keyword>
          <keyword>end\.</keyword>
          <keyword>for\.</keyword>
          <keyword>select\.</keyword>
          <keyword>case\.</keyword>
          <keyword>fcase\.</keyword>
          <keyword>throw\.</keyword>
          <keyword>try\.</keyword>
          <keyword>catch\.</keyword>
          <keyword>catchd\.</keyword>
          <keyword>catcht\.</keyword>
          <keyword>while\.</keyword>
          <keyword>whilst\.</keyword>
          <keyword>for_\%{valid-name}?\.</keyword>
          <keyword>goto_\%{valid-name}?\.</keyword>
          <keyword>label_\%{valid-name}?\.</keyword>
        </context>

        <!-- Explicit definition -->
        <context id="expdef" style-inside="true">
          <start>\%[(([1-4]|13)\s+:\s*0)|((adverb|conjunction|verb|monad|dyad)\s+define)\%]</start>
          <end>\%{close-expdef}</end>
          <include>
            <context ref="comment"/>
            <context ref="error"/>
            <context ref="exparg"/>
            <context ref="global"/>
            <context ref="local"/>
            <context ref="noun"/>
            <context ref="verb"/>
            <context ref="adverb"/>
            <context ref="conjunction"/>
            <context ref="string"/>
            <context ref="number"/>
            <context ref="control"/>
          </include>
        </context>
 
        <!-- Explicit noun definition -->
        <context id="noundef" style-ref="noundef" style-inside="true">
          <start>\%[(0\s+:\s*0|noun\s+define)\%].*$</start>
          <end>\%{close-expdef}</end>
        </context>
 
        <!-- Lab text definition -->
        <context id="labtext" style-ref="labtext">
          <start>^\s*[\x{2500}|-]{2,}</start>
          <end>\%{close-expdef}</end>
        </context>

        <!-- Note (Multiline comment) -->
        <context id="notes" style-ref="comment" style-inside="true">
          <start>^\s*\%[Note\%](?!\s*\=[:.])\s*['\d].*$</start>
          <end>\%{close-expdef}</end>
        </context>

        <!-- Note (to end-of-line comment) -->
        <context id="note" style-ref="comment" end-at-line-end="true">
          <start>\%[Note\%](?!\s*\=[:.])\s*['\d].*$</start>
        </context>

        <!-- =: (Global assignment) -->
        <context id="global" style-ref="global">
          <match>=:</match>
        </context>

        <!-- =. (Local assignment) -->
        <context id="local" style-ref="local">
          <match>=\.</match>
        </context>

      <context id="j">
        <include>
           <context ref="comment"/>
           <context ref="error"/>
           <context ref="string"/>
           <context ref="global"/>
           <context ref="local"/>
           <context ref="noun"/>
           <context ref="verb"/>
           <context ref="adverb"/>
           <context ref="conjunction"/>
           <context ref="expdef"/>
           <context ref="noundef"/>
           <context ref="labtext"/>
           <context ref="note"/>
           <context ref="notes"/>
           <context ref="parens"/>
           <context ref="number"/>
        </include>
      </context>
    </definitions>
</language>
