tree-sitter-batch 0.5.0 → 0.7.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/grammar.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const ci = (word) => new RegExp(word.split('').map((c) => /[a-zA-Z]/.test(c) ? `[${c.toLowerCase()}${c.toUpperCase()}]` : c).join(''));
2
2
  const kw = (word) => token(prec(10, ci(word)));
3
- const operand = ($) => [$.cond_exec, $.pipe_stmt, $.cmd, $.parenthesized];
3
+ const operand = ($) => [$.cond_exec, $.pipe_stmt, $.redirect_stmt, $.call_stmt, $.cmd, $.parenthesized];
4
4
 
5
5
  export default grammar({
6
6
  name: 'batch',
@@ -23,13 +23,43 @@ export default grammar({
23
23
  label: () => token(seq(':', /[a-zA-Z_][a-zA-Z0-9_-]*/)),
24
24
  variable_assignment: ($) => prec(8, seq(
25
25
  optional('@'), alias(kw('set'), $.set_keyword),
26
- optional(seq(/[ \t]+/, alias(/\/[aApP]/, $.set_option))),
27
- /[ \t]+/,
28
26
  choice(
29
- seq('"', alias(/[a-zA-Z_][a-zA-Z0-9_]*/, $.variable_name), '=', optional(alias(/[^"\r\n]+/, $.assignment_value)), '"'),
30
- seq(alias(/[a-zA-Z_][a-zA-Z0-9_]*/, $.variable_name), '=', optional(alias(/[^\r\n]+/, $.assignment_value))),
27
+ $.arithmetic_assignment,
28
+ $.prompt_assignment,
29
+ seq(
30
+ /[ \t]+/,
31
+ choice(
32
+ seq('"', alias(/[a-zA-Z_][a-zA-Z0-9_()\[\]]*/, $.variable_name), '=', optional($.quoted_assignment_value), '"'),
33
+ seq(alias(/[a-zA-Z_][a-zA-Z0-9_()\[\]]*/, $.variable_name), '=', optional($.assignment_value)),
34
+ ),
35
+ ),
31
36
  ),
32
37
  )),
38
+ arithmetic_assignment: ($) => seq(
39
+ optional(/[ \t]+/), alias(token(prec(10, ci('/a'))), $.set_option),
40
+ optional(/[ \t]+/), $.arithmetic_expression,
41
+ ),
42
+ prompt_assignment: ($) => seq(
43
+ optional(/[ \t]+/), alias(token(prec(10, ci('/p'))), $.set_option),
44
+ optional(/[ \t]+/),
45
+ alias(/[a-zA-Z_][a-zA-Z0-9_()\[\]]*/, $.variable_name), '=', optional($.assignment_value),
46
+ ),
47
+ arithmetic_expression: () => token(choice(
48
+ seq('"', /[^"\r\n]*/, '"'),
49
+ /[^\r\n"]+/,
50
+ )),
51
+ assignment_value: ($) => prec.right(repeat1(choice(
52
+ $.variable_reference,
53
+ alias(/[^%!\r\n]+/, $.assignment_literal),
54
+ alias('%', $.assignment_literal),
55
+ alias('!', $.assignment_literal),
56
+ ))),
57
+ quoted_assignment_value: ($) => prec.right(repeat1(choice(
58
+ $.variable_reference,
59
+ alias(/[^%!"\r\n]+/, $.assignment_literal),
60
+ alias('%', $.assignment_literal),
61
+ alias('!', $.assignment_literal),
62
+ ))),
33
63
  if_stmt: ($) => prec.right(8, seq(
34
64
  optional('@'), kw('if'),
35
65
  optional(kw('not')),
@@ -83,21 +113,28 @@ export default grammar({
83
113
  kw('in'), '(', optional($.for_set), ')', kw('do'),
84
114
  choice($.parenthesized, $.cmd),
85
115
  )),
86
- for_options: () => token(prec(10, choice(ci('/d'), seq(ci('/r'), optional(seq(/[ \t]+/, /[^\s]+/))), ci('/l'), seq(ci('/f'), optional(seq(/[ \t]+/, '"', /[^"]*/, '"')))))),
116
+ for_options: () => token(prec(10, choice(ci('/d'), seq(ci('/r'), optional(seq(/[ \t]+/, /(%[^\s%]|[^\s%])+%?/))), ci('/l'), seq(ci('/f'), optional(seq(/[ \t]+/, '"', /[^"]*/, '"')))))),
87
117
  for_variable: () => token(seq('%%', optional('~'), /[a-zA-Z]/)),
88
- for_set: () => /[^)\r\n]+/,
118
+ for_set: ($) => prec.right(repeat1(choice(
119
+ $.variable_reference,
120
+ alias(/[^%!)\r\n]+/, $.for_set_literal),
121
+ alias('%', $.for_set_literal),
122
+ alias('!', $.for_set_literal),
123
+ ))),
89
124
  parenthesized: ($) => seq('(', repeat(choice(seq($._stmt, /\r?\n/), /\r?\n/)), optional($._stmt), ')'),
90
- redirect_stmt: ($) => prec.right(4, seq(choice($.cmd, $.parenthesized), $.redirection)),
91
- redirection: ($) => prec.right(seq(
92
- optional(/[0-2]/), $.redirect_op, $.redirect_target,
93
- optional(seq(optional(/[0-2]/), $.redirect_op, $.redirect_target)),
94
- )),
95
- redirect_op: () => token(choice('2>&1', '>&1', '2>>', '2>', '>>', '>', '<')),
125
+ redirect_stmt: ($) => prec.right(4, seq(choice($.call_stmt, $.cmd, $.parenthesized), $.redirection)),
126
+ redirection: ($) => {
127
+ const file_redir = seq(optional(/[0-2]/), $.redirect_op, $.redirect_target);
128
+ const one_redir = choice(file_redir, $.fd_redirect);
129
+ return prec.right(repeat1(one_redir));
130
+ },
131
+ fd_redirect: () => token(choice('2>&1', '>&1')),
132
+ redirect_op: () => token(choice('2>>', '2>', '>>', '>', '<')),
96
133
  redirect_target: () => token(choice(ci('nul'), ci('con'), /[^\s|&><\r\n]+/)),
97
- pipe_stmt: ($) => prec.left(3, seq(choice($.cmd, $.parenthesized), '|', choice($.cmd, $.parenthesized))),
134
+ pipe_stmt: ($) => prec.left(3, seq(choice($.pipe_stmt, $.redirect_stmt, $.call_stmt, $.cmd, $.parenthesized), '|', choice($.redirect_stmt, $.call_stmt, $.cmd, $.parenthesized))),
98
135
  cond_exec: ($) => choice(
99
- prec.left(1, seq(choice(...operand($)), '&&', choice($.cmd, $.parenthesized))),
100
- prec.left(1, seq(choice(...operand($)), '||', choice($.cmd, $.parenthesized))),
136
+ prec.left(1, seq(choice(...operand($)), '&&', choice($.pipe_stmt, $.redirect_stmt, $.call_stmt, $.cmd, $.parenthesized))),
137
+ prec.left(1, seq(choice(...operand($)), '||', choice($.pipe_stmt, $.redirect_stmt, $.call_stmt, $.cmd, $.parenthesized))),
101
138
  ),
102
139
  command_sep: ($) => prec.left(0, seq(
103
140
  choice($.command_sep, ...operand($)),
@@ -105,12 +142,12 @@ export default grammar({
105
142
  choice(...operand($)),
106
143
  )),
107
144
  variable_reference: () => token(choice(
108
- seq('%', /[a-zA-Z_][a-zA-Z0-9_]*/, '%'),
145
+ seq('%', /[a-zA-Z_][a-zA-Z0-9_()\[\]]*/, '%'),
109
146
  seq('%~', /[a-zA-Z]*/, /[0-9]/),
110
147
  seq('%', /[0-9]/),
111
148
  seq('%%', optional('~'), /[a-zA-Z]/),
112
149
  seq('!', /[a-zA-Z_][a-zA-Z0-9_]*/, '!'),
113
- seq('%', /[a-zA-Z_][a-zA-Z0-9_]*/, ':', /[^%]+/, '%'),
150
+ seq('%', /[a-zA-Z_][a-zA-Z0-9_()\[\]]*/, ':', /[^%]+/, '%'),
114
151
  )),
115
152
  string: () => token(seq('"', /[^"\r\n]*/, '"')),
116
153
  cmd: ($) => prec.right(5, seq(optional('@'), $.command_name, optional($.argument_list))),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-batch",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "A Windows Batch/CMD grammar for tree-sitter",
5
5
  "type": "module",
6
6
  "repository": {
@@ -37,7 +37,8 @@
37
37
  "eslint": "^9.15.0",
38
38
  "eslint-config-treesitter": "^1.0.2",
39
39
  "prebuildify": "^6.0.1",
40
- "tree-sitter-cli": "0.24.7"
40
+ "tree-sitter-cli": "0.24.7",
41
+ "tree-sitter-go-types": "^0.1.0"
41
42
  },
42
43
  "peerDependencies": {
43
44
  "tree-sitter": ">=0.25.0"
@@ -51,6 +52,7 @@
51
52
  "install": "node-gyp-build",
52
53
  "prestart": "tree-sitter build --wasm",
53
54
  "start": "tree-sitter playground",
55
+ "generate": "tree-sitter generate && tree-sitter-go-types",
54
56
  "lint": "eslint grammar.js",
55
57
  "test": "node --test bindings/node/*_test.js"
56
58
  }
@@ -11,7 +11,8 @@
11
11
  (set_keyword) @keyword
12
12
  (variable_name) @variable
13
13
  (set_option) @constant
14
- (assignment_value) @string
14
+ (assignment_literal) @string
15
+ (arithmetic_expression) @string
15
16
 
16
17
  ; IF/FOR/GOTO/CALL statements
17
18
  (if_stmt) @keyword
@@ -25,6 +26,7 @@
25
26
  ; Operators
26
27
  (comparison_op) @operator
27
28
  (redirect_op) @operator
29
+ (fd_redirect) @operator
28
30
 
29
31
  ; Commands
30
32
  (command_name) @function
@@ -36,6 +38,9 @@
36
38
  ; Variables
37
39
  (variable_reference) @variable
38
40
 
41
+ ; FOR set literal content
42
+ (for_set_literal) @string
43
+
39
44
  ; FOR loop variables
40
45
  (for_variable) @variable.parameter
41
46