tree-sitter-ucode 0.3.0 → 0.5.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.
Files changed (53) hide show
  1. package/README.md +32 -81
  2. package/grammar.js +221 -35
  3. package/markup/grammar.js +1057 -0
  4. package/markup/queries/folds.scm +20 -0
  5. package/markup/queries/highlights.scm +38 -0
  6. package/markup/queries/indents.scm +51 -0
  7. package/markup/queries/injections.scm +40 -0
  8. package/markup/queries/locals.scm +107 -0
  9. package/markup/queries/tags.scm +65 -0
  10. package/markup/queries/textobjects.scm +56 -0
  11. package/markup/src/grammar.json +5814 -0
  12. package/markup/src/node-types.json +3224 -0
  13. package/markup/src/parser.c +134512 -0
  14. package/markup/src/scanner.c +22 -0
  15. package/package.json +9 -5
  16. package/prebuilds/darwin-arm64/tree-sitter-ucode.node +0 -0
  17. package/prebuilds/linux-arm64/tree-sitter-ucode.node +0 -0
  18. package/prebuilds/linux-x64/tree-sitter-ucode.node +0 -0
  19. package/prebuilds/win32-x64/tree-sitter-ucode.node +0 -0
  20. package/queries/locals.scm +8 -0
  21. package/queries/tags.scm +15 -2
  22. package/scripts/generate-markup-grammar.js +93 -0
  23. package/src/grammar.json +1104 -233
  24. package/src/node-types.json +736 -69
  25. package/src/parser.c +106697 -25362
  26. package/src/scanner.c +16 -193
  27. package/src/scanner_impl.h +494 -0
  28. package/tree-sitter-ucode.wasm +0 -0
  29. package/tree-sitter-ucode_markup.wasm +0 -0
  30. package/tree-sitter.json +46 -22
  31. package/ucdocs/grammar.js +284 -0
  32. package/ucdocs/queries/highlights.scm +25 -0
  33. package/ucdocs/queries/tags.scm +22 -0
  34. package/ucdocs/src/grammar.json +1437 -0
  35. package/ucdocs/src/node-types.json +1347 -0
  36. package/ucdocs/src/parser.c +6387 -0
  37. package/ucdocs/src/tree_sitter/alloc.h +54 -0
  38. package/ucdocs/src/tree_sitter/array.h +330 -0
  39. package/ucdocs/src/tree_sitter/parser.h +286 -0
  40. package/tmpl/grammar.js +0 -68
  41. package/tmpl/queries/folds.scm +0 -4
  42. package/tmpl/queries/highlights.scm +0 -23
  43. package/tmpl/queries/indents.scm +0 -5
  44. package/tmpl/queries/injections.scm +0 -8
  45. package/tmpl/queries/locals.scm +0 -3
  46. package/tmpl/src/grammar.json +0 -251
  47. package/tmpl/src/node-types.json +0 -238
  48. package/tmpl/src/parser.c +0 -724
  49. package/tmpl/src/scanner.c +0 -174
  50. package/tree-sitter-ucode_tmpl.wasm +0 -0
  51. /package/{tmpl → markup}/src/tree_sitter/alloc.h +0 -0
  52. /package/{tmpl → markup}/src/tree_sitter/array.h +0 -0
  53. /package/{tmpl → markup}/src/tree_sitter/parser.h +0 -0
