{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "name": "TSL",
  "scopeName": "source.tsl",
  "fileTypes": [
    "tsl",
    "tsf"
  ],
  "patterns": [
    {
      "include": "#comments"
    },
    {
      "include": "#strings"
    },
    {
      "include": "#numbers"
    },
    {
      "include": "#function-definitions"
    },
    {
      "include": "#function-calls"
    },
    {
      "include": "#variable-declarations"
    },
    {
      "include": "#property-chains"
    },
    {
      "include": "#keywords"
    },
    {
      "include": "#operators"
    },
    {
      "include": "#delimiters"
    }
  ],
  "repository": {
    "comments": {
      "patterns": [
        {
          "name": "comment.line.double-slash.tsl",
          "match": "//.*$",
          "captures": {
            "0": {
              "patterns": [
                {
                  "include": "#todo-keywords"
                }
              ]
            }
          }
        },
        {
          "name": "comment.block.pascal-style.tsl",
          "begin": "\\(\\*",
          "end": "\\*\\)",
          "patterns": [
            {
              "include": "#todo-keywords"
            }
          ]
        },
        {
          "name": "comment.block.braces.tsl",
          "begin": "\\{",
          "end": "\\}",
          "patterns": [
            {
              "include": "#todo-keywords"
            }
          ]
        }
      ]
    },
    "todo-keywords": {
      "patterns": [
        {
          "name": "keyword.other.todo.tsl",
          "match": "\\b(FIXME|NOTE|NOTES|TODO|XXX)\\b"
        }
      ]
    },
    "function-definitions": {
      "patterns": [
        {
          "name": "meta.function.definition.tsl",
          "begin": "\\b(function|procedure)\\s+",
          "beginCaptures": {
            "1": {
              "name": "storage.type.function.tsl"
            }
          },
          "end": "(?=;|\\bbegin\\b)",
          "patterns": [
            {
              "include": "#function-name"
            },
            {
              "include": "#function-params"
            },
            {
              "include": "#return-type"
            }
          ]
        }
      ]
    },
    "function-name": {
      "patterns": [
        {
          "name": "entity.name.function.definition.tsl",
          "match": "(?<=\\b(?:function|procedure)\\s+)(?:(\\w+)\\.)?(\\w+)",
          "captures": {
            "1": {
              "name": "entity.name.type.class.tsl"
            },
            "2": {
              "name": "entity.name.function.tsl"
            }
          }
        }
      ]
    },
    "function-params": {
      "name": "meta.function.parameters.tsl",
      "begin": "\\(",
      "end": "\\)",
      "patterns": [
        {
          "include": "#param-declaration"
        },
        {
          "include": "#simple-param"
        },
        {
          "include": "#param-separator"
        },
        {
          "include": "#strings"
        },
        {
          "include": "#numbers"
        },
        {
          "include": "#property-chains"
        }
      ]
    },
    "param-declaration": {
      "name": "meta.parameter.tsl",
      "match": "(\\w+)\\s*(:)\\s*([^;,)=]*)",
      "captures": {
        "1": {
          "name": "variable.parameter.tsl"
        },
        "2": {
          "name": "punctuation.separator.type.tsl"
        },
        "3": {
          "name": "storage.type.tsl"
        }
      }
    },
    "simple-param": {
      "name": "variable.parameter.simple.tsl",
      "match": "\\b(\\w+)(?=\\s*[,;)])",
      "captures": {
        "1": {
          "name": "variable.parameter.tsl"
        }
      }
    },
    "return-type": {
      "name": "meta.function.return-type.tsl",
      "match": "(:)\\s*([^;]*)",
      "captures": {
        "1": {
          "name": "punctuation.separator.type.tsl"
        },
        "2": {
          "name": "storage.type.tsl"
        }
      }
    },
    "param-separator": {
      "name": "punctuation.separator.parameter.tsl",
      "match": "[;,]"
    },
    "variable-declarations": {
      "name": "meta.variable.declaration.tsl",
      "match": "(?<!\\?\\s*)(\\w+)\\s*(:)(?!=)\\s*((?:array\\s*(?:\\[[^\\]]*\\])?\\s+of\\s+)?[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*)\\s*(;)?",
      "captures": {
        "1": {
          "name": "variable.other.declaration.tsl"
        },
        "2": {
          "name": "punctuation.separator.type.tsl"
        },
        "3": {
          "name": "storage.type.tsl"
        },
        "4": {
          "name": "punctuation.terminator.tsl"
        }
      }
    },
    "property-chains": {
      "patterns": [
        {
          "name": "meta.property.chain.tsl",
          "begin": "\\b(\\w+)(?=\\.)",
          "beginCaptures": {
            "1": {
              "name": "variable.other.object.tsl"
            }
          },
          "end": "(?!\\.(\\w+))",
          "patterns": [
            {
              "begin": "\\.",
              "beginCaptures": {
                "0": {
                  "name": "punctuation.accessor.tsl"
                }
              },
              "end": "(\\w+)",
              "endCaptures": {
                "1": {
                  "name": "variable.other.property.tsl"
                }
              }
            }
          ]
        }
      ]
    },
    "function-calls": {
      "patterns": [
        {
          "name": "meta.function.call.tsl",
          "begin": "(?<!\\b(?:function|procedure)\\s+)(\\w+)\\s*(\\()",
          "beginCaptures": {
            "1": {
              "name": "entity.name.function.tsl"
            },
            "2": {
              "name": "punctuation.definition.parameters.begin.tsl"
            }
          },
          "end": "\\)",
          "endCaptures": {
            "0": {
              "name": "punctuation.definition.parameters.end.tsl"
            }
          },
          "patterns": [
            {
              "include": "#call-params"
            },
            {
              "include": "#strings"
            },
            {
              "include": "#numbers"
            },
            {
              "include": "#function-calls"
            },
            {
              "include": "#operators"
            }
          ]
        }
      ]
    },
    "call-params": {
      "patterns": [
        {
          "name": "meta.function.call.parameter.tsl",
          "match": "(\\w+)\\s*(:)\\s*([^;,)]*)",
          "captures": {
            "1": {
              "name": "variable.parameter.tsl"
            },
            "2": {
              "name": "punctuation.separator.parameter.tsl"
            },
            "3": {
              "patterns": [
                {
                  "include": "#strings"
                },
                {
                  "include": "#numbers"
                },
                {
                  "include": "#function-calls"
                },
                {
                  "include": "#property-chains"
                },
                {
                  "include": "#operators"
                }
              ]
            }
          }
        },
        {
          "name": "punctuation.separator.parameter.tsl",
          "match": "[;,]"
        }
      ]
    },
    "strings": {
      "patterns": [
        {
          "name": "string.quoted.single.tsl",
          "begin": "[uU]?'",
          "end": "'|(?=\\s*$)",
          "beginCaptures": {
            "0": {
              "name": "punctuation.definition.string.begin.tsl"
            }
          },
          "endCaptures": {
            "0": {
              "name": "punctuation.definition.string.end.tsl"
            }
          },
          "patterns": [
            {
              "name": "constant.character.escape.tsl",
              "match": "\\\\."
            },
            {
              "name": "constant.character.escape.newline.tsl",
              "match": "\\\\\\r?\\n"
            }
          ]
        },
        {
          "name": "string.quoted.double.tsl",
          "begin": "[uU]?\"",
          "end": "\"|(?=\\s*$)",
          "beginCaptures": {
            "0": {
              "name": "punctuation.definition.string.begin.tsl"
            }
          },
          "endCaptures": {
            "0": {
              "name": "punctuation.definition.string.end.tsl"
            }
          },
          "patterns": [
            {
              "name": "constant.character.escape.tsl",
              "match": "\\\\."
            },
            {
              "name": "constant.character.escape.newline.tsl",
              "match": "\\\\\\r?\\n"
            }
          ]
        },
        {
          "name": "string.quoted.raw.tsl",
          "begin": "[uU]?[rR](['\"])",
          "end": "\\1",
          "beginCaptures": {
            "0": {
              "name": "punctuation.definition.string.begin.tsl"
            }
          },
          "endCaptures": {
            "0": {
              "name": "punctuation.definition.string.end.tsl"
            }
          },
          "patterns": [
            {
              "name": "constant.character.escape.tsl",
              "match": "\\\\."
            }
          ]
        }
      ]
    },
    "numbers": {
      "patterns": [
        {
          "name": "constant.numeric.octal.tsl",
          "match": "\\b0[oO]?[0-7]+[Ll]?\\b"
        },
        {
          "name": "constant.numeric.hexadecimal.tsl",
          "match": "\\b0[xX][0-9a-fA-F]+[Ll]?\\b"
        },
        {
          "name": "constant.numeric.binary.tsl",
          "match": "\\b0[bB][01]+[Ll]?\\b"
        },
        {
          "name": "constant.numeric.decimal.tsl",
          "match": "\\b([1-9]\\d*|0)[Ll]?\\b"
        },
        {
          "name": "constant.numeric.complex.tsl",
          "match": "\\b\\d+[jJ]\\b"
        },
        {
          "name": "constant.numeric.float.tsl",
          "match": "\\b\\d+[eE][+-]?\\d+[jJ]?\\b"
        },
        {
          "name": "constant.numeric.float.tsl",
          "match": "\\b\\d+\\.([eE][+-]?\\d+)?[jJ]?\\b"
        },
        {
          "name": "constant.numeric.float.tsl",
          "match": "\\b\\d*\\.\\d+([eE][+-]?\\d+)?[jJ]?\\b"
        }
      ]
    },
    "keywords": {
      "patterns": [
        {
          "name": "keyword.control.program-structure.tsl",
          "match": "(?i)\\b(program|function|procedure|unit|uses|implementation|interface|initalization|finalization)\\b"
        },
        {
          "name": "keyword.control.interface.tsl",
          "match": "(?i)\\b(unit|uses|implementation|interface|initalization|finalization)\\b"
        },
        {
          "name": "storage.type.primitive.tsl",
          "match": "(?i)\\b(string|integer|boolean|int64|real|array)\\b"
        },
        {
          "name": "storage.type.class.tsl",
          "match": "(?i)\\b(type|class|fakeclass|new)\\b"
        },
        {
          "name": "storage.modifier.class.tsl",
          "match": "(?i)\\b(override|overload|virtual|property|self|inherited)\\b"
        },
        {
          "name": "storage.modifier.access.tsl",
          "match": "(?i)\\b(public|protected|private|published)\\b"
        },
        {
          "name": "keyword.other.property-accessor.tsl",
          "match": "(?i)\\b(read|write)\\b"
        },
        {
          "name": "keyword.other.constructor.tsl",
          "match": "(?i)\\b(create|destroy|operator)\\b"
        },
        {
          "name": "storage.modifier.variable.tsl",
          "match": "(?i)\\b(external|const|out|var|global|static)\\b"
        },
        {
          "name": "keyword.control.conditional.tsl",
          "match": "(?i)\\b(if|else|then|case|of)\\b"
        },
        {
          "name": "keyword.control.loop.tsl",
          "match": "(?i)\\b(for|while|do|downto|step|until|repeat|to)\\b"
        },
        {
          "name": "keyword.control.branch.tsl",
          "match": "(?i)\\b(break|continue|goto|label|exit)\\b"
        },
        {
          "name": "keyword.control.return.tsl",
          "match": "(?i)\\b(return|debugreturn|debugrunenv|debugrunenvdo)\\b"
        },
        {
          "name": "keyword.control.block.tsl",
          "match": "(?i)\\b(begin|end|with)\\b"
        },
        {
          "name": "storage.modifier.reference.tsl",
          "match": "(?i)\\b(weakref|autoref)\\b"
        },
        {
          "name": "keyword.other.namespace.tsl",
          "match": "(?i)\\bnamespace\\b"
        },
        {
          "name": "keyword.control.exception.tsl",
          "match": "(?i)\\b(except|raise|try|finally|exceptobject)\\b"
        },
        {
          "name": "keyword.operator.logical.tsl",
          "match": "(?i)\\b(and|in|is|not|or)\\b"
        },
        {
          "name": "keyword.operator.arithmetic.tsl",
          "match": "(?i)\\b(div|mod)\\b"
        },
        {
          "name": "keyword.operator.bitwise.tsl",
          "match": "(?i)\\b(ror|rol|shr|shl)\\b"
        },
        {
          "name": "keyword.operator.set.tsl",
          "match": "(?i)\\b(union|minus|union2)\\b"
        },
        {
          "name": "keyword.control.sql.tsl",
          "match": "(?i)\\b(select|vselect|sselect|update|delete|mselect)\\b"
        },
        {
          "name": "keyword.operator.sql.tsl",
          "match": "(?i)\\b(on|like|in)\\b"
        },
        {
          "name": "keyword.other.sql.tsl",
          "match": "(?i)\\b(sqlin|from|where|group|by|order|distinct|join)\\b"
        },
        {
          "name": "keyword.other.calling-convention.tsl",
          "match": "(?i)\\b(cdecl|pascal|stdcall|safecall|fastcall|register)\\b"
        },
        {
          "name": "keyword.other.system.tsl",
          "match": "(?i)\\b(setuid|sudo)\\b"
        },
        {
          "name": "variable.language.builtin.tsl",
          "match": "(?i)\\b(paramcount|realparamcount|params|system|tslassigning|likeeps|likeepsrate)\\b"
        },
        {
          "name": "support.function.builtin.tsl",
          "match": "(?i)\\b(echo|mtic|mtoc)\\b"
        },
        {
          "name": "constant.language.boolean.tsl",
          "match": "(?i)\\b(false|true)\\b"
        },
        {
          "name": "constant.language.math.tsl",
          "match": "(?i)\\b(inf|nan)\\b"
        },
        {
          "name": "constant.language.null.tsl",
          "match": "(?i)\\bnil\\b"
        }
      ]
    },
    "operators": {
      "name": "keyword.operator.tsl",
      "patterns": [
        {
          "name": "keyword.operator.assignment.tsl",
          "match": ":="
        },
        {
          "name": "keyword.operator.arithmetic.tsl",
          "match": "[+\\-*/<>=!&|^~%]"
        }
      ]
    },
    "delimiters": {
      "name": "punctuation.separator.tsl",
      "match": "[()\\[\\]{},;:.@?]"
    }
  }
}