408 lines
6.7 KiB
Plaintext
408 lines
6.7 KiB
Plaintext
module.exports = grammar({
|
|
name: "dust",
|
|
|
|
word: $ => $.identifier,
|
|
|
|
extras: $ => [/\s/, $._comment],
|
|
|
|
rules: {
|
|
root: $ =>
|
|
prec(1, repeat1($.statement)),
|
|
|
|
_comment: $ => /[#][^#\n]*[#|\n]/,
|
|
|
|
block: $ =>
|
|
seq(
|
|
optional("async"),
|
|
"{",
|
|
repeat1($.statement),
|
|
"}",
|
|
),
|
|
|
|
statement: $ =>
|
|
prec.left(
|
|
seq(
|
|
choice(
|
|
$.assignment,
|
|
$.block,
|
|
$.expression,
|
|
$.for,
|
|
$.if_else,
|
|
$.index_assignment,
|
|
$.match,
|
|
$.return,
|
|
$.use,
|
|
$.while,
|
|
),
|
|
optional(";"),
|
|
),
|
|
),
|
|
|
|
expression: $ =>
|
|
prec.right(
|
|
choice(
|
|
$._expression_kind,
|
|
seq(
|
|
"(",
|
|
$._expression_kind,
|
|
")",
|
|
),
|
|
),
|
|
),
|
|
|
|
_expression_kind: $ =>
|
|
prec.right(
|
|
choice(
|
|
$.function_call,
|
|
$.identifier,
|
|
$.index,
|
|
$.logic,
|
|
$.math,
|
|
$.value,
|
|
$.yield,
|
|
),
|
|
),
|
|
|
|
_expression_list: $ =>
|
|
repeat1(
|
|
prec.right(
|
|
seq(
|
|
$.expression,
|
|
optional(","),
|
|
),
|
|
),
|
|
),
|
|
|
|
identifier: $ =>
|
|
/[_a-zA-Z]+[_a-zA-Z0-9]?/,
|
|
|
|
value: $ =>
|
|
choice(
|
|
$.integer,
|
|
$.float,
|
|
$.string,
|
|
$.boolean,
|
|
$.list,
|
|
$.function,
|
|
$.table,
|
|
$.map,
|
|
),
|
|
|
|
integer: $ =>
|
|
token(
|
|
prec.left(
|
|
seq(
|
|
optional("-"),
|
|
repeat1(
|
|
choice(
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"0",
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
float: $ =>
|
|
token(
|
|
prec.left(
|
|
seq(
|
|
optional("-"),
|
|
repeat1(
|
|
choice(
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"0",
|
|
),
|
|
),
|
|
".",
|
|
repeat1(
|
|
choice(
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"0",
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
string: $ =>
|
|
/("[^"]*?")|('[^']*?')|(`[^`]*?`)/,
|
|
|
|
boolean: $ =>
|
|
choice("true", "false"),
|
|
|
|
list: $ =>
|
|
seq(
|
|
"[",
|
|
repeat(
|
|
prec.left(
|
|
seq(
|
|
$.expression,
|
|
optional(","),
|
|
),
|
|
),
|
|
),
|
|
"]",
|
|
),
|
|
|
|
map: $ =>
|
|
seq(
|
|
"{",
|
|
repeat(
|
|
seq(
|
|
$.identifier,
|
|
"=",
|
|
$.statement,
|
|
optional(","),
|
|
),
|
|
),
|
|
"}",
|
|
),
|
|
|
|
index: $ =>
|
|
prec.left(
|
|
1,
|
|
seq(
|
|
$.expression,
|
|
":",
|
|
$.expression,
|
|
optional(
|
|
seq("..", $.expression),
|
|
),
|
|
),
|
|
),
|
|
|
|
math: $ =>
|
|
prec.left(
|
|
seq(
|
|
$.expression,
|
|
$.math_operator,
|
|
$.expression,
|
|
),
|
|
),
|
|
|
|
math_operator: $ =>
|
|
choice("+", "-", "*", "/", "%"),
|
|
|
|
logic: $ =>
|
|
prec.right(
|
|
seq(
|
|
$.expression,
|
|
$.logic_operator,
|
|
$.expression,
|
|
),
|
|
),
|
|
|
|
logic_operator: $ =>
|
|
choice(
|
|
"==",
|
|
"!=",
|
|
"&&",
|
|
"||",
|
|
">",
|
|
"<",
|
|
">=",
|
|
"<=",
|
|
),
|
|
|
|
assignment: $ =>
|
|
seq(
|
|
field(
|
|
"identifier",
|
|
$.identifier,
|
|
),
|
|
optional(
|
|
field(
|
|
"type",
|
|
$.type_definition,
|
|
),
|
|
),
|
|
field(
|
|
"assignment_operator",
|
|
$.assignment_operator,
|
|
),
|
|
field("statement", $.statement),
|
|
),
|
|
|
|
index_assignment: $ =>
|
|
seq(
|
|
$.index,
|
|
$.assignment_operator,
|
|
$.statement,
|
|
),
|
|
|
|
assignment_operator: $ =>
|
|
prec.right(
|
|
choice("=", "+=", "-="),
|
|
),
|
|
|
|
if_else: $ =>
|
|
prec.right(
|
|
seq(
|
|
$.if,
|
|
repeat($.else_if),
|
|
optional($.else),
|
|
),
|
|
),
|
|
|
|
if: $ =>
|
|
seq("if", $.expression, $.block),
|
|
|
|
else_if: $ =>
|
|
seq(
|
|
"else if",
|
|
$.expression,
|
|
$.block,
|
|
),
|
|
|
|
else: $ => seq("else", $.block),
|
|
|
|
match: $ =>
|
|
prec.right(
|
|
seq(
|
|
"match",
|
|
$.expression,
|
|
repeat1(
|
|
seq(
|
|
$.expression,
|
|
"=>",
|
|
$.block,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
|
|
while: $ =>
|
|
seq(
|
|
"while",
|
|
$.expression,
|
|
$.block,
|
|
),
|
|
|
|
for: $ =>
|
|
seq(
|
|
choice("for", "async for"),
|
|
$.identifier,
|
|
"in",
|
|
$.expression,
|
|
$.block,
|
|
),
|
|
|
|
identifier_list: $ =>
|
|
prec.right(
|
|
choice(
|
|
seq(
|
|
"|",
|
|
repeat(
|
|
seq(
|
|
$.identifier,
|
|
optional(","),
|
|
),
|
|
),
|
|
"|",
|
|
),
|
|
),
|
|
),
|
|
|
|
table: $ =>
|
|
prec.right(
|
|
seq(
|
|
"table",
|
|
$.identifier_list,
|
|
$.expression,
|
|
),
|
|
),
|
|
|
|
return: $ =>
|
|
seq("return", $.expression),
|
|
|
|
use: $ => seq("use", $.string),
|
|
|
|
type_definition: $ =>
|
|
seq("<", $.type, ">"),
|
|
|
|
type: $ =>
|
|
prec.right(
|
|
choice(
|
|
"any",
|
|
"bool",
|
|
seq(
|
|
"fn",
|
|
repeat(
|
|
seq(
|
|
$.type,
|
|
optional(","),
|
|
),
|
|
),
|
|
optional(seq("->", $.type)),
|
|
),
|
|
"int",
|
|
seq("list", $.type),
|
|
"map",
|
|
"num",
|
|
"str",
|
|
),
|
|
),
|
|
|
|
function: $ =>
|
|
seq(
|
|
"|",
|
|
repeat(
|
|
seq(
|
|
$.identifier,
|
|
optional(","),
|
|
),
|
|
),
|
|
"|",
|
|
$.block,
|
|
),
|
|
|
|
function_call: $ =>
|
|
prec.right(
|
|
1,
|
|
seq(
|
|
"(",
|
|
$.expression,
|
|
optional($._expression_list),
|
|
")",
|
|
),
|
|
),
|
|
|
|
yield: $ =>
|
|
prec.left(
|
|
seq(
|
|
$.expression,
|
|
"->",
|
|
"(",
|
|
$.expression,
|
|
optional($._expression_list),
|
|
")",
|
|
),
|
|
),
|
|
},
|
|
});
|