@@ -0,0 +1,22 @@
1
+ /*
2
+ * External scanner for the ucode_markup grammar.
3
+ *
4
+ * All implementation lives in src/scanner_impl.h (static functions). This
5
+ * file only exports the five tree_sitter_ucode_markup_external_scanner_*
6
+ * entry points — no ucode_* symbols leak into this shared library.
7
+ */
8
+
9
+ #include "../../src/scanner_impl.h"
10
+
11
+ void *tree_sitter_ucode_markup_external_scanner_create(void) { return NULL; }
12
+ void tree_sitter_ucode_markup_external_scanner_destroy(void *p) { (void)p; }
13
+ unsigned tree_sitter_ucode_markup_external_scanner_serialize(void *p, char *b) { (void)p; (void)b; return 0; }
14
+ void tree_sitter_ucode_markup_external_scanner_deserialize(void *p, const char *b, unsigned n) {
15
+ (void)p; (void)b; (void)n;
16
+ }
17
+
18
+ bool tree_sitter_ucode_markup_external_scanner_scan(
19
+ void *payload, TSLexer *lexer, const bool *valid_symbols
20
+ ) {
21
+ return ucode_scanner_scan(payload, lexer, valid_symbols);
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-ucode",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Ucode grammar for tree-sitter",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,9 +24,13 @@
24
24
  "bindings/node/*",
25
25
  "queries/*",
26
26
  "src/**",
27
- "tmpl/grammar.js",
28
- "tmpl/src/**",
29
- "tmpl/queries/*",
27
+ "markup/grammar.js",
28
+ "markup/src/**",
29
+ "markup/queries/*",
30
+ "scripts/generate-markup-grammar.js",
31
+ "ucdocs/grammar.js",
32
+ "ucdocs/src/**",
33
+ "ucdocs/queries/*",
30
34
  "*.wasm"
31
35
  ],
32
36
  "dependencies": {
@@ -47,7 +51,7 @@
47
51
  },
