2023-10-18 21:52:56 +00:00
|
|
|
module.exports = grammar({
|
|
|
|
name: 'dust',
|
|
|
|
|
|
|
|
word: $ => $.identifier,
|
|
|
|
|
2023-11-04 10:02:27 +00:00
|
|
|
extras: $ => [ /\s/, $._comment ],
|
2023-10-31 07:17:58 +00:00
|
|
|
|
2023-10-31 17:04:22 +00:00
|
|
|
conflicts: $ => [
|
|
|
|
[$.map, $.assignment_operator],
|
|
|
|
],
|
|
|
|
|
2023-10-18 21:52:56 +00:00
|
|
|
rules: {
|
2023-11-11 01:44:03 +00:00
|
|
|
root: $ => prec(1, repeat1($.statement)),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-11-04 10:02:27 +00:00
|
|
|
_comment: $ => /[#][^#\n]*[#|\n]/,
|
2023-10-31 07:17:58 +00:00
|
|
|
|
2023-11-11 01:44:03 +00:00
|
|
|
block: $ => seq(
|
|
|
|
optional('async'),
|
|
|
|
'{',
|
2023-10-31 13:31:10 +00:00
|
|
|
repeat1($.statement),
|
2023-11-11 01:44:03 +00:00
|
|
|
'}',
|
|
|
|
),
|
2023-10-31 05:09:29 +00:00
|
|
|
|
2023-11-15 01:41:57 +00:00
|
|
|
statement: $ => prec.left(seq(
|
2023-10-31 20:25:13 +00:00
|
|
|
choice(
|
|
|
|
$.assignment,
|
2023-11-11 01:44:03 +00:00
|
|
|
$.block,
|
2023-10-31 20:25:13 +00:00
|
|
|
$.expression,
|
|
|
|
$.for,
|
|
|
|
$.if_else,
|
2023-11-15 01:41:57 +00:00
|
|
|
$.index_assignment,
|
2023-10-31 20:25:13 +00:00
|
|
|
$.insert,
|
|
|
|
$.match,
|
2023-11-16 06:59:48 +00:00
|
|
|
$.return,
|
2023-10-31 20:25:13 +00:00
|
|
|
$.select,
|
2023-11-18 01:10:07 +00:00
|
|
|
$.use,
|
2023-10-31 20:25:13 +00:00
|
|
|
$.while,
|
|
|
|
),
|
|
|
|
optional(';'),
|
2023-10-29 23:31:06 +00:00
|
|
|
)),
|
2023-11-16 06:59:48 +00:00
|
|
|
|
2023-10-31 20:25:13 +00:00
|
|
|
expression: $ => prec.right(choice(
|
2023-10-18 21:52:56 +00:00
|
|
|
$._expression_kind,
|
|
|
|
seq('(', $._expression_kind, ')'),
|
2023-10-31 17:04:22 +00:00
|
|
|
)),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-11-27 15:27:44 +00:00
|
|
|
_expression_kind: $ => prec.right(choice(
|
2023-10-31 05:09:29 +00:00
|
|
|
$.function_call,
|
2023-10-18 21:52:56 +00:00
|
|
|
$.identifier,
|
2023-10-29 23:31:06 +00:00
|
|
|
$.index,
|
2023-10-18 21:52:56 +00:00
|
|
|
$.logic,
|
2023-10-31 05:09:29 +00:00
|
|
|
$.math,
|
|
|
|
$.value,
|
2023-11-15 03:26:32 +00:00
|
|
|
$.yield,
|
2023-11-27 15:27:44 +00:00
|
|
|
)),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-11-12 18:20:41 +00:00
|
|
|
_expression_list: $ => repeat1(prec.right(seq(
|
|
|
|
$.expression,
|
|
|
|
optional(','),
|
|
|
|
))),
|
2023-10-31 20:25:13 +00:00
|
|
|
|
2023-10-29 23:31:06 +00:00
|
|
|
identifier: $ => /[_a-zA-Z]+[_a-zA-Z0-9]?/,
|
2023-10-18 21:52:56 +00:00
|
|
|
|
|
|
|
value: $ => choice(
|
|
|
|
$.integer,
|
|
|
|
$.float,
|
|
|
|
$.string,
|
|
|
|
$.boolean,
|
|
|
|
$.list,
|
|
|
|
$.function,
|
|
|
|
$.table,
|
|
|
|
$.map,
|
|
|
|
),
|
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
integer: $ => token(prec.left(seq(
|
2023-10-31 09:51:37 +00:00
|
|
|
optional('-'),
|
|
|
|
repeat1(
|
|
|
|
choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')
|
|
|
|
),
|
|
|
|
))),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
float: $ => token(prec.left(seq(
|
2023-10-31 09:51:37 +00:00
|
|
|
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')),
|
|
|
|
))),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
|
|
|
string: $ => /("[^"]*?")|('[^']*?')|(`[^`]*?`)/,
|
|
|
|
|
|
|
|
boolean: $ => choice(
|
|
|
|
'true',
|
|
|
|
'false',
|
|
|
|
),
|
|
|
|
|
|
|
|
list: $ => seq(
|
|
|
|
'[',
|
2023-10-31 09:51:37 +00:00
|
|
|
repeat(prec.left(seq($.expression, optional(',')))),
|
2023-10-28 14:28:43 +00:00
|
|
|
']',
|
2023-10-18 21:52:56 +00:00
|
|
|
),
|
|
|
|
|
2023-10-29 23:31:06 +00:00
|
|
|
map: $ => seq(
|
2023-11-16 06:59:48 +00:00
|
|
|
'(',
|
2023-10-31 17:04:22 +00:00
|
|
|
repeat(seq(
|
2023-10-31 09:51:37 +00:00
|
|
|
$.identifier,
|
2023-10-31 17:04:22 +00:00
|
|
|
"=",
|
|
|
|
$.statement,
|
2023-10-31 09:51:37 +00:00
|
|
|
optional(',')
|
2023-10-31 17:04:22 +00:00
|
|
|
)),
|
2023-11-16 06:59:48 +00:00
|
|
|
')',
|
2023-10-29 23:31:06 +00:00
|
|
|
),
|
2023-10-31 17:04:22 +00:00
|
|
|
|
2023-11-16 02:35:40 +00:00
|
|
|
index: $ => prec.left(1, seq(
|
2023-10-29 23:31:06 +00:00
|
|
|
$.expression,
|
2023-10-30 21:11:06 +00:00
|
|
|
':',
|
2023-11-14 23:56:44 +00:00
|
|
|
$.expression,
|
2023-10-29 23:31:06 +00:00
|
|
|
optional(seq(
|
|
|
|
'..',
|
2023-11-14 23:56:44 +00:00
|
|
|
$.expression,
|
2023-10-29 23:31:06 +00:00
|
|
|
)),
|
|
|
|
)),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-30 21:11:06 +00:00
|
|
|
math: $ => prec.left(seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
$.expression,
|
|
|
|
$.math_operator,
|
|
|
|
$.expression,
|
|
|
|
)),
|
|
|
|
|
2023-10-31 13:31:10 +00:00
|
|
|
math_operator: $ => choice(
|
2023-10-18 21:52:56 +00:00
|
|
|
'+',
|
|
|
|
'-',
|
|
|
|
'*',
|
|
|
|
'/',
|
|
|
|
'%',
|
2023-10-31 13:31:10 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-30 21:11:06 +00:00
|
|
|
logic: $ => prec.right(seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
$.expression,
|
|
|
|
$.logic_operator,
|
|
|
|
$.expression,
|
|
|
|
)),
|
|
|
|
|
2023-10-31 13:31:10 +00:00
|
|
|
logic_operator: $ => choice(
|
2023-10-18 21:52:56 +00:00
|
|
|
'==',
|
|
|
|
'!=',
|
|
|
|
'&&',
|
|
|
|
'||',
|
|
|
|
'>',
|
|
|
|
'<',
|
|
|
|
">=",
|
|
|
|
"<=",
|
2023-10-31 13:31:10 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 13:31:10 +00:00
|
|
|
assignment: $ => seq(
|
2023-11-27 15:27:44 +00:00
|
|
|
field('identifier', $.identifier),
|
|
|
|
optional(field('type', $.type)),
|
|
|
|
field('assignment_operator', $.assignment_operator),
|
|
|
|
field('statement', $.statement),
|
2023-11-15 01:41:57 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
index_assignment: $ => seq(
|
|
|
|
$.index,
|
2023-10-18 21:52:56 +00:00
|
|
|
$.assignment_operator,
|
|
|
|
$.statement,
|
2023-10-31 13:31:10 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 13:31:10 +00:00
|
|
|
assignment_operator: $ => choice(
|
2023-10-18 21:52:56 +00:00
|
|
|
"=",
|
|
|
|
"+=",
|
|
|
|
"-=",
|
2023-10-31 13:31:10 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 20:25:13 +00:00
|
|
|
if_else: $ => prec.right(seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
$.if,
|
2023-10-31 17:04:22 +00:00
|
|
|
repeat($.else_if),
|
2023-10-30 21:11:06 +00:00
|
|
|
optional($.else),
|
2023-10-18 21:52:56 +00:00
|
|
|
)),
|
|
|
|
|
2023-10-31 20:25:13 +00:00
|
|
|
if: $ => seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
'if',
|
|
|
|
$.expression,
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-31 20:25:13 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 20:25:13 +00:00
|
|
|
else_if: $ => seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
'else if',
|
|
|
|
$.expression,
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-31 20:25:13 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 20:25:13 +00:00
|
|
|
else: $ => seq(
|
2023-10-18 21:52:56 +00:00
|
|
|
'else',
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-31 20:25:13 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
|
2023-10-31 17:04:22 +00:00
|
|
|
match: $ => prec.right(seq(
|
2023-10-31 05:09:29 +00:00
|
|
|
'match',
|
|
|
|
$.expression,
|
|
|
|
repeat1(seq(
|
|
|
|
$.expression,
|
|
|
|
'=>',
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-31 05:09:29 +00:00
|
|
|
)),
|
2023-10-31 17:04:22 +00:00
|
|
|
)),
|
2023-10-31 05:09:29 +00:00
|
|
|
|
2023-10-18 21:52:56 +00:00
|
|
|
while: $ => seq(
|
|
|
|
'while',
|
|
|
|
$.expression,
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-18 21:52:56 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
for: $ => seq(
|
2023-11-04 10:02:27 +00:00
|
|
|
choice(
|
|
|
|
'for',
|
|
|
|
'async for',
|
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
$.identifier,
|
|
|
|
'in',
|
|
|
|
$.expression,
|
2023-10-31 13:31:10 +00:00
|
|
|
$.block,
|
2023-10-18 21:52:56 +00:00
|
|
|
),
|
|
|
|
|
|
|
|
select: $ => prec.right(seq(
|
|
|
|
'select',
|
2023-10-31 22:18:39 +00:00
|
|
|
$.identifier_list,
|
2023-10-18 21:52:56 +00:00
|
|
|
'from',
|
2023-10-21 17:04:17 +00:00
|
|
|
$.expression,
|
2023-10-31 13:31:10 +00:00
|
|
|
optional($.block),
|
2023-10-18 21:52:56 +00:00
|
|
|
)),
|
|
|
|
|
|
|
|
insert: $ => prec.right(seq(
|
|
|
|
'insert',
|
|
|
|
'into',
|
|
|
|
$.identifier,
|
2023-10-22 17:55:56 +00:00
|
|
|
$.expression,
|
2023-10-18 21:52:56 +00:00
|
|
|
)),
|
2023-10-31 19:21:13 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
identifier_list: $ => prec.right(choice(
|
|
|
|
seq(
|
|
|
|
'|',
|
|
|
|
repeat(seq($.identifier, optional(','))),
|
|
|
|
'|',
|
|
|
|
),
|
|
|
|
)),
|
|
|
|
|
|
|
|
table: $ => prec.right(seq(
|
|
|
|
'table',
|
|
|
|
$.identifier_list,
|
|
|
|
$.expression,
|
|
|
|
)),
|
|
|
|
|
2023-11-21 18:42:47 +00:00
|
|
|
return: $ => seq(
|
|
|
|
'return',
|
|
|
|
$.expression,
|
|
|
|
),
|
|
|
|
|
|
|
|
use: $ => seq(
|
|
|
|
'use',
|
|
|
|
$.string,
|
|
|
|
),
|
|
|
|
|
2023-11-27 15:27:44 +00:00
|
|
|
type: $ => seq(
|
|
|
|
'<',
|
|
|
|
choice(
|
|
|
|
'any',
|
|
|
|
'bool',
|
|
|
|
'fn',
|
|
|
|
'int',
|
|
|
|
'list',
|
|
|
|
'map',
|
|
|
|
'str',
|
|
|
|
'table',
|
|
|
|
),
|
|
|
|
'>',
|
2023-11-21 18:42:47 +00:00
|
|
|
),
|
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
function: $ => seq(
|
2023-11-27 20:02:08 +00:00
|
|
|
'|',
|
|
|
|
repeat($._function_parameters),
|
|
|
|
'|',
|
|
|
|
optional(field('return_type', $.type)),
|
2023-10-31 22:18:39 +00:00
|
|
|
field('body', $.block),
|
2023-10-31 19:21:13 +00:00
|
|
|
),
|
|
|
|
|
2023-11-27 20:02:08 +00:00
|
|
|
_function_parameters: $ => seq(
|
|
|
|
$.identifier,
|
|
|
|
$.type,
|
|
|
|
optional(','),
|
|
|
|
),
|
|
|
|
|
2023-11-20 17:49:20 +00:00
|
|
|
function_call: $ => prec.right(1, seq(
|
2023-11-14 23:56:44 +00:00
|
|
|
'(',
|
2023-11-15 00:22:26 +00:00
|
|
|
choice(
|
|
|
|
$.built_in_function,
|
|
|
|
$._context_defined_function,
|
|
|
|
),
|
2023-11-14 23:56:44 +00:00
|
|
|
')',
|
|
|
|
)),
|
2023-10-31 19:21:13 +00:00
|
|
|
|
2023-11-15 00:22:26 +00:00
|
|
|
_context_defined_function: $ => prec.right(1, seq(
|
2023-11-18 01:10:07 +00:00
|
|
|
$.expression,
|
2023-10-31 20:25:13 +00:00
|
|
|
optional($._expression_list),
|
2023-10-31 19:21:13 +00:00
|
|
|
)),
|
2023-10-21 17:19:01 +00:00
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
built_in_function: $ => prec.right(seq(
|
|
|
|
$._built_in_function_name,
|
2023-10-31 20:25:13 +00:00
|
|
|
optional($._expression_list),
|
2023-10-31 19:21:13 +00:00
|
|
|
)),
|
|
|
|
|
2023-11-16 02:52:49 +00:00
|
|
|
yield: $ => prec.left(seq(
|
|
|
|
$.expression,
|
|
|
|
'->',
|
|
|
|
'(',
|
|
|
|
choice(
|
|
|
|
$.built_in_function,
|
|
|
|
$._context_defined_function,
|
|
|
|
),
|
|
|
|
')',
|
|
|
|
)),
|
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
_built_in_function_name: $ => choice(
|
2023-10-21 20:38:20 +00:00
|
|
|
// General
|
2023-10-21 17:19:01 +00:00
|
|
|
'assert',
|
|
|
|
'assert_equal',
|
2023-11-10 21:24:19 +00:00
|
|
|
'context',
|
2023-10-22 20:50:09 +00:00
|
|
|
'download',
|
2023-10-21 20:38:20 +00:00
|
|
|
'help',
|
2023-10-21 17:19:01 +00:00
|
|
|
'length',
|
2023-10-21 20:38:20 +00:00
|
|
|
'output',
|
2023-10-22 18:27:18 +00:00
|
|
|
'output_error',
|
|
|
|
'type',
|
2023-10-21 20:38:20 +00:00
|
|
|
|
|
|
|
// Filesystem
|
|
|
|
'append',
|
|
|
|
'metadata',
|
|
|
|
'move',
|
2023-10-21 17:19:01 +00:00
|
|
|
'read',
|
2023-10-31 19:21:13 +00:00
|
|
|
'workdir',
|
2023-10-21 17:19:01 +00:00
|
|
|
'write',
|
2023-10-21 20:38:20 +00:00
|
|
|
|
|
|
|
// Format conversion
|
|
|
|
'from_json',
|
|
|
|
'to_json',
|
|
|
|
'to_string',
|
2023-10-28 14:28:43 +00:00
|
|
|
'to_float',
|
2023-10-21 20:38:20 +00:00
|
|
|
|
|
|
|
// Command
|
|
|
|
'bash',
|
|
|
|
'fish',
|
|
|
|
'raw',
|
|
|
|
'sh',
|
|
|
|
'zsh',
|
2023-10-22 18:48:34 +00:00
|
|
|
|
|
|
|
// Random
|
|
|
|
'random',
|
|
|
|
'random_boolean',
|
|
|
|
'random_float',
|
|
|
|
'random_integer',
|
2023-10-22 20:32:55 +00:00
|
|
|
|
|
|
|
// Tables
|
|
|
|
'columns',
|
2023-10-22 20:33:27 +00:00
|
|
|
'rows',
|
2023-10-28 14:28:43 +00:00
|
|
|
|
|
|
|
// Lists
|
|
|
|
'reverse',
|
2023-10-21 17:19:01 +00:00
|
|
|
),
|
2023-10-18 21:52:56 +00:00
|
|
|
}
|
|
|
|
});
|