TS parser 100% done now

This commit is contained in:
2025-09-21 14:47:51 +02:00
parent e3ec5fee64
commit e8b7a76ddb
5 changed files with 27551 additions and 35103 deletions

View File

@@ -358,8 +358,6 @@ def add = a -> b -> a + b
- `func(arg1, arg2)`: function application. requires at least one argument. partial function applications are allowed too - `func(arg1, arg2)`: function application. requires at least one argument. partial function applications are allowed too
- `func(_, arg)`: bind some args from function, return funciton taking in the args with `_`, or the non-specified ones - `func(_, arg)`: bind some args from function, return funciton taking in the args with `_`, or the non-specified ones
- `expr :: type`: down-cast type - `expr :: type`: down-cast type
- `recExpr with fieldname: newFieldValue`: overwrites or adds a field to a record type.
type checking: identical to `recExpr and {fieldname: newFieldValue}`
- `recExpr and otherRecExpr`: "sum" fields together of both record expressions. - `recExpr and otherRecExpr`: "sum" fields together of both record expressions.
type checking: phi-unify `recExpr` with `otherRecExpr`, and require that both are non-nominal record types type checking: phi-unify `recExpr` with `otherRecExpr`, and require that both are non-nominal record types
- `if cond then a else b` - `if cond then a else b`

View File

