<lexer>
  <config>
    <name>microcad</name>
    <alias>µcad</alias>
    <filename>*.µcad</filename>
    <filename>*.ucad</filename>
    <filename>*.mcad</filename>
    <mime_type>text/microcad</mime_type>
    <ensure_nl>true</ensure_nl>
  </config>

  <rules>
    <!-- Root state -->
    <state name="root">
      <rule pattern="\n">
        <token type="TextWhitespace"/>
      </rule>
      <rule pattern="\s+">
        <token type="TextWhitespace"/>
      </rule>

      <!-- COMMENTS -->
      <rule pattern="///.*">
        <token type="LiteralStringDoc"/>
      </rule>

      <rule pattern="//.*">
        <token type="CommentSingle"/>
      </rule>

      <rule pattern="/\*.*">
        <token type="CommentMultiline"/>
        <push state="comment"/>
      </rule>

      <!-- KEYWORDS -->
      <rule pattern="\b(pub|sketch|part|op|mod|use|fn|const|prop|init|return|if|else|mat|__builtin|or|and|not|as)\b">
        <token type="Keyword"/>
      </rule>

      <!-- TYPES -->
      <rule pattern="\b(Integer|Scalar|String|Color|Length|Area|Volume|Angle|Weight|Density|Bool|Matrix[0-9])\b">
        <token type="KeywordType"/>
      </rule>

      <!-- FUNCTION NAMES -->
      <rule pattern="\b([a-z_][a-zA-Z0-9_]*)\s*(?=\()">
        <token type="NameFunction"/>
      </rule>

      <!-- OPERATORS -->
      <rule pattern="[+\-*/%&amp;|&lt;&gt;^!@=]">
        <token type="Operator"/>
      </rule>

      <!-- NUMBERS + UNITS -->
      <rule pattern="\b(([0-9]+(\.[0-9]+)?)(%|m²|cm²|mm²|µm²|in²|ft²|yd²|m³|cm³|mm³|µm³|in³|ft³|yd³|ml|cl|l|µl|cm|mm|m|µm|in|ft|yd|deg|°|grad|turn|rad|g|kg|lb|oz)?)|true|false\b">
        <token type="LiteralNumber"/>
      </rule>

      <!-- NAMESPACES -->
      <rule pattern="([a-z_][a-z0-9_]*)(::)">
        <bygroups>
          <token type="NameNamespace"/>
          <token type="Operator"/>
        </bygroups>
      </rule>

      <!-- CONSTANTS (ALL CAPS) -->
      <rule pattern="\b([A-Z_][A-Z0-9_]*)\b">
        <token type="NameConstant"/>
      </rule>

      <!-- CUSTOM TYPES (Capitalized identifiers) -->
      <rule pattern="\b([A-Z_][a-zA-Z0-9_]*)\b">
        <token type="NameClass"/>
      </rule>

      <!-- VARIABLES -->
      <rule pattern="\b([a-z_][a-zA-Z0-9_]*)\b">
        <token type="Name"/>
      </rule>

      <!-- STRINGS -->
      <rule pattern="&quot;[^&quot;]*&quot;">
        <token type="LiteralString"/>
      </rule>

      <!-- PAREN GROUP -->
      <rule pattern="[{}()\[\],.;:]">
        <token type="Punctuation"/>
      </rule>


      <!-- BRACE GROUP -->
      <rule pattern="\{">
        <token type="Punctuation"/>
        <push state="brace"/>
      </rule>

      <rule pattern="[\}\)]">
        <token type="Punctuation"/>
      </rule>

    </state>

    <!-- Parenthesized expression -->
    <state name="paren">
      <rule pattern="\)">
        <token type="Punctuation"/>
        <pop/>
      </rule>
      <rule>
        <include state="root"/>
      </rule>
    </state>

    <!-- Braced expression -->
    <state name="brace">
      <rule pattern="\}">
        <token type="Punctuation"/>
        <pop/>
      </rule>
      <rule>
        <include state="root"/>
      </rule>
    </state>

    <state name="comment">
      <!-- End of comment -->
      <rule pattern="\*/">
        <token type="CommentMultiline"/>
        <pop/>
      </rule>
    </state>


  </rules>
</lexer>
