local id_regex = '[_$[:alpha:]][_.$[:alnum:]]*';
local statement_kw_regex =
std.join('|', [
'if',
'else',
'while',
'for',
'return',
'call',
'jump',
'function',
'global',
'define',
'break',
'continue',
]);
{
'$schema': 'https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json',
name: 'S3AIR Lemon',
patterns: [
{ include: '#statements' },
],
repository: {
statements: {
patterns: [
{ include: '#preprocessor-directives' },
{ include: '#include' },
{ include: '#declarations' },
{ include: '#block' },
{ include: '#comments' },
{ include: '#statement-keywords' },
{ include: '#expressions' },
{ include: '#assign-operator' },
],
},
'preprocessor-directives': {
patterns: [
{
begin: '^\\s*((#)\\s*if\\b)',
beginCaptures: {
'0': { name: 'meta.preprocessor.s3air-lemon' },
'1': { name: 'keyword.control.directive.conditional.s3air-lemon' },
'2': { name: 'punctuation.definition.directive.s3air-lemon' },
},
end: '^\\s*((#)\\s*endif\\b)',
endCaptures: {
'0': { name: 'meta.preprocessor.s3air-lemon' },
'1': { name: 'keyword.control.directive.conditional.s3air-lemon' },
'2': { name: 'punctuation.definition.directive.s3air-lemon' },
},
patterns: [
{
match: '^\\s*((#)\\s*else\\b)',
captures: {
'0': { name: 'meta.preprocessor.s3air-lemon' },
'1': { name: 'keyword.control.directive.conditional.s3air-lemon' },
'2': { name: 'punctuation.definition.directive.s3air-lemon' },
},
},
{ include: '$base' },
],
},
],
},
expressions: {
patterns: [
{ include: '#index' },
{ include: '#parenthesized' },
{ include: '#strings' },
{ include: '#numbers' },
{ include: '#bools' },
{ include: '#types' },
{ include: '#registers' },
{ include: '#variables' },
{ include: '#operators' },
],
},
include: {
begin: '^\\s*(include)\\b',
beginCaptures: {
'1': { name: 'keyword.control.include.s3air-lemon' },
},
end: '(?=$)',
patterns: [
{
name: 'punctuation.separator.path.s3air-lemon',
match: '/',
},
{
name: 'string.regexp.s3air-lemon',
match: '\\?',
},
{
name: 'string.path.s3air-lemon',
match: '\\S',
},
],
},
declarations: {
patterns: [
{ include: '#function-definition' },
{ include: '#global-definition' },
{ include: '#const-definition' },
],
},
'function-definition': {
name: 'meta.function.s3air-lemon',
begin: '(\\bfunction\\b)',
beginCaptures: {
'1': { name: 'storage.type.function.s3air-lemon' },
},
end: '(?=^\\s*$|(?:^\\s*(?:global|function|return))|(?<=\\}))',
patterns: [
{ include: '#comments' },
{ include: '#types' },
{ include: '#function-parameters' },
{ include: '#block' },
{
name: 'entity.name.function.s3air-lemon',
match: id_regex,
},
],
},
'function-parameters': {
name: 'meta.parameters.s3air-lemon',
begin: '\\(',
beginCaptures: {
'0': { name: 'punctuation.definitions.parameters.begin.s3air-lemon' },
'1': { name: 'punctuation.definitions.parameters.end.s3air-lemon' },
},
end: '\\)',
patterns: [
{ include: '#comment' },
{ include: '#types' },
{
name: 'punctuation.separator.parameter.s3air-lemon',
match: ',',
},
{
name: 'variable.parameter.s3air-lemon',
match: id_regex,
},
],
},
'const-definition': {
name: 'meta.constant.s3air-lemon',
begin: '\\bdefine\\b',
beginCaptures: {
'0': { name: 'keyword.control.define.s3air-lemon' },
},
end: '(?=$)',
patterns: [
{ include: '#comments' },
{ include: '#types' },
{ include: '#assign-operator' },
{ include: '#expressions' },
{
name: 'variable.other.constant.s3air-lemon',
match: id_regex,
},
],
},
'global-definition': {
name: 'meta.global.s3air-lemon',
begin: '\\bglobal\\b(?!\\.)',
beginCaptures: {
'0': { name: 'keyword.control.global.s3air-lemon' },
},
end: '(?=$)',
patterns: [
{ include: '#comments' },
{ include: '#types' },
{
name: 'variable.other.readwrite.s3air-lemon',
match: id_regex,
},
],
},
block: {
name: 'meta.block.s3air-lemon',
begin: '\\{',
beginCaptures: {
'0': { name: 'punctuation.definition.block.s3air-lemon' },
},
end: '\\}',
endCaptures: {
'0': { name: 'punctuation.definition.block.s3air-lemon' },
},
patterns: [
{ include: '#statements' },
],
},
types: {
name: 'storage.type.built-in.s3air-lemon',
match: 'bool|string|void|[su](?:8|16|32|64)',
},
'assign-operator': {
name: 'keyword.operator.assignment.s3air-lemon',
match: '=',
},
'statement-keywords': {
patterns: [
{
name: 'keyword.control.s3air-lemon',
match: '\\b(%s)\\b(?!\\.)' % statement_kw_regex,
},
],
},
index: {
begin: '\\[',
beginCaptures: {
'0': { name: 'meta.brace.square.s3air-lemon' },
},
end: '(\\])|(?=%s)' % statement_kw_regex,
endCaptures: {
'1': { name: 'meta.brace.square.s3air-lemon' },
},
patterns: [
{ include: '#comments' },
{ include: '#expressions' },
],
},
parenthesized: {
begin: '\\(',
beginCaptures: {
'0': { name: 'meta.brace.round.s3air-lemon' },
},
end: '(\\))|(?=%s)' % statement_kw_regex,
endCaptures: {
'1': { name: 'meta.brace.round.s3air-lemon' },
},
patterns: [
{ include: '#comments' },
{ include: '#expressions' },
],
},
strings: {
name: 'string.quoted.double.s3air-lemon',
begin: '"',
end: '"',
patterns: [
{
name: 'constant.character.escape.s3air-lemon',
match: '\\\\.',
},
],
},
numbers: {
patterns: [
{
name: 'constant.numeric.hex.s3air-lemon',
match: '\\b0x[a-fA-Z0-9]+\\b',
},
{
name: 'constant.numeric.decimal.s3air-lemon',
match: '\\b[0-9]+\\b',
},
],
},
bools: {
patterns: [
{
name: 'constant.language.boolean.true.s3air-lemon',
match: '\\btrue\\b',
},
{
name: 'constant.language.boolean.false.s3air-lemon',
match: '\\bfalse\\b',
},
],
},
registers: {
patterns: [
{
name: 'variable.language.register.s3air-lemon',
match: '\\b[A-D][0-7]',
},
],
},
variables: {
patterns: [
{
name: 'variable.language.base.s3air-lemon',
match: '\\bbase(?=\\.)',
},
{
name: 'variable.other.readwrite.s3air-lemon',
match: id_regex,
},
],
},
operators: {
patterns: [
{
name: 'keyword.operator.increment.s3air-lemon',
match: '\\+\\+',
},
{
name: 'keyword.operator.decrement.s3air-lemon',
match: '--',
},
{
name: 'keyword.operator.assignment.compound.s3air-lemon',
match: '\\*=|(?<!\\()/=|%=|\\+=|\\-=',
},
{
name: 'keyword.operator.assignment.compound.bitwise.s3air-lemon',
match: '\\&=|\\^=|<<=|>>=|>>>=|\\|=',
},
{
name: 'keyword.operator.bitwise.shift.s3air-lemon',
match: '<<|>>',
},
{
name: 'keyword.operator.logical.s3air-lemon',
match: '\\!|&&|\\|\\||\\?\\?',
},
{
name: 'keyword.operator.comparison.s3air-lemon',
match: '===|!==|==|!=',
},
{
name: 'keyword.operator.relational.s3air-lemon',
match: '<=|>=|<>|<|>',
},
{
name: 'keyword.operator.bitwise.s3air-lemon',
match: '\\&|~|\\^|\\|',
},
{
name: 'keyword.operator.arithmetic.s3air-lemon',
match: '%|\\*|/|-|\\+',
},
{
name: 'keyword.operator.bitwise.s3air-lemon',
match: '\\&|~|\\^|\\|',
},
{ include: '#assign-operator' },
{
name: 'punctuation.separator.comma.s3air-lemon',
match: ',',
},
{
name: 'punctuation.accessor.s3air-lemon',
match: '.',
},
],
},
comments: {
patterns: [
{
name: 'comment.block.s3air-lemon',
begin: '/\\*',
beginCaptures: {
'0': { name: 'punctuation.defintiion.comment.s3air-lemon' },
},
end: '\\*/',
endCaptures: {
'0': { name: 'punctuation.defintiion.comment.s3air-lemon' },
},
},
{
begin: '(^[ \\t]+)?(//)',
beginCaptures: {
'1': { name: 'punctuation.whitespace.comment.leading.s3air-lemon' },
'2': { name: 'comment.line.double-slash.s3air-lemon' },
},
end: '(?=$)',
contentName: 'comment.line.double-slash.s3air-lemon',
},
],
},
},
scopeName: 'source.s3air-lemon',
}