@@ -24,6 +24,10 @@ module.exports = grammar({
precedences: _ => [ precedences: _ => [
[ [
"parentrized",
"function_call",
"expr_atom",
"ident", "ident",
"exponent", "exponent",
"multiplication", "multiplication",
@@ -34,19 +38,15 @@ module.exports = grammar({
"equal", "equal",
"if", "if",
"let", "let",
"new_match_arm",
"match_arm", "match_arm",
"new_match_arm",
"await", "await",
"tag", "tag",
], ],
], ],
conflicts: $ => [
[$.match_expr, $.match_expr], // TODO
],
rules: { rules: {
source_file: $ => repeat($._definition), source_file: $ => repeat($.definition),
_identifier_tok: $ => token(/[a-zA-Z_]+[a-zA-Z0-9_]*/), _identifier_tok: $ => token(/[a-zA-Z_]+[a-zA-Z0-9_]*/),
identifier: $ => reserved('toplevel_kw', $._identifier_tok), identifier: $ => reserved('toplevel_kw', $._identifier_tok),
@@ -55,33 +55,50 @@ module.exports = grammar({
comment: $ => comment: $ =>
token(seq("# ", /.*/)), token(seq("# ", /.*/)),
_definition: $ => choice( doc_comment: $ =>
repeat1(seq('## ', token.immediate(/.*/))),
definition: $ => seq(
optional(field('doc', $.doc_comment)),
field('body', choice(
$.full_partial_type_definition, $.full_partial_type_definition,
$.type_definition, $.type_definition,
$.extensible_union, $.extensible_union,
$.extend_decl, $.extend_decl,
$.def, $.def,
)),
), ),
extensible_union: $ => seq( extensible_union: $ => seq(
'extensible', 'union', $.path), 'extensible', 'union', $.path),
extend_decl: $ => seq( extend_decl: $ => seq(
'extend', $.path, 'with', $.tag, $._type), 'extend',
field('what', $.path),
'with',
field('tag', $.tag),
field('ty', $._type)),
full_partial_type_definition: $ => seq( full_partial_type_definition: $ => seq(
"type", "type",
"?", $.path, "?", field('name', $.path),
"=", "=",
$._type field('type', $._type)
), ),
type_definition: $ => seq( type_definition: $ => seq(
"type", "type",
repeat($.identifier), optional(choice(
$.path, field('arg', $.identifier),
seq(
'[',
repeat(seq(field('arg', $.identifier), ',')),
field('arg', $.identifier),
']'),
)),
field('name', $.path),
"=", "=",
$._type field('type', $._type)
), ),
_type_atom: $ => choice( _type_atom: $ => choice(
@@ -107,45 +124,63 @@ module.exports = grammar({
), ),
union_type: $ => prec.left(1, union_type: $ => prec.left(1,
seq($._type, '|', $._type)), seq(
field('left', $._type),
'|',
field('right', $._type))),
partial_union_type: $ => prec.left(1, partial_union_type: $ => prec.left(1,
seq($._type, '|', '...', $.partial_type)), seq(
field('left', $._type),
'|', '...',
field('partial', $.partial_type))),
tag: $ => new RustRegex("'(?:[a-zA-Z_][a-zA-Z0-9_]*(?:[.][a-zA-Z_0-9]+)*)"), tag: $ => new RustRegex("'(?:[a-zA-Z_][a-zA-Z0-9_]*(?:[.][a-zA-Z_0-9]+)*)"),
tagged_type: $ => prec.right(3, tagged_type: $ => prec.right(3,
seq($.tag, optional( seq(field('tag', $.tag), optional(
choice( field('type', choice(
$._type_atom, $._type_atom,
$.parametrized_type)))), $.parametrized_type))))),
multi_type_parameters: $ => seq('[', $._type, repeat(seq(',', $._type)), ']'), multi_type_parameters: $ => seq('[',
field('arg', $._type),
repeat(seq(',', field('arg', $._type))),
']'),
parametrized_type: $ => prec.left(4, seq( parametrized_type: $ => prec.left(4, seq(
choice( field('nest', choice(
$.multi_type_parameters, $.multi_type_parameters,
$._type_atom $._type_atom,
), )),
repeat1($.path) repeat(field('nest', $.path)),
field('type', $.path),
)), )),
with_type: $ => seq('with', $.identifier, repeat(seq(',', $.identifier)), ':', $._type), with_type: $ => seq('with',
field('arg', $.identifier),
repeat(seq(',', field('arg', $.identifier))),
':',
field('type', $._type)),
recursive_type: $ => seq('&', $.identifier, $._type), recursive_type: $ => seq('&',
field('name', $.identifier),
field('type', $._type)),
partial_type: $ => seq('?', $.identifier), partial_type: $ => seq('?', $.identifier),
fn_type: $ => prec.left(-10, fn_type: $ => prec.left(-10,
seq($._type, '->', $._type)), seq(field('arg', $._type), '->', field('res', $._type))),
just_type: $ => prec(-1, $.path), just_type: $ => prec(-1, $.path),
record_type_field: $ => seq($.identifier, ':', $._type), // TODO: doc comments
record_type_field: $ => seq(field('name', $.identifier), ':', field('type', $._type)),
record_type: $ => seq( record_type: $ => seq(
'{', '{',
repeat(seq($.record_type_field, ',')), repeat(seq(field('field', $.record_type_field), ',')),
optional(choice( optional(choice(
$.record_type_field, field('field', $.record_type_field),
seq('...', $.partial_type), seq('...', field('partial', $.partial_type)),
)), )),
'}'), '}'),
@@ -159,6 +194,7 @@ module.exports = grammar({
char_literal: $ => char_literal: $ =>
seq('\'', choice($.escape_sequence, $.char_middle), '\''), seq('\'', choice($.escape_sequence, $.char_middle), '\''),
// TODO: fstrings
string_literal: $ => string_literal: $ =>
seq('"', repeat(choice($.escape_sequence, $.string_middle)), '"'), seq('"', repeat(choice($.escape_sequence, $.string_middle)), '"'),
@@ -179,18 +215,21 @@ module.exports = grammar({
']'), ']'),
field_access: $ => prec.left( field_access: $ => prec.left(
seq($._atom, ':', $.identifier)), seq(field('expr', $._atom), ':', field('field', $.identifier))),
function_call: $ => prec.left(1, function_call: $ => prec.left("function_call",
seq($._atom, '(', seq(
repeat(seq($._expression, ',')), optional($._expression), field('fn', $._atom),
'(',
repeat(seq(field('arg', $._expression), ',')),
optional(field('arg', $._expression)),
')')), ')')),
ident_expr: $ => prec("ident", ident_expr: $ => prec("ident",
$.path), $.path),
record_expr_field: $ => record_expr_field: $ =>
seq($.identifier, ':', $._expression), seq(field('field', $.identifier), ':', field('value', $._expression)),
record_expr: $ => seq( record_expr: $ => seq(
'{', '{',
@@ -199,7 +238,7 @@ module.exports = grammar({
'}'), '}'),
_atom: $ => choice( _atom: $ => choice(
prec(0, seq('(', $._expression, ')')), prec("parentrized", seq('(', $._expression, ')')),
$.ident_expr, $.ident_expr,
$.char_literal, $.char_literal,
$.string_literal, $.string_literal,
@@ -241,68 +280,75 @@ module.exports = grammar({
field('body', $._expression) field('body', $._expression)
)), )),
with_expr: $ => prec.left("with",
seq($._expression, 'with', $._atom)),
and_expr: $ => prec.left("with", and_expr: $ => prec.left("with",
seq($._expression, 'and', $._atom)), seq(
field('left', $._expression),
'and',
field('right', $._atom))),
if_expr: $ => prec("if", if_expr: $ => prec("if",
seq('if', $._expression, 'then', $._expression, 'else', $._expression)), seq(
'if',
field('condition', $._expression),
'then',
field('then', $._expression),
'else',
field('else', $._expression))),
sub_expr: $ => prec.left("addition", sub_expr: $ => prec.left("addition",
seq($._expression, '-', $._expression)), seq(field('left', $._expression), '-', field('right', $._expression))),
add_expr: $ => prec.left("addition", add_expr: $ => prec.left("addition",
seq($._expression, '+', $._expression)), seq(field('left', $._expression), '+', field('right', $._expression))),
divide_expr: $ => prec.left("multiplication", divide_expr: $ => prec.left("multiplication",
seq($._expression, '/', $._expression)), seq(field('left', $._expression), '/', field('right', $._expression))),
multiply_expr: $ => prec.left("multiplication", multiply_expr: $ => prec.left("multiplication",
seq($._expression, '*', $._expression)), seq(field('left', $._expression), '*', field('right', $._expression))),
equal_expr: $ => prec.left("equal", equal_expr: $ => prec.left("equal",
seq($._expression, '=', $._expression)), seq(field('left', $._expression), '=', field('right', $._expression))),
concat_expr: $ => prec.left("concat", concat_expr: $ => prec.left("concat",
seq($._expression, '++', $._expression)), seq(field('left', $._expression), '++', field('right', $._expression))),
compose_expr: $ => prec.left("concat", compose_expr: $ => prec.left("concat",
seq($._expression, '=>', $._expression)), seq(field('left', $._expression), '=>', field('right', $._expression))),
exponent_expr: $ => prec.left("exponent", exponent_expr: $ => prec.left("exponent",
seq($._expression, '^', $._atom)), seq(field('left', $._expression), '^', field('right', $._atom))),
match_arm: $ => prec("match_arm", match_arm: $ => prec("match_arm",
seq( seq(
field('cases', seq($._atom, repeat(seq('|', $._atom)))), field('cases', seq($._atom, repeat(seq('|', $._atom)))),
'->', $._expression)), '->', field('expr', $._atom))),
match_expr: $ => match_expr: $ =>
seq('match', $._expression, 'with', seq('match', field('on', $._expression), 'with',
$.match_arm, field('arm', $.match_arm),
prec("new_match_arm", repeat(seq('|', $.match_arm)))), prec("new_match_arm", repeat(seq('|', field('arm', $.match_arm))))),
negate_expr: $ => prec.right("negate", negate_expr: $ => prec.right("negate",
seq('-', $._expression)), seq('-', field('expr', $._expression))),
tag_expr: $ => prec.right("tag", tag_expr: $ => prec.right("tag",
seq($.tag, $._expression)), seq(
field('tag', $.tag),
field('expr', $._expression))),
await_expr: $ => prec.right("await", await_expr: $ => prec.right("await",
seq('await', $._expression)), seq('await', field('expr', $._expression))),
_expression: $ => choice( _expression: $ => choice(
$._atom, prec("expr_atom", $._atom),
$.let_binding, $.let_binding,
$.await_binding, $.await_binding,
$.await_expr, $.await_expr,
$.type_downcast, $.type_downcast,
$.lambda, $.lambda,
$.with_expr,
$.and_expr, $.and_expr,
$.if_expr, $.if_expr,
$.match_expr,
$.tag_expr, $.tag_expr,
$.match_expr,
$.add_expr, $.add_expr,
$.sub_expr, $.sub_expr,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

54301
tree-sitter/src/parser.c generated

File diff suppressed because it is too large Load Diff