<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2018 Jack R Linhart <iatenine@gmail.com>
Copyright (C) 2014 Matthias F. Brandstetter <pub@mabra.me>

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="gdscript" name="GDScript" version="2.0" _section="Script">
    <metadata>
        <property name="mimetypes">text/x-gdscript</property>
        <property name="globs">*.gd</property>
        <property name="line-comment-start">#</property>
    </metadata>

    <styles>
        <style id="module-handler"    name="Module Handler"        map-to="def:preprocessor"/>
        <style id="keyword"           name="Keyword"               map-to="def:keyword"/>
        <style id="multiline-string"  name="Multiline string"      map-to="def:string"/>
        <style id="string"            name="String"                map-to="def:string"/>
        <style id="escaped-char"      name="Escaped Character"     map-to="def:special-char"/>
        <style id="format"            name="Format"                map-to="def:character"/>
        <style id="string-conversion" name="string-conversion"/>
        <style id="special-variable"  name="Special Variable"      map-to="def:identifier"/>
        <style id="boolean"           name="Boolean"               map-to="def:boolean"/>
        <style id="floating-point"    name="Floating point number" map-to="def:floating-point"/>
        <style id="decimal"           name="Decimal number"        map-to="def:decimal"/>
        <style id="base-n-integer"    name="Base-N number"         map-to="def:base-n-integer"/>
        <style id="complex"           name="Complex number"        map-to="def:complex"/>
        <style id="builtin-constant"  name="Builtin Constant"      map-to="def:special-constant"/>
        <style id="builtin-object"    name="Builtin Object"        map-to="def:type"/>
        <style id="builtin-function"  name="Builtin Function"      map-to="def:builtin"/>
        <style id="method-calls"      name="Method Calls"          map-to="def:method-calls"/>
    </styles>

    <definitions>
        <context id="method-calls" style-ref="method-calls">
            <match extended="true">
                (\.[\s\n\r]*[\w]+)[\s\n\r]*(?=\(.*\))
            </match>
        </context>

        <define-regex id="identifier">[_a-zA-Z][_a-zA-Z0-9]*</define-regex>
        <define-regex id="number">[1-9][0-9]*</define-regex>

        <context id="format" style-ref="format" extend-parent="false">
            <match extended="true">
                %                       # leading % sign
                \(\%{identifier}\)?     # mapping key
                [#0\-\ \+]*             # conversion flags
                (\-?\%{number}|\*)?     # minimum field width
                (\.(\-?\%{number}|\*))? # precision
                (hlL)?                  # length modifier
                [diouxXeEfFgGcrs%]      # conversion type
            </match>
        </context>

        <!-- http://docs.python.org/ref/strings.html -->
        <context id="escaped-char" style-ref="escaped-char" extend-parent="true">
            <match extended="true">
                \\(                   # leading backslash
                [\\\"\'nrbtfav\?] |   # escaped character
                [0-7]{1,3} |          # one, two, or three octal digits
                x[0-9A-Fa-f]+         # 'x' followed by hex digits
                )
            </match>
        </context>

        <context id="double-quoted-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
            <start>"</start>
            <end>"</end>
            <include>
                <context ref="format"/>
                <context ref="escaped-char"/>
                <context ref="def:line-continue"/>
            </include>
        </context>

        <context id="single-quoted-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
            <start>'</start>
            <end>'</end>
            <include>
                <context ref="format"/>
                <context ref="escaped-char"/>
                <context ref="def:line-continue"/>
            </include>
        </context>

        <context id="gdscript" class="no-spell-check">
            <include>
                <context ref="method-calls"/>

                <context ref="def:shebang"/>
                <context ref="def:shell-like-comment"/>

                <context ref="double-quoted-string"/>
                <context ref="single-quoted-string"/>

                <context id="special-variables" style-ref="special-variable">
                    <prefix>(?&lt;![\w\.])</prefix>
                    <keyword>_init</keyword>
                    <keyword>_ready</keyword>
                </context>

                <context id="boolean" style-ref="boolean">
                    <prefix>(?&lt;![\w\.])</prefix>
                    <keyword>false</keyword>
                    <keyword>true</keyword>
                </context>

                <define-regex id="float" extended="true">
                    ( (\d+)?\.\d+ | \d+\. ) |
                    ( (\d+|(\d+)?\.\d+|\d+\.)[eE][+-]?\d+ )
                </define-regex>

                <context id="complex" style-ref="complex">
                    <match>(?&lt;![\w\.])(\%{float}|\d+)[jJ]\b</match>
                </context>

                <context id="float" style-ref="floating-point">
                    <match>(?&lt;![\w\.])\%{float}(?![\w\.])</match>
                </context>

                <context id="decimal" style-ref="decimal">
                    <match>(?&lt;![\w\.])([1-9][0-9]*|0)[lL]?(?![\w\.])</match>
                </context>

                <context id="octal" style-ref="base-n-integer">
                    <match>(?&lt;![\w\.])0[0-7]+[lL]?(?![\w\.])</match>
                </context>

                <context id="hex" style-ref="base-n-integer">
                    <match>(?&lt;![\w\.])0[xX][0-9A-Fa-f]+[lL]?(?![\w\.])</match>
                </context>

                <context id="module-handler" style-ref="module-handler">
                    <keyword>extends</keyword>
                    <keyword>preload</keyword>
                </context>

                <context id="builtin-constants" style-ref="builtin-constant">
                    <prefix>(?&lt;![\w\.])</prefix>
                    <keyword>null</keyword>
                </context>

                <context id="keyword" style-ref="keyword">
                    <keyword>and</keyword>
                    <keyword>assert</keyword>
                    <keyword>break</keyword>
                    <keyword>breakpoint</keyword>
                    <keyword>class</keyword>
                    <keyword>const</keyword>
                    <keyword>continue</keyword>
                    <keyword>elif</keyword>
                    <keyword>else</keyword>
                    <keyword>enum</keyword>
                    <keyword>export</keyword>
                    <keyword>extends</keyword>
                    <keyword>false</keyword>
                    <keyword>float</keyword>
                    <keyword>for</keyword>
                    <keyword>func</keyword>
                    <keyword>if</keyword>
                    <keyword>in</keyword>
                    <keyword>int</keyword>
                    <keyword>not</keyword>
                    <keyword>null</keyword>
                    <keyword>onready</keyword>
                    <keyword>or</keyword>
                    <keyword>pass</keyword>
                    <keyword>return</keyword>
                    <keyword>self</keyword>
                    <keyword>setget</keyword>
                    <keyword>signal</keyword>
                    <keyword>static</keyword>
                    <keyword>tool</keyword>
                    <keyword>true</keyword>
                    <keyword>var</keyword>
                    <keyword>while</keyword>
                    <keyword>yield</keyword>
                </context>

                <context id="builtin-objects" style-ref="builtin-object">
                    <prefix>(?&lt;![\w\.])</prefix>
                    <keyword>Vector2</keyword>
                    <keyword>Size2</keyword>
                    <keyword>Rect2</keyword>
                    <keyword>Vector3</keyword>
                    <keyword>Matrix32</keyword>
                    <keyword>Plane</keyword>
                    <keyword>Quat</keyword>
                    <keyword>AABB</keyword>
                    <keyword>Box3</keyword>
                    <keyword>Matrix3</keyword>
                    <keyword>Transform</keyword>
                    <keyword>Color</keyword>
                    <keyword>Image</keyword>
                    <keyword>NodePath</keyword>
                    <keyword>RID</keyword>
                    <keyword>Object</keyword>
                    <keyword>InputEvent</keyword>
                </context>

                <context id="builtin-function" style-ref="builtin-function">
                    <prefix>(?&lt;![\w\.])</prefix>
                    <keyword>print</keyword>
                    <keyword>sin</keyword>
                    <keyword>cos</keyword>
                    <keyword>tan</keyword>
                    <keyword>sinh</keyword>
                    <keyword>cosh</keyword>
                    <keyword>tanh</keyword>
                    <keyword>asin</keyword>
                    <keyword>acos</keyword>
                    <keyword>atan</keyword>
                    <keyword>atan2</keyword>
                    <keyword>sqrt</keyword>
                    <keyword>fmod</keyword>
                    <keyword>fposmod</keyword>
                    <keyword>floor</keyword>
                    <keyword>ceil</keyword>
                    <keyword>round</keyword>
                    <keyword>abs</keyword>
                    <keyword>sign</keyword>
                    <keyword>pow</keyword>
                    <keyword>log</keyword>
                    <keyword>exp</keyword>
                    <keyword>isnan</keyword>
                    <keyword>isinf</keyword>
                    <keyword>ease</keyword>
                    <keyword>decimals</keyword>
                    <keyword>stepify</keyword>
                    <keyword>lerp</keyword>
                    <keyword>dectime</keyword>
                    <keyword>randomize</keyword>
                    <keyword>rand</keyword>
                    <keyword>randi</keyword>
                    <keyword>randf</keyword>
                    <keyword>rand_range</keyword>
                    <keyword>rand_seed</keyword>
                    <keyword>deg2rad</keyword>
                    <keyword>rad2deg</keyword>
                    <keyword>linear2db</keyword>
                    <keyword>db2linear</keyword>
                    <keyword>max</keyword>
                    <keyword>min</keyword>
                    <keyword>clamp</keyword>
                    <keyword>nearest_po2</keyword>
                    <keyword>weakref</keyword>
                    <keyword>convert</keyword>
                    <keyword>str</keyword>
                    <keyword>print</keyword>
                    <keyword>printt</keyword>
                    <keyword>printerr</keyword>
                    <keyword>printraw</keyword>
                    <keyword>range</keyword>
                    <keyword>load</keyword>
                    <keyword>inst2dict</keyword>
                    <keyword>dict2inst</keyword>
                </context>
            </include>
        </context>
    </definitions>
</language>
