Skip to content

Commit 39e380d

Browse files
author
Ross MacLeod
committed
highlight and locals queries along with associated adjustments to syntax tree
1 parent c0929b7 commit 39e380d

13 files changed

+32823
-35152
lines changed

grammar.js

+80-50
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
function kw(keyword) {
2-
return alias(caseInsensitiveRe(keyword), keyword);
1+
function kw(keyword, name) {
2+
return alias(caseInsensitiveRe(keyword), name || keyword);
33
}
44

55
function kws(keywords) {
6-
return choice(...keywords.split(" ").map(kw));
6+
return choice(...keywords.split(" ").map((w) => kw(w)));
77
}
88

99
function caseInsensitiveRe(word) {
@@ -24,34 +24,51 @@ function caseInsensitiveRe(word) {
2424
}
2525

2626
function controlCommentWithArg(keyword, arg) {
27-
return seq("(", kw(keyword), ",", field("arg", alias(/[^)]*/, arg)), ")");
27+
return seq(
28+
"(",
29+
field("control", kw(keyword)),
30+
",",
31+
field("arg", alias(/[^)]*/, arg)),
32+
")"
33+
);
2834
}
2935

3036
function controlComment(keyword) {
31-
return seq("(", kw(keyword), ")");
37+
return seq(
38+
"(",
39+
field("control", kw(keyword)),
40+
")"
41+
);
3242
}
3343

3444
function controlCommentWithMessage($, keyword) {
35-
return seq("(", kw(keyword), ",", optional($._comment_parameters), ")");
45+
return seq(
46+
"(",
47+
field("control", kw(keyword)),
48+
",",
49+
optional($._comment_parameters),
50+
")"
51+
);
3652
}
3753

38-
const DECIMAL_RE = /[-+]?(\d+([.]\d+)?|[.]\d+)/;
54+
const NONNEGATIVE_DECIMAL_RE = /([.]\d+|\d+([.]\d+)?)/;
3955

4056
function valueWords($, letters) {
4157
return choice(
4258
...letters.split("").map(letter =>
4359
alias(
44-
seq(kw(letter), $._value),
45-
$[letter.toLowerCase()]
60+
// "E" seems to have some special meaning to treesitter, so avoid using it
61+
seq(field("word", kw(letter, `letter_${letter}`)), $._value),
62+
$.value_word
4663
)
4764
)
4865
);
4966
}
5067

5168
function valueWord($, tok, name) {
5269
return alias(
53-
seq(alias(tok, tok), $._value),
54-
$[name]
70+
seq(field("word", alias(tok, tok)), $._value),
71+
$.value_word
5572
)
5673
}
5774

