<lexer>
  <config>
    <name>RGBDS Assembly</name>
    <alias>rgbasm</alias>
    <filename>*.asm</filename>
    <priority>0.5</priority>
    <case_insensitive>true</case_insensitive>
  </config>
  <rules>
    <!-- Symbol state for parsing anything between curly brackets -->
    <state name="symbol">
      <rule pattern="[^{}]+">
        <token type="NameVariable"/>
      </rule>
      <rule pattern="{">
        <token type="Punctuation"/>
        <push state="symbol"/>
      </rule>
      <rule pattern="}">
        <token type="Punctuation"/>
        <pop depth="1"/>
      </rule>
    </state>
    <!-- String states for parsing quote-delimited text that may contain symbols -->
    <state name="string">
      <rule pattern="[^{&#34;\n\\]+">
        <token type="LiteralString"/>
      </rule>
      <rule pattern="\\.">
        <token type="LiteralStringEscape"/>
      </rule>
      <rule pattern="{">
        <token type="Punctuation"/>
        <push state="symbol"/>
      </rule>
      <rule pattern="(&#34;|\n)">
        <token type="LiteralString"/>
        <pop depth="1"/>
      </rule>
    </state>
    <state name="stringmultiline">
      <rule pattern="&#34;{3}">
        <token type="LiteralString"/>
        <pop depth="1"/>
      </rule>
      <rule pattern="[^{\\]+?">
        <token type="LiteralString"/>
      </rule>
      <rule pattern="\\.">
        <token type="LiteralStringEscape"/>
      </rule>
      <rule pattern="{">
        <token type="Punctuation"/>
        <push state="symbol"/>
      </rule>
    </state>
    <!-- Root state -->
    <state name="root">
      <!-- Comments -->
      <rule pattern=";.*?$">
        <token type="CommentSingle"/>
      </rule>
      <rule pattern="/[*](.|\n)*?[*]/">
        <token type="CommentMultiline"/>
      </rule>
      <!-- Local label -->
      <rule pattern="^(\.)(\w+)(:?)">
        <bygroups>
          <token type="Punctuation"/>
          <token type="NameLabel"/>
          <token type="Punctuation"/>
        </bygroups>
      </rule>
      <!-- Global label (with optional local) -->
      <rule pattern="(^\w+)(?:(\.)(\w+))?(::?)">
        <bygroups>
          <token type="NameLabel"/>
          <token type="Punctuation"/>
          <token type="NameLabel"/>
          <token type="Punctuation"/>
        </bygroups>
      </rule>
      <!-- Symbols delimited by curly brackets -->
      <rule pattern="{">
        <token type="Punctuation"/>
        <push state="symbol"/>
      </rule>
      <!-- Numeric types (can contain '_' except at the beginning) -->
      <rule pattern="(0x|\$)[0-9a-fA-F][0-9a-fA-F_]*">
        <token type="LiteralNumberHex"/>
      </rule>
      <rule pattern="[0-9a-fA-F][0-9a-fA-F_]*h\b">
        <token type="LiteralNumberHex"/>
      </rule>
      <rule pattern="(0o|&amp;)[0-7][0-7_]*">
        <token type="LiteralNumberOct"/>
      </rule>
      <rule pattern="(0b|%)[01][01_]*">
        <token type="LiteralNumberBin"/>
      </rule>
      <rule pattern="-?[0-9][0-9_]*\.[0-9_]+(q[0-9]+)?">
        <token type="LiteralNumberFloat"/>
      </rule>
      <rule pattern="-?[0-9][0-9_]*">
        <token type="LiteralNumberInteger"/>
      </rule>
      <!-- "Game Boy graphics" format, which can be made of user-defined symbols -->
      <rule pattern="`[^\s]+">
        <token type="LiteralNumberInteger"/>
      </rule>
      <!-- #-prefixed raw string (multiline) -->
      <rule pattern="(#)(&#34;{3}(?:.|\n)*?&#34;{3})">
        <bygroups>
          <token type="LiteralStringAffix"/>
          <token type="LiteralString"/>
        </bygroups>
      </rule>
      <!-- #-prefixed raw string -->
      <rule pattern="(#)(&#34;.*?&#34;)">
        <bygroups>
          <token type="LiteralStringAffix"/>
          <token type="LiteralString"/>
        </bygroups>
      </rule>
      <!-- Start of quote-delimited (non-raw) strings -->
      <rule pattern="&#34;{3}">
        <token type="LiteralString"/>
        <push state="stringmultiline"/>
      </rule>
      <rule pattern="&#34;">
        <token type="LiteralString"/>
        <push state="string"/>
      </rule>
      <!-- Macro arguments (single character) -->
      <rule pattern="\\[1-9@#]">
        <token type="NameVariableMagic"/>
      </rule>
      <!-- Macro arguments (bracketed) -->
      <rule pattern="(\\&lt;)([^&gt;]+)(&gt;)">
        <bygroups>
          <token type="NameVariableMagic"/>
          <usingself state="root"/>
          <token type="NameVariableMagic"/>
        </bygroups>
      </rule>
      <!-- LDI/LDD alternate formats -->
      <rule pattern="(\[)(hl\+|hl-|hli|hld)(\])">
        <bygroups>
          <token type="Punctuation"/>
          <token type="Keyword"/>
          <token type="Punctuation"/>
        </bygroups>
      </rule>
      <!-- Punctuation (excluding period which is used in predeclared symbols) -->
      <rule pattern="[\[\],()\\:]">
        <token type="Punctuation"/>
      </rule>
      <!-- Variable definitions that can contain RL, which is also an opcode -->
      <rule pattern="((?:re)?def)([\t ]+)([\w{}:]+)([\t ]+)(rb|rw|rl|equs|equ)?">
        <bygroups>
          <token type="NameBuiltin"/>
          <token type="TextWhitespace"/>
          <usingself state="root"/>
          <token type="TextWhitespace"/>
          <token type="NameBuiltin"/>
        </bygroups>
      </rule>
      <!-- Specific rule for some names that are both built-ins and functions -->
      <rule pattern="\b(bank|section)(\()\b">
        <bygroups>
          <token type="NameFunction"/>
          <token type="Punctuation"/>
        </bygroups>
      </rule>
      <!-- Specific rule for options redefinitions -->
      <rule pattern="\b(opt|pusho)([\t ]+)([^,\s]+)(?:(,)([\t ]*)([^,\s]+))*">
        <bygroups>
          <token type="NameBuiltin"/>
          <token type="TextWhitespace"/>
          <token type="Literal"/>
          <token type="Punctuation"/>
          <token type="TextWhitespace"/>
          <token type="Literal"/>
        </bygroups>
      </rule>
      <!-- Predeclared symbols -->
      <rule pattern="\b(_rs|_narg|__date__|__time__|__iso_8601_local__|__iso_8601_utc__|__utc_year__|__utc_month__|__utc_day__|__utc_hour__|__utc_minute__|__utc_second__|__rgbds_major__|__rgbds_minor__|__rgbds_patch__|__rgbds_rc__|__rgbds_version__)\b">
        <token type="NameVariableMagic"/>
      </rule>
      <!-- Built-in statements -->
      <rule pattern="\b(align|assert|bank|break|charmap|db|dl|ds|dw|elif|else|endc|endl|endm|endr|endsection|endu|export|fail|fatal|for|fragment|hram|if|incbin|include|load|macro|newcharmap|nextu|oam|popc|popo|pops|println|print|purge|pushc|pusho|pushs|redef|rept|rom0|romx|rsreset|rsset|section|setcharmap|shift|sram|static_assert|union|vram|warn|wram0|wramx)">
        <token type="NameBuiltin"/>
      </rule>
      <!-- Integer functions -->
      <rule pattern="\b(high|low|bitwidth|tzcount)\b">
        <token type="NameFunction"/>
      </rule>
      <!-- Fixed-point functions -->
      <rule pattern="\b(div|mul|fmod|pow|log|round|ceil|floor|sin|cos|tan|asin|acos|atan|atan2)\b">
        <token type="NameFunction"/>
      </rule>
      <!-- String functions -->
      <rule pattern="\b(strcat|strupr|strlwr|strslice|strrpl|strfmt|strchar|revchar|strlen|strcmp|strfind|strrfind|incharmap|charlen|charcmp|charsize|strsub|strin|strrin|charsub)\b">
        <token type="NameFunction"/>
      </rule>
      <!-- Other functions, excluding some that are the same as built-ins (BANK and SECTION) -->
      <rule pattern="\b(def|isconst|sizeof|startof)">
        <token type="NameFunction"/>
      </rule>
      <!-- Opcodes -->
      <rule pattern="\b(adc|add|and|bit|call|ccf|cp|cpl|daa|dec|di|ei|halt|inc|jp|jr|ld|ldd|ldh|ldi|nop|or|pop|push|res|ret|reti|rlca|rla|rlc|rl|rr|rra|rrc|rrca|rst|sbc|scf|set|sla|sra|srl|stop|sub|swap|xor)\b">
        <token type="Keyword"/>
      </rule>
      <!-- Registers and flags -->
      <rule pattern="\b(a|f|b|c|d|e|h|l|af|bc|de|hl|sp|pc|z|nz|nc)\b">
        <token type="Keyword"/>
      </rule>
      <!-- Operators -->
      <rule pattern="[-%!+/*~\^&amp;|=&lt;&gt;]">
        <token type="Operator"/>
      </rule>
      <!-- Reference to label -->
      <rule pattern="(\.)?(\w+)">
        <bygroups>
          <token type="Punctuation"/>
          <token type="Name"/>
        </bygroups>
      </rule>
      <!-- Predeclared symbols (non-words) -->
      <rule pattern="(@|\.|\.\.)">
        <token type="NameVariableMagic"/>
      </rule>
      <!-- Default text -->
      <rule pattern="\s+">
        <token type="TextWhitespace"/>
      </rule>
    </state>
  </rules>
</lexer>