module.exports = grammar({ name: 'spl', rules: { source_file: $ => seq(repeat($._statement)), _unspaced_statement: $ => seq( choice( $.ministring, $.string, $.number, $.function_definition, $.type_definition, $.with_expr, $.array, $.if, $.while, $.catch, $.use, $.include, $.def, $.call_expr, seq( repeat('&'), $.call ), ), optional(';'), optional($.call_expr), ), _statement: $ => seq( $._unspaced_statement, $._spacing, ), function_definition: $ => choice($.func, $.block), func: $ => seq( 'func', $._spacing, $.identifier, $._spacing, choice(seq('@', $.identifier, $._spacing, '!', $.blocky), $.block), ), blocky: $ => seq('{', repeat(choice($.blocky, /./)), '}'), block: $ => seq( '{', $._spacing, repeat(seq(/[^ \n\r\t|]+/, $._spacing)), '|', repeat($._statement), '}', ), identifier: $ => /[^ \n\r\t<>:;&{}"'\[\],]+/, call: $ => choice( seq( optional($.call), ':', optional(repeat('&')), $.identifier, ), $.operation, $.identifier, ), number: $ => token(prec(10, /\d+(\.\d+)?/)), ministring: $ => token(prec(10, seq('^', /[^ \n\r\t<>:;&{}"'\[\],]+/))), string: $ => seq('"', repeat(choice(/\\./, /./)), '"'), call_expr: $ => seq('<', optional($._spacing), repeat($._statement), $._unspaced_statement, '>'), with_expr: $ => seq( 'with', $._spacing, repeat(seq($.identifier, $._spacing)), ';', ), array: $ => seq('[', $._spacing, optional(repeat($._statement)), ']'), operation: $ => choice(/[+\-*\/%&]/, "=>!", "=>?", "=>?!", "=>"), set_variable: $ => seq('=', $.identifier), type_definition: $ => seq( 'construct', $._spacing, $.call, $._spacing, optional(seq('namespace', $._spacing)), '{', $._spacing, repeat(seq($.identifier, $._spacing)), optional(seq( ';', repeat(seq($.identifier, $.block, $._spacing)), )), '}', ), _spacing: $ => /[ \n\r\t\(\)]+/, if: $ => seq( 'if', $._spacing, '{', $._spacing, repeat($._statement), '}', ), while: $ => seq( 'while', $._spacing, '{', $._spacing, repeat($._statement), '}', $._spacing, '{', $._spacing, repeat($._statement), '}', ), catch: $ => seq( 'catch', $._spacing, optional(repeat(seq($.identifier, $._spacing))), '{', $._spacing, repeat($._statement), '}', $._spacing, '{', $._spacing, repeat($._statement), '}', ), include: $ => seq( 'include', $.identifier, $._spacing, 'in', $.identifier, ), use: $ => seq( 'use', $._spacing, $.call, ), def: $ => seq( 'def', $._spacing, $.identifier, optional(repeat(seq(',', $._spacing, $.identifier))) ), }, });