tree-sitter-dust/grammar.js
2023-10-02 15:20:00 -04:00

200 lines
3.3 KiB
JavaScript

module.exports = grammar({
name: 'dust',
word: $ => $.identifier,
rules: {
root: $ => repeat1($.item),
item: $ => choice(
$.comment,
$.statement,
),
comment: $ => seq(token('#'), /.*/),
statement: $ => prec.right(choice(
$.expression,
$.yield,
)),
yield: $ => prec.left(
seq(
$.expression,
'->',
$.expression,
repeat(prec.left(seq('->', $.expression)))
)
),
expression: $ => choice(
$._expression_kind,
seq('(', $._expression_kind, ')')
),
_expression_kind: $ => prec.right(choice(
$.value,
$.identifier,
$.control_flow,
$.select,
$.insert,
$.function_call,
$.assignment,
$.math,
$.logic,
$.loop,
$.match,
)),
identifier: $ => /[a-z|_|.]+[0-9]?/,
value: $ => prec.left(1, choice(
$.integer,
$.float,
$.string,
$.list,
$.boolean,
$.function,
$.table,
$.map,
)),
float: $ => /[-]*[0-9]*[.]{1}[0-9]+/,
integer: $ => /[-]*[0-9]+[.]{0}/,
string: $ => /(".*?")|('.*?')|(`.*?`)/,
boolean: $ => choice(
'true',
'false',
),
list: $ => seq(
'[',
repeat1(seq(field('item', $.value), optional(','))),
']'
),
function: $ => seq(
'function',
optional(seq('<', repeat(seq($.identifier, optional(','))), '>')),
'{',
repeat1($.statement),
'}',
),
table: $ => seq(
'table',
seq('<', repeat1(seq($.identifier, optional(','))), '>'),
'{',
repeat($.list),
'}',
),
map: $ => seq(
'map',
'{',
repeat(seq($.identifier, "=", $.value)),
'}',
),
math: $ => prec.right(seq(
$.expression,
$.math_operator,
$.expression,
)),
math_operator: $ => choice(
'+',
'-',
'*',
'/',
'%',
),
logic: $ => prec.right(seq(
$.expression,
$.logic_operator,
$.expression,
)),
logic_operator: $ => choice(
'==',
'&&',
'||',
'and',
'or',
),
assignment: $ => prec.right(seq(
$.identifier,
choice("=", "+=", "-="),
$.statement,
)),
select: $ => prec.right(seq(
'select',
$.identifier,
'from',
$.identifier,
optional(
seq('where', $.expression)
),
)),
insert: $ => prec.right(seq(
'insert',
repeat1($.list),
'into',
$.identifier,
optional(
seq('where', $.expression)
),
)),
control_flow: $ => prec.right(seq(
'if',
$.expression,
'then',
$.statement,
optional(seq('else', $.statement))
)),
function_call: $ => prec.right(seq(
$.identifier,
'<',
repeat(seq($.expression, optional(','))),
'>',
)),
loop: $ => choice(
$.break_loop,
$.while_loop,
),
while_loop: $ => seq(
'while',
$.expression,
'{',
$.statement,
'}',
),
break_loop: $ => seq(
'loop',
'{',
$.statement,
'}',
),
match: $ => seq(
'match',
$.expression,
'{',
repeat1(seq($.expression, '=>', $.statement)),
'}',
),
}
});