fixed grammar, grammar injections, wip topiary formatter

This commit is contained in:
2025-09-21 21:32:21 +02:00
parent 81af0683d1
commit 13d459f594
9 changed files with 21026 additions and 24553 deletions

8
tree-sitter/build.sh Executable file
View File

@@ -0,0 +1,8 @@
set -e
tree-sitter generate
make
tree-sitter build --wasm
rm -f /usr/lib64/nvim/parser/crepuscular.so
cp libtree-sitter-crepuscular.so /usr/lib64/nvim/parser/crepuscular.so
rm -f ~/.config/nvim/after/queries/crepuscular/*
cp queries/* ~/.config/nvim/after/queries/crepuscular/

View File

@@ -4,8 +4,24 @@ def tricky =
ab + cd
## doc comment
type [a,b] list = [a,b] List option
## *_this_*
## does *_this_* work?
## video::https://code.org[Cool]
##
## a list:
## * item1
## * item2
##
## === test
## Double TS language injection goes hard
##
## [source,c]
## ----
## int main() {
## return 0;
## }
## ----
type t List = 'EOL | 'Cons {hd: t, tl: t List}
# comment

View File

@@ -59,8 +59,13 @@ module.exports = grammar({
section_comment: $ =>
token(seq("###", /.*/)),
doc_comment_value: $ =>
choice(
token.immediate(/\n/),
token.immediate(/[^\n]*\n?/)),
doc_comment: $ =>
repeat1(seq('## ', token.immediate(/.*/))),
repeat1(seq('##', token.immediate(/ */), $.doc_comment_value)),
definition: $ => seq(
optional(field('doc', $.doc_comment)),
@@ -81,13 +86,13 @@ module.exports = grammar({
field('what', $.path),
'with',
field('tag', $.tag),
field('ty', $._type)),
field('ty', $.type)),
full_partial_type_definition: $ => seq(
"type",
"?", field('name', $.path),
"=",
field('type', $._type)
field('type', $.type)
),
type_definition: $ => seq(
@@ -102,18 +107,18 @@ module.exports = grammar({
)),
field('name', $.path),
"=",
field('type', $._type)
field('type', $.type)
),
_type_atom: $ => choice(
type_atom: $ => choice(
$.just_type,
$.partial_type,
seq('(', $._type, ')'),
seq('(', $.type, ')'),
$.record_type,
),
_type_non_fn: $ => choice(
$._type_atom,
$.type_atom,
$.tagged_type,
$.union_type,
$.partial_union_type,
@@ -122,20 +127,20 @@ module.exports = grammar({
$.recursive_type,
),
_type: $ => choice(
type: $ => choice(
$._type_non_fn,
$.fn_type,
),
union_type: $ => prec.left(1,
seq(
field('left', $._type),
field('left', $.type),
'|',
field('right', $._type))),
field('right', $.type))),
partial_union_type: $ => prec.left(1,
seq(
field('left', $._type),
field('left', $.type),
'|', '...',
field('partial', $.partial_type))),
@@ -143,17 +148,17 @@ module.exports = grammar({
tagged_type: $ => prec.right(3,
seq(field('tag', $.tag), optional(
field('type', choice(
$._type_atom,
$.type_atom,
$.parametrized_type))))),
multi_type_parameters: $ => seq('[',
field('arg', $._type),
repeat(seq(',', field('arg', $._type))),
field('arg', $.type),
repeat(seq(',', field('arg', $.type))),
']'),
parametrized_type: $ => prec.left(4, seq(
field('nest', choice(
$.multi_type_parameters,
$._type_atom,
$.type_atom,
)),
repeat(field('nest', $.path)),
field('type', $.path),
@@ -163,22 +168,22 @@ module.exports = grammar({
field('arg', $.identifier),
repeat(seq(',', field('arg', $.identifier))),
':',
field('type', $._type)),
field('type', $.type)),
recursive_type: $ => seq('&',
field('name', $.identifier),
field('type', $._type)),
field('type', $.type)),
partial_type: $ => seq('?', $.identifier),
fn_type: $ => prec.left(-10,
seq(field('arg', $._type), '->', field('res', $._type))),
seq(field('arg', $.type), '->', field('res', $.type))),
just_type: $ => prec(-1, $.path),
// TODO: doc comments
record_type_field: $ => seq(field('name', $.identifier), ':', field('type', $._type)),
record_type_field: $ => seq(field('name', $.identifier), ':', field('type', $.type)),
record_type: $ => seq(
'{',
repeat(seq(field('field', $.record_type_field), ',')),
@@ -214,26 +219,26 @@ module.exports = grammar({
list_expression: $ =>
seq(
'[',
repeat(seq($._expression, ',')),
optional($._expression),
repeat(seq($.expression, ',')),
optional($.expression),
']'),
field_access: $ => prec.left(
seq(field('expr', $._atom), ':', field('field', $.identifier))),
seq(field('expr', $.atom), ':', field('field', $.identifier))),
function_call: $ => prec.left("function_call",
seq(
field('fn', $._atom),
field('fn', $.atom),
'(',
repeat(seq(field('arg', $._expression), ',')),
optional(field('arg', $._expression)),
repeat(seq(field('arg', $.expression), ',')),
optional(field('arg', $.expression)),
')')),
ident_expr: $ => prec("ident",
$.path),
record_expr_field: $ =>
seq(field('field', $.identifier), ':', field('value', $._expression)),
seq(field('field', $.identifier), ':', field('value', $.expression)),
record_expr: $ => seq(
'{',
@@ -241,8 +246,8 @@ module.exports = grammar({
optional($.record_expr_field),
'}'),
_atom: $ => choice(
prec("parentrized", seq('(', $._expression, ')')),
atom: $ => choice(
prec("parentrized", seq('(', $.expression, ')')),
$.ident_expr,
$.char_literal,
$.string_literal,
@@ -257,93 +262,93 @@ module.exports = grammar({
'let',
field('name', $.identifier),
'=',
field('value', $._expression),
field('value', $.expression),
optional('in'),
field('body', $._expression),
field('body', $.expression),
)),
await_binding: $ => prec("let", seq(
'await',
field('name', $.identifier),
'=',
field('value', $._expression),
field('value', $.expression),
optional('in'),
field('body', $._expression),
field('body', $.expression),
)),
type_downcast: $ => seq(
field('expr', $._atom),
field('expr', $.atom),
'::',
field('as', $._type),
field('as', $.type),
),
lambda: $ => prec.right(4, seq(
field('arg', $.identifier),
optional(seq(':', field('arg_type', $._type_non_fn))),
'->',
field('body', $._expression)
field('body', $.expression)
)),
and_expr: $ => prec.left("with",
seq(
field('left', $._expression),
field('left', $.expression),
'and',
field('right', $._atom))),
field('right', $.atom))),
if_expr: $ => prec("if",
seq(
'if',
field('condition', $._expression),
field('condition', $.expression),
'then',
field('then', $._expression),
field('then', $.expression),
'else',
field('else', $._expression))),
field('else', $.expression))),
sub_expr: $ => prec.left("addition",
seq(field('left', $._expression), '-', field('right', $._expression))),
seq(field('left', $.expression), '-', field('right', $.expression))),
add_expr: $ => prec.left("addition",
seq(field('left', $._expression), '+', field('right', $._expression))),
seq(field('left', $.expression), '+', field('right', $.expression))),
divide_expr: $ => prec.left("multiplication",
seq(field('left', $._expression), '/', field('right', $._expression))),
seq(field('left', $.expression), '/', field('right', $.expression))),
multiply_expr: $ => prec.left("multiplication",
seq(field('left', $._expression), '*', field('right', $._expression))),
seq(field('left', $.expression), '*', field('right', $.expression))),
equal_expr: $ => prec.left("equal",
seq(field('left', $._expression), '=', field('right', $._expression))),
seq(field('left', $.expression), '=', field('right', $.expression))),
concat_expr: $ => prec.left("concat",
seq(field('left', $._expression), '++', field('right', $._expression))),
seq(field('left', $.expression), '++', field('right', $.expression))),
compose_expr: $ => prec.left("concat",
seq(field('left', $._expression), '=>', field('right', $._expression))),
seq(field('left', $.expression), '=>', field('right', $.expression))),
exponent_expr: $ => prec.left("exponent",
seq(field('left', $._expression), '^', field('right', $._atom))),
seq(field('left', $.expression), '^', field('right', $.atom))),
match_arm: $ => prec("match_arm",
seq(
field('cases', seq($._atom, repeat(seq('|', $._atom)))),
'->', field('expr', $._atom))),
field('cases', seq($.atom, repeat(seq('|', $.atom)))),
'->', field('expr', $.atom))),
match_expr: $ =>
seq('match', field('on', $._expression), 'with',
seq('match', field('on', $.expression), 'with',
field('arm', $.match_arm),
prec("new_match_arm", repeat(seq('|', field('arm', $.match_arm))))),
negate_expr: $ => prec.right("negate",
seq('-', field('expr', $._expression))),
seq('-', field('expr', $.expression))),
tag_expr: $ => prec.right("tag",
seq(
field('tag', $.tag),
field('expr', $._expression))),
field('expr', $.expression))),
await_expr: $ => prec.right("await",
seq('await', field('expr', $._expression))),
seq('await', field('expr', $.expression))),
_expression: $ => choice(
prec("expr_atom", $._atom),
expression: $ => choice(
prec("expr_atom", $.atom),
$.let_binding,
$.await_binding,
$.await_expr,
@@ -369,10 +374,10 @@ module.exports = grammar({
'def',
field('name', $.path),
choice(
seq(':', field('signature', $._type)),
seq(':', field('signature', $.type)),
seq(
optional(seq(':', field('signature', $._type))),
seq('=', field('value', $._expression)),
optional(seq(':', field('signature', $.type))),
seq('=', field('value', $.expression)),
)
),
),

View File

@@ -0,0 +1,3 @@
((doc_comment_value) @injection.content
(#set! injection.language "asciidoc")
(#set! injection.combined))

View File

@@ -0,0 +1,112 @@
; do not format inside these
[(string_literal)
(char_literal)
(comment)
(doc_comment)
] @leaf
; TODO: word wrapping in comments
(definition) @allow_blank_line_before
(doc_comment_value) @append_hardline
(doc_comment) @prepend_hardline @append_hardline
(comment) @append_hardline
(let_binding
"let" @prepend_spaced_softline @append_space
"=" @prepend_space @append_space ; @append_spaced_softline
value: (_) @prepend_indent_start @append_indent_end
body: (_) @prepend_hardline)
; TODO: report assertion error
;(await_binding
; body: (_) @prepend_hardline)
(def
":" @prepend_space @append_spaced_softline
signature: (_) @prepend_spaced_softline @prepend_indent_start @append_indent_end)
(def
"=" @prepend_space @append_spaced_softline @append_indent_start
value: (_) @append_indent_end)
(def "def" @append_space)
(if_expr
"if" @prepend_space @append_space
"then" @prepend_space @append_spaced_softline
then: (_) @prepend_indent_start @append_indent_end @append_hardline
"else" @prepend_space @append_spaced_softline
else: (_) @prepend_indent_start @append_indent_end)
((match_arm) @append_hardline . (match_arm))
(match_arm
"->" @append_spaced_softline @prepend_indent_start @append_indent_end)
(match_expr
"|" @append_space)
(match_expr
"match" @append_space
"with" @prepend_space @append_hardline
. (match_arm) @prepend_indent_start @append_indent_end)
; add newline between two consecutive definitions
((definition) @append_hardline . (definition))
(list_expression
"," @append_spaced_softline)
(list_expression
"[" @append_empty_softline
"]" @prepend_empty_softline)
(list_expression) @prepend_space @append_space
(atom
"(" @append_empty_softline
")" @prepend_empty_softline)
(extensible_union
"extensible" @append_space
"union" @append_space)
(extend_decl
"extend" @append_space
"with" @prepend_spaced_softline @append_space
tag: (_) @append_space)
(atom
"(" @delete
. (expression (atom))
. ")" @delete)
(full_partial_type_definition
"type" @append_space
"=" @prepend_space @append_spaced_softline)
(type_definition
"[" @prepend_space
"]" @append_space)
(type_definition
"," @append_space)
(type_definition
arg: (_) @append_space)
(type_definition
"type" @append_space
"=" @prepend_space @append_spaced_softline)
(function_call
"," @append_spaced_softline)
(record_expr_field
":" @append_spaced_softline)
(record_expr
"," @append_spaced_softline)
(record_expr
"{" @append_empty_softline
"}" @prepend_empty_softline)
; TODO: unify binary exprs
; TODO: scopes
; TODO: non-atom exprs
; TODO: types
; TODO: disable format regions

View File

@@ -86,6 +86,25 @@
]
}
},
"doc_comment_value": {
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "\\n"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^\\n]*\\n?"
}
}
]
},
"doc_comment": {
"type": "REPEAT1",
"content": {
@@ -99,8 +118,12 @@
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": ".*"
"value": " *"
}
},
{
"type": "SYMBOL",
"name": "doc_comment_value"
}
]
}
@@ -204,7 +227,7 @@
"name": "ty",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -237,7 +260,7 @@
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -328,12 +351,12 @@
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
},
"_type_atom": {
"type_atom": {
"type": "CHOICE",
"members": [
{
@@ -353,7 +376,7 @@
},
{
"type": "SYMBOL",
"name": "_type"
"name": "type"
},
{
"type": "STRING",
@@ -372,7 +395,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_type_atom"
"name": "type_atom"
},
{
"type": "SYMBOL",
@@ -400,7 +423,7 @@
}
]
},
"_type": {
"type": {
"type": "CHOICE",
"members": [
{
@@ -424,7 +447,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
},
{
@@ -436,7 +459,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -453,7 +476,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
},
{
@@ -504,7 +527,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_type_atom"
"name": "type_atom"
},
{
"type": "SYMBOL",
@@ -533,7 +556,7 @@
"name": "arg",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
},
{
@@ -550,7 +573,7 @@
"name": "arg",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -580,7 +603,7 @@
},
{
"type": "SYMBOL",
"name": "_type_atom"
"name": "type_atom"
}
]
}
@@ -651,7 +674,7 @@
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -676,7 +699,7 @@
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -705,7 +728,7 @@
"name": "arg",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
},
{
@@ -717,7 +740,7 @@
"name": "res",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -751,7 +774,7 @@
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -953,7 +976,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
},
{
"type": "STRING",
@@ -967,7 +990,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
},
{
"type": "BLANK"
@@ -991,7 +1014,7 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
},
{
@@ -1020,7 +1043,7 @@
"name": "fn",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
},
{
@@ -1037,7 +1060,7 @@
"name": "arg",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1055,7 +1078,7 @@
"name": "arg",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1098,7 +1121,7 @@
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1144,7 +1167,7 @@
}
]
},
"_atom": {
"atom": {
"type": "CHOICE",
"members": [
{
@@ -1159,7 +1182,7 @@
},
{
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
},
{
"type": "STRING",
@@ -1229,7 +1252,7 @@
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1249,7 +1272,7 @@
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1282,7 +1305,7 @@
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1302,7 +1325,7 @@
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1316,7 +1339,7 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
},
{
@@ -1328,7 +1351,7 @@
"name": "as",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -1381,7 +1404,7 @@
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1398,7 +1421,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1410,7 +1433,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
}
]
@@ -1431,7 +1454,7 @@
"name": "condition",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1443,7 +1466,7 @@
"name": "then",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1455,7 +1478,7 @@
"name": "else",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1472,7 +1495,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1484,7 +1507,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1501,7 +1524,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1513,7 +1536,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1530,7 +1553,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1542,7 +1565,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1559,7 +1582,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1571,7 +1594,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1588,7 +1611,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1600,7 +1623,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1617,7 +1640,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1629,7 +1652,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1646,7 +1669,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1658,7 +1681,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1675,7 +1698,7 @@
"name": "left",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1687,7 +1710,7 @@
"name": "right",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
}
]
@@ -1707,7 +1730,7 @@
"members": [
{
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
},
{
"type": "REPEAT",
@@ -1720,7 +1743,7 @@
},
{
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
]
}
@@ -1737,7 +1760,7 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
}
]
@@ -1755,7 +1778,7 @@
"name": "on",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
},
{
@@ -1811,7 +1834,7 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1836,7 +1859,7 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
@@ -1857,13 +1880,13 @@
"name": "expr",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]
}
},
"_expression": {
"expression": {
"type": "CHOICE",
"members": [
{
@@ -1871,7 +1894,7 @@
"value": "expr_atom",
"content": {
"type": "SYMBOL",
"name": "_atom"
"name": "atom"
}
},
{
@@ -1978,7 +2001,7 @@
"name": "signature",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -2001,7 +2024,7 @@
"name": "signature",
"content": {
"type": "SYMBOL",
"name": "_type"
"name": "type"
}
}
]
@@ -2023,7 +2046,7 @@
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
"name": "expression"
}
}
]

File diff suppressed because it is too large Load Diff

39774
tree-sitter/src/parser.c generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
{
languages = {
crepuscular = {
extensions = ["crr"],
indent = " ",
grammar.source.path = "./libtree-sitter-crepuscular.so",
}
}
}