tree-sitter-ucode 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -21
- package/package.json +3 -3
- package/prebuilds/darwin-arm64/tree-sitter-ucode.node +0 -0
- package/prebuilds/linux-arm64/tree-sitter-ucode.node +0 -0
- package/prebuilds/linux-x64/tree-sitter-ucode.node +0 -0
- package/prebuilds/win32-x64/tree-sitter-ucode.node +0 -0
- package/queries/folds.scm +38 -0
- package/queries/highlights.scm +6 -0
- package/queries/indents.scm +63 -0
- package/queries/textobjects.scm +84 -0
- package/src/parser.c +1 -1
- package/tmpl/grammar.js +2 -1
- package/tmpl/queries/folds.scm +4 -0
- package/tmpl/queries/indents.scm +5 -0
- package/tmpl/src/grammar.json +8 -0
- package/tmpl/src/node-types.json +8 -0
- package/tmpl/src/parser.c +42 -25
- package/tmpl/src/scanner.c +5 -0
- package/tree-sitter-ucode.wasm +0 -0
- package/tree-sitter-ucode_tmpl.wasm +0 -0
- package/tree-sitter.json +22 -21
package/README.md
CHANGED
|
@@ -7,7 +7,12 @@ Two grammars are provided:
|
|
|
7
7
|
| Grammar | Scope | File types |
|
|
8
8
|
|---------|-------|------------|
|
|
9
9
|
| `ucode` | `source.uc` | `.uc` |
|
|
10
|
-
| `ucode_tmpl` | `source.uc.tmpl` | `.uc
|
|
10
|
+
| `ucode_tmpl` | `source.uc.tmpl` | `.uc` (template files — detected by content) |
|
|
11
|
+
|
|
12
|
+
Both grammars use the `.uc` extension. Template files are distinguished from plain
|
|
13
|
+
code files by content: any `.uc` file whose first tag opener (`{%`, `{{`, or `{#`)
|
|
14
|
+
appears at the start of a line is automatically parsed by `ucode_tmpl`. Plain code
|
|
15
|
+
files fall back to `ucode`. See [File-type detection](#file-type-detection) below.
|
|
11
16
|
|
|
12
17
|
## Ucode vs JavaScript
|
|
13
18
|
|
|
@@ -55,10 +60,18 @@ npm test # runs tree-sitter test for ucode and ucode_tmpl
|
|
|
55
60
|
To filter by corpus file name:
|
|
56
61
|
|
|
57
62
|
```sh
|
|
58
|
-
npx tree-sitter test --file-name control_flow
|
|
63
|
+
npx tree-sitter test --lib-path ucode.so --lang-name ucode --file-name control_flow
|
|
59
64
|
npx tree-sitter test -p tmpl --file-name template
|
|
60
65
|
```
|
|
61
66
|
|
|
67
|
+
## File-type detection
|
|
68
|
+
|
|
69
|
+
Both grammars claim the `.uc` extension. Tools that respect `content-regex` in
|
|
70
|
+
`tree-sitter.json` (including the tree-sitter CLI ≥ 0.24) automatically route
|
|
71
|
+
template files to `ucode_tmpl` when a tag opener appears at the start of a line.
|
|
72
|
+
Editors that manage their own filetype dispatch (Neovim, Helix) need an explicit
|
|
73
|
+
rule — see the editor sections below.
|
|
74
|
+
|
|
62
75
|
## Use in Neovim (nvim-treesitter)
|
|
63
76
|
|
|
64
77
|
Add to your nvim-treesitter config (e.g. `~/.config/nvim/lua/plugins/treesitter.lua`):
|
|
@@ -85,15 +98,26 @@ parser_config.ucode_tmpl = {
|
|
|
85
98
|
}
|
|
86
99
|
```
|
|
87
100
|
|
|
88
|
-
Associate `.uc`
|
|
101
|
+
Associate `.uc` files with the right filetype. Since nvim-treesitter does not
|
|
102
|
+
use `content-regex`, the mapping must be done with a `BufRead` autocmd or a
|
|
103
|
+
filetype function that inspects the file content:
|
|
89
104
|
|
|
90
105
|
```lua
|
|
91
106
|
vim.filetype.add({
|
|
92
107
|
extension = {
|
|
93
|
-
uc
|
|
94
|
-
|
|
108
|
+
uc = function(path)
|
|
109
|
+
-- Files whose first tag opener is at the start of a line are templates
|
|
110
|
+
local f = io.open(path, "r")
|
|
111
|
+
if f then
|
|
112
|
+
local content = f:read("*a")
|
|
113
|
+
f:close()
|
|
114
|
+
if content:find("^%s*{[%%{#]", 1, false) or content:find("\n%s*{[%%{#]") then
|
|
115
|
+
return "ucode_tmpl"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
return "ucode"
|
|
119
|
+
end,
|
|
95
120
|
},
|
|
96
|
-
pattern = { [".*%.uc%.tmpl"] = "ucode_tmpl" },
|
|
97
121
|
})
|
|
98
122
|
```
|
|
99
123
|
|
|
@@ -103,32 +127,38 @@ Add to `~/.config/helix/languages.toml`:
|
|
|
103
127
|
|
|
104
128
|
```toml
|
|
105
129
|
[[language]]
|
|
106
|
-
name
|
|
107
|
-
scope
|
|
108
|
-
file-types
|
|
130
|
+
name = "ucode"
|
|
131
|
+
scope = "source.uc"
|
|
132
|
+
file-types = [{ glob = "*.uc" }]
|
|
109
133
|
comment-token = "//"
|
|
110
|
-
indent
|
|
111
|
-
grammar
|
|
134
|
+
indent = { tab-width = 2, unit = " " }
|
|
135
|
+
grammar = "ucode"
|
|
112
136
|
|
|
113
137
|
[[language]]
|
|
114
|
-
name
|
|
115
|
-
scope
|
|
116
|
-
|
|
117
|
-
|
|
138
|
+
name = "ucode-tmpl"
|
|
139
|
+
scope = "source.uc.tmpl"
|
|
140
|
+
comment-token = "{#"
|
|
141
|
+
indent = { tab-width = 2, unit = " " }
|
|
142
|
+
grammar = "ucode_tmpl"
|
|
118
143
|
|
|
119
144
|
[[grammar]]
|
|
120
145
|
name = "ucode"
|
|
121
|
-
source = { git = "https://github.com/m00qek/tree-sitter-ucode", rev = "
|
|
146
|
+
source = { git = "https://github.com/m00qek/tree-sitter-ucode", rev = "v0.3.0" }
|
|
122
147
|
|
|
123
148
|
[[grammar]]
|
|
124
149
|
name = "ucode_tmpl"
|
|
125
|
-
source = { git = "https://github.com/m00qek/tree-sitter-ucode", rev = "
|
|
150
|
+
source = { git = "https://github.com/m00qek/tree-sitter-ucode", rev = "v0.3.0", subpath = "tmpl" }
|
|
126
151
|
```
|
|
127
152
|
|
|
128
|
-
|
|
153
|
+
Helix does not support content-based filetype detection. To open a `.uc`
|
|
154
|
+
template file as `ucode-tmpl`, use `:set-language ucode-tmpl` in command mode,
|
|
155
|
+
or configure a file-specific override via a `.helix/languages.toml` in your
|
|
156
|
+
project.
|
|
157
|
+
|
|
158
|
+
## Template files
|
|
129
159
|
|
|
130
|
-
Template files mix raw text with code tags. The `ucode_tmpl` grammar produces
|
|
131
|
-
|
|
160
|
+
Template files mix raw text with code tags. The `ucode_tmpl` grammar produces a
|
|
161
|
+
`document` tree; editors use language injection to apply ucode highlighting
|
|
132
162
|
inside the code and expression tags.
|
|
133
163
|
|
|
134
164
|
| Tag | Purpose |
|
|
@@ -141,7 +171,17 @@ inside the code and expression tags.
|
|
|
141
171
|
| `{%+ ... %}` | Statement block — suppress `lstrip_blocks` stripping |
|
|
142
172
|
| `{#- ... -#}` | Comment — strip whitespace on both sides |
|
|
143
173
|
|
|
144
|
-
Opener and closer markers are independent: any opener variant may be combined
|
|
174
|
+
Opener and closer markers are independent: any opener variant may be combined
|
|
175
|
+
with any closer variant. `{%-` / `{{-` / `{#-` strip the preceding raw text;
|
|
176
|
+
`-%}` / `-}}` / `-#}` strip the following raw text. `{%+` suppresses
|
|
177
|
+
`lstrip_blocks` stripping and may be combined with `-%}`.
|
|
178
|
+
|
|
179
|
+
**EOF-implicit close**: a `{%` statement tag that reaches end-of-file without
|
|
180
|
+
an explicit `%}` is treated as implicitly closed. This supports the common
|
|
181
|
+
OpenWrt pattern of a file that opens one `{%` block at the top and contains
|
|
182
|
+
only ucode code, with no closing `%}`. The parse tree shows an `(eof_close)`
|
|
183
|
+
node in the `close` field. Expression (`{{`) and comment (`{#`) tags still
|
|
184
|
+
require explicit closers.
|
|
145
185
|
|
|
146
186
|
Example:
|
|
147
187
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tree-sitter-ucode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Ucode grammar for tree-sitter",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"prebuildify": "^6.0.1",
|
|
38
|
-
"tree-sitter-cli": "
|
|
38
|
+
"tree-sitter-cli": "0.26.9"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"tree-sitter": "^0.22.0"
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"scripts": {
|
|
49
49
|
"install": "node-gyp-build",
|
|
50
50
|
"build": "tree-sitter generate && tree-sitter generate tmpl/grammar.js --output tmpl/src && node-gyp-build && tree-sitter build --output ucode.so . && tree-sitter build --output ucode_tmpl.so ./tmpl",
|
|
51
|
-
"test": "
|
|
51
|
+
"test": "node scripts/run-tests.js",
|
|
52
52
|
"prestart": "tree-sitter build --wasm",
|
|
53
53
|
"start": "tree-sitter playground"
|
|
54
54
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
; Fold queries for ucode.
|
|
2
|
+
; Each captured node becomes a collapsible fold region.
|
|
3
|
+
|
|
4
|
+
; -------------------------------------------------------------------------
|
|
5
|
+
; Brace-delimited blocks
|
|
6
|
+
;
|
|
7
|
+
; statement_block covers brace-body function_declaration, function_expression,
|
|
8
|
+
; and arrow_function bodies — the signature line stays visible because the
|
|
9
|
+
; fold starts at '{', not at the 'function' keyword.
|
|
10
|
+
; -------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
[
|
|
13
|
+
(statement_block)
|
|
14
|
+
(switch_body)
|
|
15
|
+
(object)
|
|
16
|
+
(array)
|
|
17
|
+
] @fold
|
|
18
|
+
|
|
19
|
+
; -------------------------------------------------------------------------
|
|
20
|
+
; Alternative (colon/endif) syntax — fold the entire construct
|
|
21
|
+
; -------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
[
|
|
24
|
+
(if_alt_statement)
|
|
25
|
+
(for_alt_statement)
|
|
26
|
+
(for_in_alt_statement)
|
|
27
|
+
(while_alt_statement)
|
|
28
|
+
] @fold
|
|
29
|
+
|
|
30
|
+
; -------------------------------------------------------------------------
|
|
31
|
+
; Colon-body function declaration (function f(): ... endfunction)
|
|
32
|
+
;
|
|
33
|
+
; Brace-body function declarations are folded via (statement_block) above.
|
|
34
|
+
; The colon form has no statement_block, so we fold the whole declaration.
|
|
35
|
+
; We filter on "endfunction" so this pattern only matches the colon form.
|
|
36
|
+
; -------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
(function_declaration "endfunction") @fold
|
package/queries/highlights.scm
CHANGED
|
@@ -119,6 +119,12 @@
|
|
|
119
119
|
["import" "export"] @keyword.import
|
|
120
120
|
["as" "from"] @keyword.import
|
|
121
121
|
|
|
122
|
+
; 'default' in export context is a module keyword, not a conditional.
|
|
123
|
+
; These patterns are more specific than the generic ["switch" "case" "default"]
|
|
124
|
+
; below, so they take priority for 'default' tokens inside export constructs.
|
|
125
|
+
(export_statement "default" @keyword.import)
|
|
126
|
+
(export_specifier "default" @keyword.import)
|
|
127
|
+
|
|
122
128
|
; -------------------------------------------------------------------------
|
|
123
129
|
; Keywords — storage / operators
|
|
124
130
|
; -------------------------------------------------------------------------
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
; Indentation queries for ucode.
|
|
2
|
+
; Capture names follow the nvim-treesitter standard.
|
|
3
|
+
|
|
4
|
+
; -------------------------------------------------------------------------
|
|
5
|
+
; Brace-delimited constructs — increase indent inside
|
|
6
|
+
; -------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
[
|
|
9
|
+
(statement_block)
|
|
10
|
+
(switch_body)
|
|
11
|
+
(object)
|
|
12
|
+
(array)
|
|
13
|
+
(arguments)
|
|
14
|
+
(formal_parameters)
|
|
15
|
+
] @indent.begin
|
|
16
|
+
|
|
17
|
+
; Closing delimiters — decrease indent
|
|
18
|
+
[
|
|
19
|
+
"}"
|
|
20
|
+
"]"
|
|
21
|
+
")"
|
|
22
|
+
] @indent.end
|
|
23
|
+
|
|
24
|
+
; -------------------------------------------------------------------------
|
|
25
|
+
; Alternative (colon/endif) syntax
|
|
26
|
+
; -------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
; The ':' after the condition opens the body
|
|
29
|
+
(if_alt_statement ":" @indent.begin)
|
|
30
|
+
(elif_clause ":" @indent.begin)
|
|
31
|
+
(for_alt_statement ":" @indent.begin)
|
|
32
|
+
(for_in_alt_statement ":" @indent.begin)
|
|
33
|
+
(while_alt_statement ":" @indent.begin)
|
|
34
|
+
(function_declaration ":" @indent.begin)
|
|
35
|
+
|
|
36
|
+
; Closing keywords close the body
|
|
37
|
+
[
|
|
38
|
+
"endif"
|
|
39
|
+
"endfor"
|
|
40
|
+
"endwhile"
|
|
41
|
+
"endfunction"
|
|
42
|
+
] @indent.end
|
|
43
|
+
|
|
44
|
+
; -------------------------------------------------------------------------
|
|
45
|
+
; Branch keywords (else/elif) — dedent keyword, indent following body
|
|
46
|
+
; -------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
(else_clause "else") @indent.branch
|
|
49
|
+
(else_alt_clause "else") @indent.branch
|
|
50
|
+
(elif_clause "elif") @indent.branch
|
|
51
|
+
|
|
52
|
+
; else_alt_clause has no ':' delimiter (grammar: 'else' repeat(statement)),
|
|
53
|
+
; so @indent.branch alone only dedents the 'else' keyword — it does not
|
|
54
|
+
; open an indent scope for the body. Add @indent.begin on the whole node
|
|
55
|
+
; so the body statements are indented one level relative to 'else'.
|
|
56
|
+
(else_alt_clause) @indent.begin
|
|
57
|
+
|
|
58
|
+
; -------------------------------------------------------------------------
|
|
59
|
+
; Switch
|
|
60
|
+
; -------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
(switch_case "case") @indent.branch
|
|
63
|
+
(switch_default "default") @indent.branch
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
; Text-object queries for nvim-treesitter-textobjects.
|
|
2
|
+
; Provides @function, @parameter, @conditional, @loop, @call, and @block
|
|
3
|
+
; text objects for ucode source files.
|
|
4
|
+
|
|
5
|
+
; -------------------------------------------------------------------------
|
|
6
|
+
; Functions
|
|
7
|
+
; -------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
; Brace-body function declaration
|
|
10
|
+
(function_declaration
|
|
11
|
+
body: (statement_block) @function.inner) @function.outer
|
|
12
|
+
|
|
13
|
+
; Colon-body function declaration — outer only; no block node to target for inner
|
|
14
|
+
(function_declaration "endfunction") @function.outer
|
|
15
|
+
|
|
16
|
+
(function_expression
|
|
17
|
+
body: (statement_block) @function.inner) @function.outer
|
|
18
|
+
|
|
19
|
+
(arrow_function
|
|
20
|
+
body: (statement_block) @function.inner) @function.outer
|
|
21
|
+
|
|
22
|
+
; Arrow function with expression body (no braces).
|
|
23
|
+
; Uses the 'expression' supertype so all expression forms are matched
|
|
24
|
+
; without an explicit enumeration — including update_expression (x => x++),
|
|
25
|
+
; assignment_expression (x => y = 1), and any type added to the grammar later.
|
|
26
|
+
(arrow_function
|
|
27
|
+
body: (expression) @function.inner) @function.outer
|
|
28
|
+
|
|
29
|
+
; -------------------------------------------------------------------------
|
|
30
|
+
; Parameters
|
|
31
|
+
;
|
|
32
|
+
; @parameter.inner — the parameter node itself
|
|
33
|
+
; @parameter.outer — same node; nvim-treesitter-textobjects extends the
|
|
34
|
+
; selection to absorb adjacent ',' delimiters automatically when the
|
|
35
|
+
; capture name ends in .outer
|
|
36
|
+
; -------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
(formal_parameters (_) @parameter.inner)
|
|
39
|
+
(formal_parameters (_) @parameter.outer)
|
|
40
|
+
|
|
41
|
+
; -------------------------------------------------------------------------
|
|
42
|
+
; Conditionals
|
|
43
|
+
; -------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
(if_statement
|
|
46
|
+
consequence: (statement_block) @conditional.inner) @conditional.outer
|
|
47
|
+
|
|
48
|
+
(if_alt_statement) @conditional.outer
|
|
49
|
+
|
|
50
|
+
; -------------------------------------------------------------------------
|
|
51
|
+
; Loops
|
|
52
|
+
; -------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
(for_statement
|
|
55
|
+
body: (statement_block) @loop.inner) @loop.outer
|
|
56
|
+
|
|
57
|
+
(for_in_statement
|
|
58
|
+
body: (statement_block) @loop.inner) @loop.outer
|
|
59
|
+
|
|
60
|
+
(while_statement
|
|
61
|
+
body: (statement_block) @loop.inner) @loop.outer
|
|
62
|
+
|
|
63
|
+
(for_alt_statement) @loop.outer
|
|
64
|
+
(for_in_alt_statement) @loop.outer
|
|
65
|
+
(while_alt_statement) @loop.outer
|
|
66
|
+
|
|
67
|
+
; -------------------------------------------------------------------------
|
|
68
|
+
; Calls
|
|
69
|
+
; -------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
(call_expression
|
|
72
|
+
arguments: (arguments) @call.inner) @call.outer
|
|
73
|
+
|
|
74
|
+
; -------------------------------------------------------------------------
|
|
75
|
+
; Blocks
|
|
76
|
+
;
|
|
77
|
+
; @block.outer — the full statement_block including braces
|
|
78
|
+
; @block.inner — named children only; nvim-treesitter-textobjects selects
|
|
79
|
+
; from the first to the last captured child, covering the block interior
|
|
80
|
+
; without needing the deprecated #make-range! predicate
|
|
81
|
+
; -------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
(statement_block) @block.outer
|
|
84
|
+
(statement_block (_) @block.inner)
|
package/src/parser.c
CHANGED
|
@@ -32491,7 +32491,7 @@ TS_PUBLIC const TSLanguage *tree_sitter_ucode(void) {
|
|
|
32491
32491
|
.max_reserved_word_set_size = 28,
|
|
32492
32492
|
.metadata = {
|
|
32493
32493
|
.major_version = 0,
|
|
32494
|
-
.minor_version =
|
|
32494
|
+
.minor_version = 3,
|
|
32495
32495
|
.patch_version = 0,
|
|
32496
32496
|
},
|
|
32497
32497
|
};
|
package/tmpl/grammar.js
CHANGED
|
@@ -33,6 +33,7 @@ module.exports = grammar({
|
|
|
33
33
|
$._stmt_code, // content between {% ... %} (before the closer)
|
|
34
34
|
$._expr_code, // content between {{ ... }} (before the closer)
|
|
35
35
|
$._comment_body, // content between {# ... #} (before the closer)
|
|
36
|
+
$.eof_close, // emitted at EOF when inside a statement tag (implicit close)
|
|
36
37
|
],
|
|
37
38
|
|
|
38
39
|
// The template scanner handles all whitespace explicitly; no implicit extras.
|
|
@@ -49,7 +50,7 @@ module.exports = grammar({
|
|
|
49
50
|
statement_tag: $ => seq(
|
|
50
51
|
field('open', choice('{%-', '{%+', '{%')),
|
|
51
52
|
field('code', optional(alias($._stmt_code, $.code))),
|
|
52
|
-
field('close', choice('-%}', '%}')),
|
|
53
|
+
field('close', choice('-%}', '%}', $.eof_close)),
|
|
53
54
|
),
|
|
54
55
|
|
|
55
56
|
expression_tag: $ => seq(
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
; Indentation queries for ucode_tmpl.
|
|
2
|
+
; Raw text between tags is not indented by the template engine, so there are
|
|
3
|
+
; no template-level indent rules. Code inside statement_tag and expression_tag
|
|
4
|
+
; is parsed via language injection (see injections.scm) and indented according
|
|
5
|
+
; to the injected ucode grammar's indents.scm.
|
package/tmpl/src/grammar.json
CHANGED
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
{
|
|
90
90
|
"type": "STRING",
|
|
91
91
|
"value": "%}"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "SYMBOL",
|
|
95
|
+
"name": "eof_close"
|
|
92
96
|
}
|
|
93
97
|
]
|
|
94
98
|
}
|
|
@@ -235,6 +239,10 @@
|
|
|
235
239
|
{
|
|
236
240
|
"type": "SYMBOL",
|
|
237
241
|
"name": "_comment_body"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"type": "SYMBOL",
|
|
245
|
+
"name": "eof_close"
|
|
238
246
|
}
|
|
239
247
|
],
|
|
240
248
|
"inline": [],
|
package/tmpl/src/node-types.json
CHANGED
|
@@ -130,6 +130,10 @@
|
|
|
130
130
|
{
|
|
131
131
|
"type": "-%}",
|
|
132
132
|
"named": false
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"type": "eof_close",
|
|
136
|
+
"named": true
|
|
133
137
|
}
|
|
134
138
|
]
|
|
135
139
|
},
|
|
@@ -191,6 +195,10 @@
|
|
|
191
195
|
"type": "comment_content",
|
|
192
196
|
"named": true
|
|
193
197
|
},
|
|
198
|
+
{
|
|
199
|
+
"type": "eof_close",
|
|
200
|
+
"named": true
|
|
201
|
+
},
|
|
194
202
|
{
|
|
195
203
|
"type": "raw_text",
|
|
196
204
|
"named": true
|
package/tmpl/src/parser.c
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
#define LANGUAGE_VERSION 15
|
|
10
10
|
#define STATE_COUNT 17
|
|
11
11
|
#define LARGE_STATE_COUNT 4
|
|
12
|
-
#define SYMBOL_COUNT
|
|
12
|
+
#define SYMBOL_COUNT 24
|
|
13
13
|
#define ALIAS_COUNT 0
|
|
14
|
-
#define TOKEN_COUNT
|
|
15
|
-
#define EXTERNAL_TOKEN_COUNT
|
|
14
|
+
#define TOKEN_COUNT 19
|
|
15
|
+
#define EXTERNAL_TOKEN_COUNT 5
|
|
16
16
|
#define FIELD_COUNT 4
|
|
17
17
|
#define MAX_ALIAS_SEQUENCE_LENGTH 3
|
|
18
18
|
#define MAX_RESERVED_WORD_SET_SIZE 0
|
|
@@ -37,11 +37,12 @@ enum ts_symbol_identifiers {
|
|
|
37
37
|
sym__stmt_code = 15,
|
|
38
38
|
sym__expr_code = 16,
|
|
39
39
|
sym__comment_body = 17,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
sym_eof_close = 18,
|
|
41
|
+
sym_document = 19,
|
|
42
|
+
sym_statement_tag = 20,
|
|
43
|
+
sym_expression_tag = 21,
|
|
44
|
+
sym_comment_tag = 22,
|
|
45
|
+
aux_sym_document_repeat1 = 23,
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
static const char * const ts_symbol_names[] = {
|
|
@@ -63,6 +64,7 @@ static const char * const ts_symbol_names[] = {
|
|
|
63
64
|
[sym__stmt_code] = "code",
|
|
64
65
|
[sym__expr_code] = "code",
|
|
65
66
|
[sym__comment_body] = "comment_content",
|
|
67
|
+
[sym_eof_close] = "eof_close",
|
|
66
68
|
[sym_document] = "document",
|
|
67
69
|
[sym_statement_tag] = "statement_tag",
|
|
68
70
|
[sym_expression_tag] = "expression_tag",
|
|
@@ -89,6 +91,7 @@ static const TSSymbol ts_symbol_map[] = {
|
|
|
89
91
|
[sym__stmt_code] = sym__stmt_code,
|
|
90
92
|
[sym__expr_code] = sym__stmt_code,
|
|
91
93
|
[sym__comment_body] = sym__comment_body,
|
|
94
|
+
[sym_eof_close] = sym_eof_close,
|
|
92
95
|
[sym_document] = sym_document,
|
|
93
96
|
[sym_statement_tag] = sym_statement_tag,
|
|
94
97
|
[sym_expression_tag] = sym_expression_tag,
|
|
@@ -169,6 +172,10 @@ static const TSSymbolMetadata ts_symbol_metadata[] = {
|
|
|
169
172
|
.visible = true,
|
|
170
173
|
.named = true,
|
|
171
174
|
},
|
|
175
|
+
[sym_eof_close] = {
|
|
176
|
+
.visible = true,
|
|
177
|
+
.named = true,
|
|
178
|
+
},
|
|
172
179
|
[sym_document] = {
|
|
173
180
|
.visible = true,
|
|
174
181
|
.named = true,
|
|
@@ -359,7 +366,7 @@ static const TSLexerMode ts_lex_modes[STATE_COUNT] = {
|
|
|
359
366
|
[10] = {.lex_state = 0, .external_lex_state = 3},
|
|
360
367
|
[11] = {.lex_state = 0, .external_lex_state = 4},
|
|
361
368
|
[12] = {.lex_state = 0, .external_lex_state = 5},
|
|
362
|
-
[13] = {.lex_state = 0},
|
|
369
|
+
[13] = {.lex_state = 0, .external_lex_state = 6},
|
|
363
370
|
[14] = {.lex_state = 0},
|
|
364
371
|
[15] = {.lex_state = 0},
|
|
365
372
|
[16] = {.lex_state = 0},
|
|
@@ -385,6 +392,7 @@ static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = {
|
|
|
385
392
|
[sym__stmt_code] = ACTIONS(1),
|
|
386
393
|
[sym__expr_code] = ACTIONS(1),
|
|
387
394
|
[sym__comment_body] = ACTIONS(1),
|
|
395
|
+
[sym_eof_close] = ACTIONS(1),
|
|
388
396
|
},
|
|
389
397
|
[STATE(1)] = {
|
|
390
398
|
[sym_document] = STATE(16),
|
|
@@ -510,34 +518,36 @@ static const uint16_t ts_small_parse_table[] = {
|
|
|
510
518
|
[84] = 2,
|
|
511
519
|
ACTIONS(72), 1,
|
|
512
520
|
sym__stmt_code,
|
|
513
|
-
ACTIONS(70),
|
|
521
|
+
ACTIONS(70), 3,
|
|
522
|
+
sym_eof_close,
|
|
514
523
|
anon_sym_DASH_PERCENT_RBRACE,
|
|
515
524
|
anon_sym_PERCENT_RBRACE,
|
|
516
|
-
[
|
|
525
|
+
[93] = 2,
|
|
517
526
|
ACTIONS(76), 1,
|
|
518
527
|
sym__expr_code,
|
|
519
528
|
ACTIONS(74), 2,
|
|
520
529
|
anon_sym_DASH_RBRACE_RBRACE,
|
|
521
530
|
anon_sym_RBRACE_RBRACE,
|
|
522
|
-
[
|
|
531
|
+
[101] = 2,
|
|
523
532
|
ACTIONS(80), 1,
|
|
524
533
|
sym__comment_body,
|
|
525
534
|
ACTIONS(78), 2,
|
|
526
535
|
anon_sym_DASH_POUND_RBRACE,
|
|
527
536
|
anon_sym_POUND_RBRACE,
|
|
528
|
-
[
|
|
529
|
-
ACTIONS(82),
|
|
537
|
+
[109] = 1,
|
|
538
|
+
ACTIONS(82), 3,
|
|
539
|
+
sym_eof_close,
|
|
530
540
|
anon_sym_DASH_PERCENT_RBRACE,
|
|
531
541
|
anon_sym_PERCENT_RBRACE,
|
|
532
|
-
[
|
|
542
|
+
[115] = 1,
|
|
533
543
|
ACTIONS(84), 2,
|
|
534
544
|
anon_sym_DASH_RBRACE_RBRACE,
|
|
535
545
|
anon_sym_RBRACE_RBRACE,
|
|
536
|
-
[
|
|
546
|
+
[120] = 1,
|
|
537
547
|
ACTIONS(86), 2,
|
|
538
548
|
anon_sym_DASH_POUND_RBRACE,
|
|
539
549
|
anon_sym_POUND_RBRACE,
|
|
540
|
-
[
|
|
550
|
+
[125] = 1,
|
|
541
551
|
ACTIONS(88), 1,
|
|
542
552
|
ts_builtin_sym_end,
|
|
543
553
|
};
|
|
@@ -550,12 +560,12 @@ static const uint32_t ts_small_parse_table_map[] = {
|
|
|
550
560
|
[SMALL_STATE(8)] = 56,
|
|
551
561
|
[SMALL_STATE(9)] = 70,
|
|
552
562
|
[SMALL_STATE(10)] = 84,
|
|
553
|
-
[SMALL_STATE(11)] =
|
|
554
|
-
[SMALL_STATE(12)] =
|
|
555
|
-
[SMALL_STATE(13)] =
|
|
556
|
-
[SMALL_STATE(14)] =
|
|
557
|
-
[SMALL_STATE(15)] =
|
|
558
|
-
[SMALL_STATE(16)] =
|
|
563
|
+
[SMALL_STATE(11)] = 93,
|
|
564
|
+
[SMALL_STATE(12)] = 101,
|
|
565
|
+
[SMALL_STATE(13)] = 109,
|
|
566
|
+
[SMALL_STATE(14)] = 115,
|
|
567
|
+
[SMALL_STATE(15)] = 120,
|
|
568
|
+
[SMALL_STATE(16)] = 125,
|
|
559
569
|
};
|
|
560
570
|
|
|
561
571
|
static const TSParseActionEntry ts_parse_actions[] = {
|
|
@@ -608,6 +618,7 @@ enum ts_external_scanner_symbol_identifiers {
|
|
|
608
618
|
ts_external_token__stmt_code = 1,
|
|
609
619
|
ts_external_token__expr_code = 2,
|
|
610
620
|
ts_external_token__comment_body = 3,
|
|
621
|
+
ts_external_token_eof_close = 4,
|
|
611
622
|
};
|
|
612
623
|
|
|
613
624
|
static const TSSymbol ts_external_scanner_symbol_map[EXTERNAL_TOKEN_COUNT] = {
|
|
@@ -615,20 +626,23 @@ static const TSSymbol ts_external_scanner_symbol_map[EXTERNAL_TOKEN_COUNT] = {
|
|
|
615
626
|
[ts_external_token__stmt_code] = sym__stmt_code,
|
|
616
627
|
[ts_external_token__expr_code] = sym__expr_code,
|
|
617
628
|
[ts_external_token__comment_body] = sym__comment_body,
|
|
629
|
+
[ts_external_token_eof_close] = sym_eof_close,
|
|
618
630
|
};
|
|
619
631
|
|
|
620
|
-
static const bool ts_external_scanner_states[
|
|
632
|
+
static const bool ts_external_scanner_states[7][EXTERNAL_TOKEN_COUNT] = {
|
|
621
633
|
[1] = {
|
|
622
634
|
[ts_external_token__raw_text] = true,
|
|
623
635
|
[ts_external_token__stmt_code] = true,
|
|
624
636
|
[ts_external_token__expr_code] = true,
|
|
625
637
|
[ts_external_token__comment_body] = true,
|
|
638
|
+
[ts_external_token_eof_close] = true,
|
|
626
639
|
},
|
|
627
640
|
[2] = {
|
|
628
641
|
[ts_external_token__raw_text] = true,
|
|
629
642
|
},
|
|
630
643
|
[3] = {
|
|
631
644
|
[ts_external_token__stmt_code] = true,
|
|
645
|
+
[ts_external_token_eof_close] = true,
|
|
632
646
|
},
|
|
633
647
|
[4] = {
|
|
634
648
|
[ts_external_token__expr_code] = true,
|
|
@@ -636,6 +650,9 @@ static const bool ts_external_scanner_states[6][EXTERNAL_TOKEN_COUNT] = {
|
|
|
636
650
|
[5] = {
|
|
637
651
|
[ts_external_token__comment_body] = true,
|
|
638
652
|
},
|
|
653
|
+
[6] = {
|
|
654
|
+
[ts_external_token_eof_close] = true,
|
|
655
|
+
},
|
|
639
656
|
};
|
|
640
657
|
|
|
641
658
|
#ifdef __cplusplus
|
|
@@ -696,7 +713,7 @@ TS_PUBLIC const TSLanguage *tree_sitter_ucode_tmpl(void) {
|
|
|
696
713
|
.max_reserved_word_set_size = 0,
|
|
697
714
|
.metadata = {
|
|
698
715
|
.major_version = 0,
|
|
699
|
-
.minor_version =
|
|
716
|
+
.minor_version = 3,
|
|
700
717
|
.patch_version = 0,
|
|
701
718
|
},
|
|
702
719
|
};
|
package/tmpl/src/scanner.c
CHANGED
|
@@ -6,6 +6,7 @@ enum TokenType {
|
|
|
6
6
|
STMT_CODE,
|
|
7
7
|
EXPR_CODE,
|
|
8
8
|
COMMENT_BODY,
|
|
9
|
+
EOF_CLOSE,
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
void *tree_sitter_ucode_tmpl_external_scanner_create(void) { return NULL; }
|
|
@@ -160,6 +161,10 @@ bool tree_sitter_ucode_tmpl_external_scanner_scan(
|
|
|
160
161
|
) {
|
|
161
162
|
(void)payload;
|
|
162
163
|
|
|
164
|
+
if (valid_symbols[EOF_CLOSE] && lexer->lookahead == '\0') {
|
|
165
|
+
lexer->result_symbol = EOF_CLOSE;
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
163
168
|
if (valid_symbols[RAW_TEXT]) return scan_raw_text(lexer);
|
|
164
169
|
if (valid_symbols[STMT_CODE]) return scan_stmt_code(lexer);
|
|
165
170
|
if (valid_symbols[EXPR_CODE]) return scan_expr_code(lexer);
|
package/tree-sitter-ucode.wasm
CHANGED
|
Binary file
|
|
Binary file
|
package/tree-sitter.json
CHANGED
|
@@ -1,33 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"grammars": [
|
|
3
|
-
{
|
|
4
|
-
"name": "ucode",
|
|
5
|
-
"camelcase": "Ucode",
|
|
6
|
-
"scope": "source.uc",
|
|
7
|
-
"path": ".",
|
|
8
|
-
"file-types": [
|
|
9
|
-
"uc"
|
|
10
|
-
],
|
|
11
|
-
"highlights": [
|
|
12
|
-
"queries/highlights.scm"
|
|
13
|
-
],
|
|
14
|
-
"locals": [
|
|
15
|
-
"queries/locals.scm"
|
|
16
|
-
],
|
|
17
|
-
"tags": [
|
|
18
|
-
"queries/tags.scm"
|
|
19
|
-
],
|
|
20
|
-
"injection-regex": "^ucode$"
|
|
21
|
-
},
|
|
22
3
|
{
|
|
23
4
|
"name": "ucode_tmpl",
|
|
24
5
|
"camelcase": "UcodeTmpl",
|
|
25
6
|
"scope": "source.uc.tmpl",
|
|
26
7
|
"path": "./tmpl",
|
|
27
8
|
"file-types": [
|
|
28
|
-
"uc
|
|
9
|
+
"uc",
|
|
29
10
|
"utpl"
|
|
30
11
|
],
|
|
12
|
+
"content-regex": "(?m)^\\s*\\{[%{#]",
|
|
31
13
|
"highlights": [
|
|
32
14
|
"tmpl/queries/highlights.scm"
|
|
33
15
|
],
|
|
@@ -38,10 +20,29 @@
|
|
|
38
20
|
"tmpl/queries/injections.scm"
|
|
39
21
|
],
|
|
40
22
|
"injection-regex": "^ucode_tmpl$"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "ucode",
|
|
26
|
+
"camelcase": "Ucode",
|
|
27
|
+
"scope": "source.uc",
|
|
28
|
+
"path": ".",
|
|
29
|
+
"file-types": [
|
|
30
|
+
"uc"
|
|
31
|
+
],
|
|
32
|
+
"highlights": [
|
|
33
|
+
"queries/highlights.scm"
|
|
34
|
+
],
|
|
35
|
+
"locals": [
|
|
36
|
+
"queries/locals.scm"
|
|
37
|
+
],
|
|
38
|
+
"tags": [
|
|
39
|
+
"queries/tags.scm"
|
|
40
|
+
],
|
|
41
|
+
"injection-regex": "^ucode$"
|
|
41
42
|
}
|
|
42
43
|
],
|
|
43
44
|
"metadata": {
|
|
44
|
-
"version": "0.
|
|
45
|
+
"version": "0.3.0",
|
|
45
46
|
"license": "MIT",
|
|
46
47
|
"description": "Ucode grammar for tree-sitter",
|
|
47
48
|
"links": {
|