@@ -106,7 +123,7 @@ module.exports = grammar({
106123
),
107124

108125
_wordish: $ => choice(
109-
valueWords($, "ABCDEFHIJKULPQRSTVWXYZ"),
126+
valueWords($, "ABCDEFHIJKLPQRSTUVWXYZ"),
110127
valueWord($, "$", "spindle"),
111128
$.polar_distance,
112129
$.polar_angle,
@@ -119,7 +136,11 @@ module.exports = grammar({
119136

120137
polar_distance: $ => seq("@", $._value),
121138
polar_angle: $ => seq("^", $._value),
122-
assignment: $ => seq($._parameter, "=", $._value),
139+
assignment: $ => seq(
140+
field("left", $._parameter),
141+
"=",
142+
field("right", $._value)
143+
),
123144

124145
g: $ => choice(
125146
kws("G0 G1 G2 G3 G4 G5 G5.1 G5.2 G5.3 G7 G8 G10 G17 G17.1 G18 G18.1 G19 G19.1 G20 G21"),
@@ -221,49 +242,54 @@ module.exports = grammar({
221242
"continue": $ => oLine($, kw("continue")),
222243

223244
_value: $ => choice(
224-
$.literal,
225-
$._parameter,
226-
$.expression
245+
prec(8, $._sign),
246+
prec(8, $.expression),
247+
prec(7, $.literal),
248+
prec(7, $._parameter),
227249
// LinuxCNC docs claim a bare function can be used here but that seems a tad too spooky,
228250
// so skip on it for now
229251
),
230252

231253
expression: $ => seq("[", $._expr, "]"),
232254

233255
_expr: $ => choice(
234-
prec(7, $._parameter),
235-
prec(7, $.literal),
256+
$._value,
236257
$.atan_call_expr,
237258
$.func_call_expr,
238259
$.binary_expr,
239260
),
240261

241-
_parameter: $ => choice(
242-
seq("#<", choice(
243-
alias(/_[^>]+/, $.named_global_parameter),
244-
alias(/[^_>][^>]*/, $.named_local_parameter),
245-
), ">"),
246-
alias(/#\d+/, $.numbered_parameter),
262+
_parameter: $ => seq(
263+
"#",
264+
choice(
265+
seq("<", choice(
266+
alias(/_[^>]+/, $.named_global_parameter),
267+
alias(/[^_>][^>]*/, $.named_local_parameter),
268+
), ">"),
269+
alias(/\d+/, $.numbered_parameter)
270+
)
247271
),
248272

249-
literal: $ => DECIMAL_RE,
273+
_sign: $ => seq(alias(/[+-]/, "sign"), $._value),
274+
275+
literal: $ => NONNEGATIVE_DECIMAL_RE,
250276

251277
binary_expr: $ => {
252278
function kwop(keyword) {
253-
return alias(caseInsensitiveRe(keyword), $[keyword]);
279+
return alias(caseInsensitiveRe(keyword), keyword);
254280
}
255281

256282
function kwops(keywords, prec) {
257283
return keywords.split(" ").map((s) => [kwop(s), prec]);
258284
}
259285

260286
const table = [
261-
[alias("**", $.pow), 6],
262-
[alias("*", $.mul), 5],
263-
[alias("/", $.div), 5],
287+
[alias("**", "**"), 6],
288+
[alias("*", "*"), 5],
289+
[alias("/", "/"), 5],
264290
[kwop("mod"), 5],
265-
[alias("+", $.add), 4],
266-
[alias("-", $.sub), 4],
291+
[alias("+", "+"), 4],
292+
[alias("-", "-"), 4],
267293
...kwops("eq ne gt ge lt le", 3),
268294
...kwops("and or xor", 2)
269295
];
@@ -290,27 +316,31 @@ module.exports = grammar({
290316
),
291317

292318
_comment: $ => choice(
293-
$.msg,
294-
$.probeopen,
295-
$.probeclose,
296-
$.logopen,
297-
$.logappend,
298-
$.logclose,
299-
$.log,
300-
$.debug,
301-
$.print,
319+
$.control_comment,
302320
prec(-1, $.comment),
303321
),
304322

305-
probeopen: $ => controlCommentWithArg("probeopen", $.filename),
306-
probeclose: $ => controlComment("probeclose"),
307-
logopen: $ => controlCommentWithArg("logopen", $.filename),
308-
logappend: $ => controlCommentWithArg("logappend", $.filename),
309-
logclose: $ => controlComment("logclose"),
310-
msg: $ => controlCommentWithMessage($, "msg"),
311-
log: $ => controlCommentWithMessage($, "log"),
312-
debug: $ => controlCommentWithMessage($, "debug"),
313-
print: $ => controlCommentWithMessage($, "print"),
323+
control_comment: $ => choice(
324+
$._msg,
325+
$._probeopen,
326+
$._probeclose,
327+
$._logopen,
328+
$._logappend,
329+
$._logclose,
330+
$._log,
331+
$._debug,
332+
$._print,
333+
),
334+
335+
_probeopen: $ => controlCommentWithArg("probeopen", $.filename),
336+
_probeclose: $ => controlComment("probeclose"),
337+
_logopen: $ => controlCommentWithArg("logopen", $.filename),
338+
_logappend: $ => controlCommentWithArg("logappend", $.filename),
339+
_logclose: $ => controlComment("logclose"),
340+
_msg: $ => controlCommentWithMessage($, "msg"),
341+
_log: $ => controlCommentWithMessage($, "log"),
342+
_debug: $ => controlCommentWithMessage($, "debug"),
343+
_print: $ => controlCommentWithMessage($, "print"),
314344

315345
comment: $ => choice(
316346
seq("(", token(prec(-1, /[^)]*/)), ")"),
@@ -320,7 +350,7 @@ module.exports = grammar({
320350
_comment_parameters: $ => repeat1(
321351
choice(
322352
$._parameter,
323-
/[^)#]+/,
353+
alias(/[^)#]+/, "text"),
324354
),
325355
),
326356
}

package.json

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "tree-sitter-LINUXCNC-GCODE",
2+
"name": "tree-sitter-linuxcnc-gcode",
33
"version": "0.0.1",
4-
"description": "LINUXCNC-GCODE grammar for tree-sitter",
4+
"description": "linuxcnc-gcode grammar for tree-sitter",
55
"main": "bindings/node",
66
"keywords": [
77
"parsing",
@@ -15,5 +15,13 @@
1515
},
1616
"scripts": {
1717
"test": "tree-sitter test"
18-
}
18+
},
19+
"tree-sitter": [
20+
{
21+
"scope": "source.linuxcnc-gcode",
22+
"file-types": [
23+
"ngc"
24+
]
25+
}
26+
]
1927
}

queries/highlights.scm

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
[
2+
"sub" "endsub"
3+
"if" "elseif" "else" "endif"
4+
"do" "while" "endwhile"
5+
"repeat" "endrepeat"
6+
"call" "return" "break" "continue"
7+
"O" "N"
8+
] @keyword
9+
10+
[
11+
"**" "*" "/" "mod" "+" "-"
12+
"eq" "ne" "gt" "ge" "lt" "le"
13+
"and" "or" "xor"
14+
"="
15+
] @operator
16+
17+
[ "=" ] @punctuation
18+
[ "[" "]" ] @punctuation.bracket
19+
20+
(literal) @number
21+
"sign" @number
22+
23+
[
24+
"letter_A" "letter_B" "letter_C"
25+
"letter_D" "letter_E" "letter_F" "letter_H"
26+
"letter_I" "letter_J" "letter_K"
27+
"letter_L" "letter_P" "letter_Q" "letter_R" "letter_S" "letter_T"
28+
"letter_U" "letter_V" "letter_W"
29+
"letter_X" "letter_Y" "letter_Z"
30+
"@" "^" "$"
31+
] @parameter
32+
33+
(g) @function.special
34+
(m) @function.macro
35+
(call [(o_name) (o_number)] @function)
36+
(sub [(o_name) (o_number)] @function)
37+
(endsub [(o_name) (o_number)] @function)
38+
(return [(o_name) (o_number)] @function)
39+
(if [(o_name) (o_number)] @label)
40+
(elseif [(o_name) (o_number)] @label)
41+
(else [(o_name) (o_number)] @label)
42+
(endif [(o_name) (o_number)] @label)
43+
(do [(o_name) (o_number)] @label)
44+
(while [(o_name) (o_number)] @label)
45+
(endwhile [(o_name) (o_number)] @label)
46+
(repeat [(o_name) (o_number)] @label)
47+
(endrepeat [(o_name) (o_number)] @label)
48+
(break [(o_name) (o_number)] @label)
49+
(continue [(o_name) (o_number)] @label)
50+
(block_number) @label
51+
52+
(
53+
[ (named_local_parameter) (named_global_parameter) (numbered_parameter) ]
54+
@variable
55+
)
56+
57+
"text" @string
58+
59+
(
60+
(control_comment
61+
control: _ @keyword
62+
arg: _? @string)
63+
)
64+
65+
(comment) @comment
66+

queries/locals.scm

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(sub) @local.scope
2+
3+
(assignment
4+
(numbered_parameter) @local.definition
5+
(#match? @local.definition "^([0-9]|[12][0-9]|30)$"))
6+
7+
(
8+
(numbered_parameter) @local.reference
9+
(#match? @local.reference "^([0-9]|[12][0-9]|30)$"))

0 commit comments

Comments
 (0)