48
52
  "scripts": {
49
53
  "install": "node-gyp-build",
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",
54
+ "build": "node scripts/generate-markup-grammar.js && tree-sitter generate && tree-sitter generate markup/grammar.js --output markup/src && node-gyp-build && tree-sitter build --output ucode.so . && tree-sitter build --output ucode_markup.so ./markup",
51
55
  "test": "node scripts/run-tests.js",
52
56
  "prestart": "tree-sitter build --wasm",
53
57
  "start": "tree-sitter playground"
@@ -5,6 +5,7 @@
5
5
  ; Scopes
6
6
  ; -------------------------------------------------------------------------
7
7
 
8
+ (program) @local.scope
8
9
  (function_declaration) @local.scope
9
10
  (function_expression) @local.scope
10
11
  (arrow_function) @local.scope
@@ -24,6 +25,13 @@
24
25
 
25
26
  ; Function declaration names belong to the enclosing scope so that
26
27
  ; callers outside the function body can resolve them.
28
+ ;
29
+ ; NOTE: tree-sitter does not evaluate #set! predicates — it has no built-in
30
+ ; concept of "place this definition one scope level up." This annotation is
31
+ ; metadata only; the consumer must detect it (predicate name and args) and
32
+ ; implement the scope-parent walk itself. A consumer that builds a
33
+ ; scope -> definitions map by structural nesting alone will misplace this
34
+ ; definition: it will end up invisible to callers outside the function body.
27
35
  (function_declaration
28
36
  name: (identifier) @local.definition.function
29
37
  (#set! definition.function.scope parent))
package/queries/tags.scm CHANGED
@@ -1,5 +1,19 @@
1
1
  ; Tags queries for ucode.
2
2
  ; Used by GitHub code navigation and tools that index symbol definitions.
3
+ ;
4
+ ; NOTE on #strip! and #select-adjacent!: these are non-standard predicates with
5
+ ; no tree-sitter runtime support — tree-sitter only evaluates #eq?/#match?/
6
+ ; #not-match?-family predicates and filters non-matching captures; everything
7
+ ; else (including these two) passes through as metadata for the consumer to
8
+ ; act on. A consumer that reads @doc captures verbatim gets raw `/** ... */`
9
+ ; text with leading `*` characters intact (no #strip!), and may associate a
10
+ ; comment from several lines above with the wrong definition (no
11
+ ; #select-adjacent!). Expected semantics:
12
+ ; #strip! @capture <regex> — strip text matching <regex> from the
13
+ ; start/end of @capture's text.
14
+ ; #select-adjacent! @a @b — only keep this match if @a is on a line
15
+ ; immediately preceding @b (no blank
16
+ ; lines or other statements between).
3
17
 
4
18
  ; -------------------------------------------------------------------------
5
19
  ; Function definitions — named declarations (brace body or endfunction body)
@@ -87,5 +101,4 @@
87
101
 
88
102
  (call_expression
89
103
  function: (member_expression
90
- property: (property_identifier) @name)
91
- arguments: (_) @reference.call)
104
+ property: (property_identifier) @name)) @reference.call
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate markup/grammar.js from grammar.js.
4
+ *
5
+ * The main grammar has `program` as the first (start) rule so that `.uc`
6
+ * files work. For `.uc.tmpl` files we need `markup` to be the
7
+ * start rule. This script produces markup/grammar.js by:
8
+ *
9
+ * 1. Changing the grammar name from 'ucode' to 'ucode_markup'
10
+ * 2. Swapping the `markup` and `program` rule definitions so `markup`
11
+ * appears first (tree-sitter uses the first rule as the start rule)
12
+ *
13
+ * The generated file is checked in and rebuilt whenever grammar.js changes.
14
+ * Run via `npm run generate-markup` or as part of `npm run build`.
15
+ */
16
+
17
+ 'use strict';
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+
22
+ const srcPath = path.resolve(__dirname, '..', 'grammar.js');
23
+ const dstPath = path.resolve(__dirname, '..', 'markup', 'grammar.js');
24
+
25
+ let src = fs.readFileSync(srcPath, 'utf8');
26
+
27
+ // 1. Rename the grammar
28
+ src = src.replace(/name:\s*'ucode'/, "name: 'ucode_markup'");
29
+
30
+ // 2. Locate the `program` and `markup` rule definitions inside `rules: { ... }`.
31
+ // Each top-level rule starts with "\n <ident>: $ =>".
32
+ // We need to swap the two so `markup` comes first.
33
+
34
+ // Find the position of each rule's leading newline+spaces
35
+ const programMatch = src.match(/\n program: \$/);
36
+ const markupMatch = src.match(/\n markup: \$/);
37
+
38
+ if (!programMatch || !markupMatch) {
39
+ console.error('Could not locate program or markup rule in grammar.js');
40
+ process.exit(1);
41
+ }
42
+
43
+ const programIdx = src.indexOf('\n program: $');
44
+ const markupIdx = src.indexOf('\n markup: $');
45
+
46
+ if (programIdx === markupIdx) {
47
+ console.error('program and markup are at the same position?');
48
+ process.exit(1);
49
+ }
50
+
51
+ // Determine which comes first in the file
52
+ const firstIdx = Math.min(programIdx, markupIdx);
53
+ const secondIdx = Math.max(programIdx, markupIdx);
54
+
55
+ // Extract each rule: from its start up to the start of the next rule (or end-of-rules).
56
+ // A top-level rule starts at "\n <ident>: $" and ends just before the next "\n <ident>: $".
57
+ // We need the SPANS of the two rules to swap them.
58
+
59
+ function findNextRuleStart(text, from) {
60
+ // Match "\n <word>: $ =>" — the arrow function syntax uniquely identifies
61
+ // rule definitions vs. object properties at the same indentation level.
62
+ const re = /\n \w+: \$ =>/g;
63
+ re.lastIndex = from + 1; // skip the current match
64
+ const m = re.exec(text);
65
+ return m ? m.index : text.length;
66
+ }
67
+
68
+ const firstEnd = findNextRuleStart(src, firstIdx);
69
+ const secondEnd = findNextRuleStart(src, secondIdx);
70
+
71
+ const firstRule = src.slice(firstIdx, firstEnd);
72
+ const secondRule = src.slice(secondIdx, secondEnd);
73
+
74
+ // Reconstruct: everything before firstIdx, then the rule that was second,
75
+ // then everything between the two rules, then the rule that was first,
76
+ // then everything after secondEnd.
77
+ const between = src.slice(firstEnd, secondIdx);
78
+
79
+ const swapped =
80
+ src.slice(0, firstIdx) +
81
+ secondRule +
82
+ between +
83
+ firstRule +
84
+ src.slice(secondEnd);
85
+
86
+ // 3. Add a header comment noting this is generated
87
+ const header = '// GENERATED by scripts/generate-markup-grammar.js — do not edit by hand.\n';
88
+ const output = header + swapped;
89
+
90
+ fs.mkdirSync(path.dirname(dstPath), { recursive: true });
91
+ fs.writeFileSync(dstPath, output, 'utf8');
92
+
93
+ console.log(`Wrote ${path.relative(process.cwd(), dstPath)}`);