xaizek / zograscope (License: AGPLv3 only) (since 2018-12-07)
Mainly a syntax-aware diff that also provides a number of additional tools.
Commit a38b6e355ed257e4becca10d5e39b56db851d6ba

Update Lua parser to support Lua 5.4
Author: xaizek
Author date (UTC): 2022-11-27 18:22
Committer name: xaizek
Committer date (UTC): 2022-12-03 11:37
Parent(s): 3b71ff546123ac49bce4eb31db863154ecea3cdd
Signing key: 99DC5E4DB05F6BE2
Tree: d7f44dfa108a7e6ed97d1fe01d8b1e3a3ef87c04
File Lines added Lines deleted
docs/zograscope.md 3 2
man/zograscope.7 6 4
src/ts/lua/TSLuaLanguage.cpp 149 172
src/ts/lua/TSLuaSType.hpp 37 33
tests/tooling/Matcher.cpp 1 1
tests/ts/lua/ts-lua-diffing.cpp 15 0
third-party/tree-sitter/parsers/README.md 13 1
third-party/tree-sitter/parsers/lua-parser.c 9405 40736
third-party/tree-sitter/parsers/lua-scanner.c 315 0
third-party/tree-sitter/parsers/lua-scanner.cpp 0 232
File docs/zograscope.md changed (mode: 100644) (index 6a74dae..36fc312)
... ... LANGUAGE SUPPORT
21 21 | C++ | C++14 and earlier with common extensions | C++ | C++14 and earlier with common extensions
22 22 | Bash | Not targeting a specific version | Bash | Not targeting a specific version
23 23 | GNU Make | Most of the syntax | GNU Make | Most of the syntax
24 | Lua | Version 5.3
24 | Lua | Version 5.4
25 25
26 26 C C
27 27 - -
 
... ... Lua
85 85
86 86 Note the following: Note the following:
87 87
88 * non-5.3 versions might still work, albeit can produce worse results
88 * non-5.4 versions should work, but can produce worse results (however, syntax
89 is normally backward compatible so this shouldn't happen often)
89 90
90 91 Other Other
91 92 ----- -----
File man/zograscope.7 changed (mode: 100644) (index 7d3a6c4..5f65e12)
1 1 '\" t '\" t
2 .\" Automatically generated by Pandoc 2.17.1.1
2 .\" Automatically generated by Pandoc 2.19.2
3 3 .\" .\"
4 4 .\" Define V font for inline verbatim, using C font in formats .\" Define V font for inline verbatim, using C font in formats
5 5 .\" that render this, and otherwise B font. .\" that render this, and otherwise B font.
 
15 15 . ftr VB CB . ftr VB CB
16 16 . ftr VBI CBI . ftr VBI CBI
17 17 .\} .\}
18 .TH "zograscope" "7" "July 31, 2022" "" ""
18 .TH "zograscope" "7" "November 27, 2022" "" ""
19 19 .hy .hy
20 20 .SH NAME .SH NAME
21 21 .PP .PP
 
... ... T}
64 64 T{ T{
65 65 Lua Lua
66 66 T}@T{ T}@T{
67 Version 5.3
67 Version 5.4
68 68 T} T}
69 69 .TE .TE
70 70 .SS C .SS C
 
... ... that often)
125 125 .PP .PP
126 126 Note the following: Note the following:
127 127 .IP \[bu] 2 .IP \[bu] 2
128 non-5.3 versions might still work, albeit can produce worse results
128 non-5.4 versions should work, but can produce worse results (however,
129 syntax is normally backward compatible so this shouldn\[cq]t happen
130 often)
129 131 .SS Other .SS Other
130 132 .PP .PP
131 133 More languages should be added in the future, maybe with external More languages should be added in the future, maybe with external
File src/ts/lua/TSLuaLanguage.cpp changed (mode: 100644) (index 121ee6f..ff4fe6d)
... ... TsLuaLanguage::TsLuaLanguage() : tsLanguage(*tree_sitter_lua())
35 35 { "separator", +TSLuaSType::Separator }, { "separator", +TSLuaSType::Separator },
36 36 { "comment", +TSLuaSType::Comment }, { "comment", +TSLuaSType::Comment },
37 37
38 { "program", +TSLuaSType::Program },
38 { "chunk", +TSLuaSType::Program },
39 39
40 { "function", +TSLuaSType::Function },
41 { "function_definition", +TSLuaSType::Function },
42 { "local_function", +TSLuaSType::Function },
43 { "function_name", +TSLuaSType::FunctionName },
44 { "function_name_field", +TSLuaSType::FunctionName },
45 { "function_body", +TSLuaSType::FunctionBody },
46 { "parameters", +TSLuaSType::Parameters },
47 { "parameter", +TSLuaSType::Parameter },
48
49 { "function_call", +TSLuaSType::FunctionCall },
50 { "function_call_statement", +TSLuaSType::CallStatement },
51 { "arguments", +TSLuaSType::Arguments },
52
53 { "local_variable_declaration_statement", +TSLuaSType::DeclStatement },
54 { "variable_declaration_statement", +TSLuaSType::DeclStatement },
55 { "local_variable_declaration", +TSLuaSType::VariableDecl },
56 { "variable_declaration", +TSLuaSType::VariableDecl },
57 { "variable_declarator", +TSLuaSType::VariableDeclarator },
58
59 { "unary_operation", +TSLuaSType::UnaryOperation },
60 { "binary_operation", +TSLuaSType::BinaryOperation },
61
62 { "expression", +TSLuaSType::Expression },
40 { "binary_expression", +TSLuaSType::BinaryExpression },
63 41 { "condition_expression", +TSLuaSType::ConditionExpression }, { "condition_expression", +TSLuaSType::ConditionExpression },
64 { "loop_expression", +TSLuaSType::LoopExpression },
65 { "field_expression", +TSLuaSType::FieldExpression },
42 { "expression", +TSLuaSType::Expression },
43 { "parenthesized_expression", +TSLuaSType::ParenthesizedExpression },
44 { "prefix_expression", +TSLuaSType::PrefixExpression },
45 { "unary_expression", +TSLuaSType::UnaryExpression },
66 46
67 { "if_statement", +TSLuaSType::IfStatement },
68 { "elseif", +TSLuaSType::ElseIfStatement },
69 { "else", +TSLuaSType::ElseStatement },
47 { "table", +TSLuaSType::Table },
48 { "expression_list", +TSLuaSType::ExpressionList },
70 49
50 { "statement", +TSLuaSType::Statement },
51 { "call_statement", +TSLuaSType::CallStatement },
71 52 { "do_statement", +TSLuaSType::DoStatement }, { "do_statement", +TSLuaSType::DoStatement },
72 { "repeat_statement", +TSLuaSType::RepeatStatement },
73 { "while_statement", +TSLuaSType::WhileStatement },
74 { "for_in_statement", +TSLuaSType::ForInStatement },
75 { "for_statement", +TSLuaSType::ForStatement },
76
53 { "empty_statement", +TSLuaSType::EmptyStatement },
54 { "for_generic_statement", +TSLuaSType::ForGenericStatement },
55 { "for_numeric_statement", +TSLuaSType::ForNumericStatement },
56 { "function_definition_statement",
57 +TSLuaSType::FunctionDefinitionStatement },
77 58 { "goto_statement", +TSLuaSType::GotoStatement }, { "goto_statement", +TSLuaSType::GotoStatement },
78 59 { "label_statement", +TSLuaSType::LabelStatement }, { "label_statement", +TSLuaSType::LabelStatement },
60 { "local_function_definition_statement",
61 +TSLuaSType::LocalFunctionDefinitionStatement },
62 { "repeat_statement", +TSLuaSType::RepeatStatement },
79 63 { "return_statement", +TSLuaSType::ReturnStatement }, { "return_statement", +TSLuaSType::ReturnStatement },
64 { "while_statement", +TSLuaSType::WhileStatement },
80 65
81 { "table", +TSLuaSType::Table },
82 { "field", +TSLuaSType::Field },
83 { "quoted_field", +TSLuaSType::QuotedField },
66 { "if_statement", +TSLuaSType::IfStatement },
67 { "else_clause", +TSLuaSType::ElseClause },
68 { "elseif_clause", +TSLuaSType::ElseifClause },
69
70 { "function_body", +TSLuaSType::FunctionBody },
71 { "function_definition", +TSLuaSType::FunctionDefinition },
84 72
85 { "global_variable", +TSLuaSType::GlobalVariable },
73 { "local_variable_declaration", +TSLuaSType::LocalVariableDeclaration },
74 { "variable", +TSLuaSType::Variable },
75 { "variable_assignment", +TSLuaSType::VariableAssignment },
76 { "variable_list", +TSLuaSType::VariableList },
77
78 { "parameter", +TSLuaSType::Parameter },
79 { "parameter_list", +TSLuaSType::ParameterList },
80
81 { "argument_list", +TSLuaSType::ArgumentList },
82 { "attribute", +TSLuaSType::Attribute },
83 { "block", +TSLuaSType::Block },
84 { "call", +TSLuaSType::Call },
85 { "field", +TSLuaSType::Field },
86 { "field_list", +TSLuaSType::FieldList },
86 87
87 88 { "not", +TSLuaSType::UnaryOperator }, { "not", +TSLuaSType::UnaryOperator },
88 89 { "and", +TSLuaSType::BinaryOperator }, { "and", +TSLuaSType::BinaryOperator },
 
... ... TsLuaLanguage::TsLuaLanguage() : tsLanguage(*tree_sitter_lua())
90 91 }; };
91 92
92 93 types = { types = {
93 { "local", Type::Specifiers },
94
95 94 { "comment", Type::Comments }, { "comment", Type::Comments },
95 { "shebang", Type::Directives },
96 96
97 { "function", Type::Keywords },
98 { "while", Type::Keywords },
99 { "repeat", Type::Keywords },
100 { "until", Type::Keywords },
101 { "if", Type::Keywords },
102 { "then", Type::Keywords },
97 { "local", Type::Specifiers },
98
99 { "do", Type::Keywords },
103 100 { "else", Type::Keywords }, { "else", Type::Keywords },
104 101 { "elseif", Type::Keywords }, { "elseif", Type::Keywords },
105 102 { "end", Type::Keywords }, { "end", Type::Keywords },
106 { "for", Type::Keywords },
107 { "in", Type::Keywords },
108 { "do", Type::Keywords },
109 { "true", Type::Keywords },
110 103 { "false", Type::Keywords }, { "false", Type::Keywords },
111 { "return", Type::Keywords },
104 { "for", Type::Keywords },
105 { "function", Type::Keywords },
106 { "if", Type::Keywords },
112 107 { "nil", Type::Keywords }, { "nil", Type::Keywords },
108 { "repeat", Type::Keywords },
109 { "return", Type::Keywords },
110 { "then", Type::Keywords },
111 { "true", Type::Keywords },
112 { "until", Type::Keywords },
113 { "while", Type::Keywords },
113 114
114 115 { "break_statement", Type::Jumps }, { "break_statement", Type::Jumps },
115 { "next", Type::Jumps },
116 116 { "goto", Type::Jumps }, { "goto", Type::Jumps },
117 117
118 { "number", Type::IntConstants },
119 { "string", Type::StrConstants },
120
121 { "method", Type::Functions },
122
123 { "_G", Type::Identifiers },
124 { "_VERSION", Type::Identifiers },
125 { "self", Type::Identifiers },
126 { "identifier", Type::Identifiers },
127 { "property_identifier", Type::Identifiers },
128
129 118 { "and", Type::Keywords }, { "and", Type::Keywords },
130 { "or", Type::Keywords },
119 { "in", Type::Keywords },
131 120 { "not", Type::Keywords }, { "not", Type::Keywords },
121 { "or", Type::Keywords },
132 122
133 { "==", Type::Comparisons },
134 { "~=", Type::Comparisons },
123 { "identifier", Type::Identifiers },
124 { "number", Type::IntConstants },
125 { "string", Type::StrConstants },
126
127 { "<=", Type::Comparisons },
135 128 { "<", Type::Comparisons }, { "<", Type::Comparisons },
136 129 { ">", Type::Comparisons }, { ">", Type::Comparisons },
137 { "<=", Type::Comparisons },
130 { "==", Type::Comparisons },
138 131 { ">=", Type::Comparisons }, { ">=", Type::Comparisons },
132 { "~=", Type::Comparisons },
133
134 { "=", Type::Assignments },
135
136 { "(", Type::LeftBrackets },
137 { "{", Type::LeftBrackets },
138 { "[", Type::LeftBrackets },
139
140 { ")", Type::RightBrackets },
141 { "}", Type::RightBrackets },
142 { "]", Type::RightBrackets },
139 143
140 144 { "~", Type::Operators }, { "~", Type::Operators },
141 145 { "#", Type::Operators }, { "#", Type::Operators },
 
... ... TsLuaLanguage::TsLuaLanguage() : tsLanguage(*tree_sitter_lua())
152 156 { ">>", Type::Operators }, { ">>", Type::Operators },
153 157 { "..", Type::Operators }, { "..", Type::Operators },
154 158
155 { "=", Type::Assignments },
156
157 { "(", Type::LeftBrackets },
158 { "{", Type::LeftBrackets },
159 { "[", Type::LeftBrackets },
160
161 { ")", Type::RightBrackets },
162 { "}", Type::RightBrackets },
163 { "]", Type::RightBrackets },
164
165 159 { ",", Type::Other }, { ",", Type::Other },
166 160 { ":", Type::Other }, { ":", Type::Other },
167 161 { "::", Type::Other }, { "::", Type::Other },
168 162 { ";", Type::Other }, { ";", Type::Other },
169 163 { ".", Type::Other }, { ".", Type::Other },
170 { "spread", Type::Other },
164 { "vararg_expression", Type::Other },
171 165 }; };
166
172 167 } }
173 168
174 169 Type Type
 
... ... TsLuaLanguage::canBeFlattened(const Node */*parent*/, const Node *child,
206 201 case 2: case 2:
207 202 return false; return false;
208 203 default: default:
209 return -child->stype != TSLuaSType::FunctionCall
210 && -child->stype != TSLuaSType::VariableDecl
204 return -child->stype != TSLuaSType::Call
205 && -child->stype != TSLuaSType::LocalVariableDeclaration
211 206 && -child->stype != TSLuaSType::Parameter; && -child->stype != TSLuaSType::Parameter;
212 207 } }
213 208 } }
 
... ... TsLuaLanguage::shouldSplice(SType parent, const Node *childNode) const
253 248 { {
254 249 TSLuaSType child = -childNode->stype; TSLuaSType child = -childNode->stype;
255 250
256 // Splice all but first BinaryOperation node of a nesting chain.
257 if (-parent == TSLuaSType::BinaryOperation &&
258 child == TSLuaSType::BinaryOperation) {
251 // Splice all but first BinaryExpression node of a nesting chain.
252 if (-parent == TSLuaSType::BinaryExpression &&
253 child == TSLuaSType::BinaryExpression) {
259 254 bool oneLevel = true; bool oneLevel = true;
260 255 const Node *n = (childNode->next && !childNode->next->last) const Node *n = (childNode->next && !childNode->next->last)
261 256 ? childNode->next ? childNode->next
262 257 : childNode; : childNode;
263 258 for (const Node *node : n->children) { for (const Node *node : n->children) {
264 if (-node->stype == TSLuaSType::BinaryOperation) {
259 if (-node->stype == TSLuaSType::BinaryExpression) {
265 260 oneLevel = false; oneLevel = false;
266 261 break; break;
267 262 } }
 
... ... TsLuaLanguage::shouldSplice(SType parent, const Node *childNode) const
271 266 } }
272 267 } }
273 268
274 if (child == TSLuaSType::Parameters ||
275 child == TSLuaSType::Arguments) {
269 if (child == TSLuaSType::ParameterList) {
276 270 return true; return true;
277 271 } }
278 272 return false; return false;
 
... ... TsLuaLanguage::shouldSplice(SType parent, const Node *childNode) const
281 275 bool bool
282 276 TsLuaLanguage::isValueNode(SType stype) const TsLuaLanguage::isValueNode(SType stype) const
283 277 { {
284 return -stype == TSLuaSType::ConditionExpression
285 || -stype == TSLuaSType::LoopExpression;
278 return -stype == TSLuaSType::ConditionExpression;
286 279 } }
287 280
288 281 bool bool
289 282 TsLuaLanguage::isLayerBreak(SType /*parent*/, SType stype) const TsLuaLanguage::isLayerBreak(SType /*parent*/, SType stype) const
290 283 { {
291 return -stype == TSLuaSType::FunctionCall
292 || -stype == TSLuaSType::Function
293 || -stype == TSLuaSType::VariableDecl
284 return -stype == TSLuaSType::Call
285 || -stype == TSLuaSType::LocalFunctionDefinitionStatement
286 || -stype == TSLuaSType::LocalVariableDeclaration
287 || -stype == TSLuaSType::FunctionDefinition
288 || -stype == TSLuaSType::FunctionDefinitionStatement
294 289 || -stype == TSLuaSType::Field || -stype == TSLuaSType::Field
295 290 || -stype == TSLuaSType::Parameter || -stype == TSLuaSType::Parameter
296 291 || -stype == TSLuaSType::ReturnStatement || -stype == TSLuaSType::ReturnStatement
297 || -stype == TSLuaSType::UnaryOperation
298 || -stype == TSLuaSType::BinaryOperation
292 || -stype == TSLuaSType::UnaryExpression
293 || -stype == TSLuaSType::BinaryExpression
299 294 || isValueNode(stype); || isValueNode(stype);
300 295 } }
301 296
 
... ... MType
311 306 TsLuaLanguage::classify(SType stype) const TsLuaLanguage::classify(SType stype) const
312 307 { {
313 308 switch (-stype) { switch (-stype) {
314 case TSLuaSType::VariableDecl:
309 case TSLuaSType::LocalVariableDeclaration:
315 310 return MType::Declaration; return MType::Declaration;
316 311
317 312 case TSLuaSType::IfStatement: case TSLuaSType::IfStatement:
318 case TSLuaSType::ElseIfStatement:
319 case TSLuaSType::ElseStatement:
313 case TSLuaSType::ElseifClause:
314 case TSLuaSType::ElseClause:
315 case TSLuaSType::CallStatement:
320 316 case TSLuaSType::RepeatStatement: case TSLuaSType::RepeatStatement:
321 317 case TSLuaSType::WhileStatement: case TSLuaSType::WhileStatement:
322 case TSLuaSType::ForInStatement:
323 case TSLuaSType::ForStatement:
318 case TSLuaSType::EmptyStatement:
324 319 case TSLuaSType::GotoStatement: case TSLuaSType::GotoStatement:
325 320 case TSLuaSType::LabelStatement: case TSLuaSType::LabelStatement:
326 321 case TSLuaSType::ReturnStatement: case TSLuaSType::ReturnStatement:
327 case TSLuaSType::CallStatement:
328 case TSLuaSType::DeclStatement:
322 case TSLuaSType::ForGenericStatement:
323 case TSLuaSType::ForNumericStatement:
324 case TSLuaSType::VariableAssignment:
329 325 return MType::Statement; return MType::Statement;
330 326
331 case TSLuaSType::Function:
327 case TSLuaSType::FunctionDefinition:
332 328 return MType::Function; return MType::Function;
333 329
334 case TSLuaSType::FunctionCall:
330 case TSLuaSType::Call:
335 331 return MType::Call; return MType::Call;
336 332
337 333 case TSLuaSType::Parameter: case TSLuaSType::Parameter:
 
... ... TsLuaLanguage::classify(SType stype) const
352 348 const char * const char *
353 349 TsLuaLanguage::toString(SType stype) const TsLuaLanguage::toString(SType stype) const
354 350 { {
355 switch (-stype) {
356 case TSLuaSType::None: return "TSLuaSType::None";
357
358 case TSLuaSType::Separator: return "TSLuaSType::Separator";
359 case TSLuaSType::Comment: return "TSLuaSType::Comment";
360
361 case TSLuaSType::Program: return "TSLuaSType::Program";
362
363 case TSLuaSType::Function: return "TSLuaSType::Function";
364 case TSLuaSType::FunctionName: return "TSLuaSType::FunctionName";
365 case TSLuaSType::FunctionBody: return "TSLuaSType::FunctionBody";
366 case TSLuaSType::Parameters: return "TSLuaSType::Parameters";
367 case TSLuaSType::Parameter: return "TSLuaSType::Parameter";
368
369 case TSLuaSType::FunctionCall: return "TSLuaSType::FunctionCall";
370 case TSLuaSType::Arguments: return "TSLuaSType::Arguments";
371
372 case TSLuaSType::VariableDecl: return "TSLuaSType::VariableDecl";
373 case TSLuaSType::VariableDeclarator:
374 return "TSLuaSType::VariableDeclarator";
375
376 case TSLuaSType::UnaryOperation:
377 return "TSLuaSType::UnaryOperation";
378 case TSLuaSType::BinaryOperation:
379 return "TSLuaSType::BinaryOperation";
380
381 case TSLuaSType::Expression: return "TSLuaSType::Expression";
382 case TSLuaSType::ConditionExpression:
383 return "TSLuaSType::ConditionExpression";
384 case TSLuaSType::LoopExpression:
385 return "TSLuaSType::LoopExpression";
386 case TSLuaSType::FieldExpression:
387 return "TSLuaSType::FieldExpression";
388
389 case TSLuaSType::IfStatement: return "TSLuaSType::IfStatement";
390 case TSLuaSType::ElseIfStatement:
391 return "TSLuaSType::ElseIfStatement";
392 case TSLuaSType::ElseStatement:
393 return "TSLuaSType::ElseStatement";
394
395 case TSLuaSType::DoStatement: return "TSLuaSType::DoStatement";
396 case TSLuaSType::RepeatStatement:
397 return "TSLuaSType::RepeatStatement";
398 case TSLuaSType::WhileStatement:
399 return "TSLuaSType::WhileStatement";
400 case TSLuaSType::ForInStatement:
401 return "TSLuaSType::ForInStatement";
402 case TSLuaSType::ForStatement: return "TSLuaSType::ForStatement";
403
404 case TSLuaSType::GotoStatement:
405 return "TSLuaSType::GotoStatement";
406 case TSLuaSType::LabelStatement:
407 return "TSLuaSType::LabelStatement";
408 case TSLuaSType::ReturnStatement:
409 return "TSLuaSType::ReturnStatement";
410 case TSLuaSType::CallStatement:
411 return "TSLuaSType::CallStatement";
412 case TSLuaSType::DeclStatement:
413 return "TSLuaSType::DeclStatement";
414
415 case TSLuaSType::Table: return "TSLuaSType::Table";
416 case TSLuaSType::Field: return "TSLuaSType::Field";
417 case TSLuaSType::QuotedField: return "TSLuaSType::QuotedField";
351 #define CASE(item) case TSLuaSType::item: return "TSLuaSType::" #item
418 352
419 case TSLuaSType::GlobalVariable:
420 return "TSLuaSType::GlobalVariable";
421
422 case TSLuaSType::UnaryOperator:
423 return "TSLuaSType::UnaryOperator";
424 case TSLuaSType::BinaryOperator:
425 return "TSLuaSType::BinaryOperator";
353 switch (-stype) {
354 CASE(None);
355
356 CASE(Separator);
357 CASE(Comment);
358
359 CASE(Program);
360
361 CASE(Expression);
362 CASE(PrefixExpression);
363 CASE(Statement);
364 CASE(ArgumentList);
365 CASE(Attribute);
366 CASE(BinaryExpression);
367 CASE(ConditionExpression);
368 CASE(Block);
369 CASE(Call);
370 CASE(DoStatement);
371 CASE(ElseClause);
372 CASE(ElseifClause);
373 CASE(EmptyStatement);
374 CASE(ExpressionList);
375 CASE(Field);
376 CASE(FieldList);
377 CASE(ForGenericStatement);
378 CASE(ForNumericStatement);
379 CASE(FunctionBody);
380 CASE(FunctionDefinition);
381 CASE(FunctionDefinitionStatement);
382 CASE(GotoStatement);
383 CASE(IfStatement);
384 CASE(LabelStatement);
385 CASE(LocalFunctionDefinitionStatement);
386 CASE(LocalVariableDeclaration);
387 CASE(Parameter);
388 CASE(ParameterList);
389 CASE(ParenthesizedExpression);
390 CASE(CallStatement);
391 CASE(RepeatStatement);
392 CASE(ReturnStatement);
393 CASE(Table);
394 CASE(UnaryExpression);
395 CASE(Variable);
396 CASE(VariableAssignment);
397 CASE(VariableList);
398 CASE(WhileStatement);
399 CASE(UnaryOperator);
400 CASE(BinaryOperator);
426 401 } }
427 402
428 403 assert(false && "Unhandled enumeration item"); assert(false && "Unhandled enumeration item");
429 404 return "<UNKNOWN>"; return "<UNKNOWN>";
405
406 #undef CASE
430 407 } }
File src/ts/lua/TSLuaSType.hpp changed (mode: 100644) (index bc30069..db7223e)
... ... enum class TSLuaSType : std::uint8_t
34 34
35 35 Program, Program,
36 36
37 Function,
38 FunctionName,
39 FunctionBody,
40 Parameters,
41 Parameter,
42
43 FunctionCall,
44 Arguments,
45
46 VariableDecl,
47 VariableDeclarator,
48
49 UnaryOperation,
50 BinaryOperation,
51
52 Expression,
37 BinaryExpression,
53 38 ConditionExpression, ConditionExpression,
54 LoopExpression,
55 FieldExpression,
39 Expression,
40 ParenthesizedExpression,
41 PrefixExpression,
42 UnaryExpression,
56 43
57 IfStatement,
58 ElseIfStatement,
59 ElseStatement,
44 Table,
45 ExpressionList,
60 46
47 Statement,
48 CallStatement,
61 49 DoStatement, DoStatement,
62 RepeatStatement,
63 WhileStatement,
64 ForInStatement,
65 ForStatement,
66
50 EmptyStatement,
51 ForGenericStatement,
52 ForNumericStatement,
53 FunctionDefinitionStatement,
67 54 GotoStatement, GotoStatement,
68 55 LabelStatement, LabelStatement,
56 LocalFunctionDefinitionStatement,
57 RepeatStatement,
69 58 ReturnStatement, ReturnStatement,
70 CallStatement,
71 DeclStatement,
59 WhileStatement,
72 60
73 Table,
74 Field,
75 QuotedField,
61 IfStatement,
62 ElseClause,
63 ElseifClause,
64
65 FunctionBody,
66 FunctionDefinition,
76 67
77 GlobalVariable,
68 LocalVariableDeclaration,
69 Variable,
70 VariableAssignment,
71 VariableList,
72
73 Parameter,
74 ParameterList,
75
76 ArgumentList,
77 Attribute,
78 Block,
79 Call,
80 Field,
81 FieldList,
78 82
79 UnaryOperator,
80 83 BinaryOperator, BinaryOperator,
84 UnaryOperator,
81 85 }; };
82 86
83 87 // "Conversion operator": TSLuaSType -> SType. // "Conversion operator": TSLuaSType -> SType.
File tests/tooling/Matcher.cpp changed (mode: 100644) (index ec2c22e..2b8e66d)
... ... TEST_CASE("Declaration matcher works", "[tooling][matcher][.srcml]")
215 215 CHECK(nMatches == 4); CHECK(nMatches == 4);
216 216 } }
217 217 SECTION("In Lua") { SECTION("In Lua") {
218 Tree tree = parseLua("a1 = 1; a2 = 2; a3 = 3; a4 = 4");
218 Tree tree = parseLua("local a1; local a2; local a3; local a4");
219 219 CHECK(matcher.match(tree.getRoot(), *tree.getLanguage(), matchHandler)); CHECK(matcher.match(tree.getRoot(), *tree.getLanguage(), matchHandler));
220 220 CHECK(nMatches == 4); CHECK(nMatches == 4);
221 221 } }
File tests/ts/lua/ts-lua-diffing.cpp changed (mode: 100644) (index 927e6d0..cea8988)
... ... TEST_CASE("Variable is moved to table value", "[ts-lua][comparison]")
61 61 end end
62 62 )"); )");
63 63 } }
64
65 TEST_CASE("Complex update picks correct statement", "[ts-lua][comparison]")
66 {
67 diffTsLua(R"(
68 local name = prefix --- Deletions
69 if name == nil then --- Mixed
70 name = vifm.fnamemodify(current, ':t:r:r') --- Mixed
71 end
72 )", R"(
73 local outname = vifm.fnamemodify(current, ':t:r') --- Additions
74 if ext == 'tar' then --- Mixed
75 outname = vifm.fnamemodify(outname, ':r') --- Mixed
76 end
77 )");
78 }
File third-party/tree-sitter/parsers/README.md changed (mode: 100644) (index 78cbbc3..9e94a33)
1 Third-party grammars are amended to be more suitable for zograscope and
2 regenerated. This avoids rewriting tree after obtaining it from tree-sitter.
3 Below is information about what served as base versions for each imported
4 grammar.
5
1 6 `bash-*` files `bash-*` files
2 7 ============== ==============
3 8
4 Lua parser is generated from a grammar at
9 Bash parser is generated from a grammar at
5 10
6 11 https://github.com/tree-sitter/tree-sitter-bash https://github.com/tree-sitter/tree-sitter-bash
7 12
13 * commit: 4094e3a
14 * date: 2021-11-02
15
8 16 `lua-*` files `lua-*` files
9 17 ============= =============
10 18
11 19 Lua parser is generated from a grammar based on Lua parser is generated from a grammar based on
12 20
13 21 https://github.com/Azganoth/tree-sitter-lua https://github.com/Azganoth/tree-sitter-lua
22
23 * commit: 6b02dfd
24 * date: 2022-08-14
25 * tag: v2.1.3
The diff for file third-party/tree-sitter/parsers/lua-parser.c is too big (50141 changes) and cannot be shown.
File third-party/tree-sitter/parsers/lua-scanner.c added (mode: 100644) (index 0000000..6f7b50d)
1 #include <tree_sitter/parser.h>
2 #include <wctype.h>
3
4 enum TokenType
5 {
6 COMMENT_START,
7 COMMENT_CONTENT,
8 COMMENT_END,
9 STRING_START,
10 STRING_CONTENT,
11 STRING_END,
12 };
13
14 static void consume(TSLexer *lexer)
15 {
16 lexer->advance(lexer, false);
17 }
18 static void skip(TSLexer *lexer)
19 {
20 lexer->advance(lexer, true);
21 }
22 static bool consume_if(TSLexer *lexer, const int32_t character)
23 {
24 if (lexer->lookahead == character)
25 {
26 consume(lexer);
27 return true;
28 }
29
30 return false;
31 }
32
33 const char SQ_STRING_DELIMITER = '\'';
34 const char DQ_STRING_DELIMITER = '"';
35
36 enum StartedToken
37 {
38 SHORT_COMMENT = 1,
39 SHORT_SQ_STRING,
40 SHORT_DQ_STRING,
41 LONG_COMMENT,
42 LONG_STRING,
43 };
44
45 struct ScannerState
46 {
47 enum StartedToken started;
48 unsigned int depth;
49 };
50
51 void *tree_sitter_lua_external_scanner_create()
52 {
53 return calloc(1, sizeof(struct ScannerState));
54 }
55
56 void tree_sitter_lua_external_scanner_destroy(void *payload)
57 {
58 free(payload);
59 }
60
61 unsigned int tree_sitter_lua_external_scanner_serialize(void *payload, char *buffer)
62 {
63 struct ScannerState *state = payload;
64 buffer[0] = state->started;
65 buffer[1] = state->depth;
66 return 2;
67 }
68
69 void tree_sitter_lua_external_scanner_deserialize(void *payload, const char *buffer, unsigned int length)
70 {
71 if (length == 2)
72 {
73 struct ScannerState *state = payload;
74 state->started = buffer[0];
75 state->depth = buffer[1];
76 }
77 }
78
79 static unsigned int get_depth(TSLexer *lexer)
80 {
81 unsigned int current_depth = 0;
82 while (consume_if(lexer, '='))
83 {
84 current_depth += 1;
85 }
86
87 return current_depth;
88 }
89
90 static bool scan_depth(TSLexer *lexer, unsigned int remaining_depth)
91 {
92 while (remaining_depth > 0 && consume_if(lexer, '='))
93 {
94 remaining_depth -= 1;
95 }
96
97 return remaining_depth == 0;
98 }
99
100 bool tree_sitter_lua_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols)
101 {
102 struct ScannerState *state = payload;
103 switch (state->started)
104 {
105 case SHORT_COMMENT:
106 {
107 // try to match the short comment's end (new line or eof)
108 if (lexer->lookahead == '\n' || lexer->eof(lexer))
109 {
110 if (valid_symbols[COMMENT_END])
111 {
112 state->started = 0;
113
114 lexer->result_symbol = COMMENT_END;
115 return true;
116 }
117 }
118 else if (valid_symbols[COMMENT_CONTENT])
119 {
120 // consume all characters till a short comment's end
121 do
122 {
123 consume(lexer);
124 } while (lexer->lookahead != '\n' && !lexer->eof(lexer));
125
126 lexer->result_symbol = COMMENT_CONTENT;
127 return true;
128 }
129
130 break;
131 }
132 case SHORT_SQ_STRING:
133 case SHORT_DQ_STRING:
134 {
135 // define the short string's delimiter
136 const char delimiter = state->started == SHORT_SQ_STRING ? SQ_STRING_DELIMITER : DQ_STRING_DELIMITER;
137
138 // try to match the short string's end (" or ')
139 if (consume_if(lexer, delimiter))
140 {
141 if (valid_symbols[STRING_END])
142 {
143 state->started = 0;
144
145 lexer->result_symbol = STRING_END;
146 return true;
147 }
148 }
149 else if (valid_symbols[STRING_CONTENT] && lexer->lookahead != '\n' && !lexer->eof(lexer))
150 {
151 // consume any character till a short string's end, new line or eof
152 do
153 {
154 // consume any character after a backslash, unless it's a new line or eof
155 if (consume_if(lexer, '\\') && (lexer->lookahead == '\n' || lexer->eof(lexer)))
156 {
157 break;
158 }
159
160 consume(lexer);
161 } while (lexer->lookahead != delimiter && lexer->lookahead != '\n' && !lexer->eof(lexer));
162
163 lexer->result_symbol = STRING_CONTENT;
164 return true;
165 }
166
167 break;
168 }
169 case LONG_COMMENT:
170 case LONG_STRING:
171 {
172 const bool is_inside_a_comment = state->started == LONG_COMMENT;
173
174 bool some_characters_were_consumed = false;
175 if (is_inside_a_comment ? valid_symbols[COMMENT_END] : valid_symbols[STRING_END])
176 {
177 // try to match the long comment's/string's end (]=*])
178 if (consume_if(lexer, ']'))
179 {
180 if (scan_depth(lexer, state->depth) && consume_if(lexer, ']'))
181 {
182 state->started = 0;
183 state->depth = 0;
184
185 lexer->result_symbol = is_inside_a_comment ? COMMENT_END : STRING_END;
186 return true;
187 }
188
189 some_characters_were_consumed = true;
190 }
191 }
192
193 if (is_inside_a_comment ? valid_symbols[COMMENT_CONTENT] : valid_symbols[STRING_CONTENT])
194 {
195 if (!some_characters_were_consumed)
196 {
197 if (lexer->eof(lexer))
198 {
199 break;
200 }
201
202 // consume the next character as it can't start a long comment's/string's end ([)
203 consume(lexer);
204 }
205
206 // consume any character till a long comment's/string's end or eof
207 while (true)
208 {
209 lexer->mark_end(lexer);
210 if (consume_if(lexer, ']'))
211 {
212 if (scan_depth(lexer, state->depth))
213 {
214 if (consume_if(lexer, ']'))
215 {
216 break;
217 }
218 }
219 else
220 {
221 continue;
222 }
223 }
224
225 if (lexer->eof(lexer))
226 {
227 break;
228 }
229
230 consume(lexer);
231 }
232
233 lexer->result_symbol = is_inside_a_comment ? COMMENT_CONTENT : STRING_CONTENT;
234 return true;
235 }
236
237 break;
238 }
239 default:
240 {
241 // ignore all whitespace
242 while (iswspace(lexer->lookahead))
243 {
244 skip(lexer);
245 }
246
247 if (valid_symbols[COMMENT_START])
248 {
249 // try to match a short comment's start (--)
250 if (consume_if(lexer, '-'))
251 {
252 if (consume_if(lexer, '-'))
253 {
254 state->started = SHORT_COMMENT;
255
256 // try to match a long comment's start (--[=*[)
257 lexer->mark_end(lexer);
258 if (consume_if(lexer, '['))
259 {
260 unsigned int possible_depth = get_depth(lexer);
261
262 if (consume_if(lexer, '['))
263 {
264 state->started = LONG_COMMENT;
265 state->depth = possible_depth;
266
267 lexer->mark_end(lexer);
268 }
269 }
270
271 lexer->result_symbol = COMMENT_START;
272 return true;
273 }
274
275 break;
276 }
277 }
278
279 if (valid_symbols[STRING_START])
280 {
281 // try to match a short single-quoted string's start (")
282 if (consume_if(lexer, SQ_STRING_DELIMITER))
283 {
284 state->started = SHORT_SQ_STRING;
285 }
286 // try to match a short double-quoted string's start (')
287 else if (consume_if(lexer, DQ_STRING_DELIMITER))
288 {
289 state->started = SHORT_DQ_STRING;
290 }
291 // try to match a long string's start ([=*[)
292 else if (consume_if(lexer, '['))
293 {
294 unsigned int possible_depth = get_depth(lexer);
295
296 if (consume_if(lexer, '['))
297 {
298 state->started = LONG_STRING;
299 state->depth = possible_depth;
300 }
301 }
302
303 if (state->started)
304 {
305 lexer->result_symbol = STRING_START;
306 return true;
307 }
308 }
309
310 break;
311 }
312 }
313
314 return false;
315 }
File third-party/tree-sitter/parsers/lua-scanner.cpp deleted (index 70af2b8..0000000)
1 #include <tree_sitter/parser.h>
2 #include <cwctype>
3
4 namespace {
5
6 using std::iswspace;
7
8 enum TokenType {
9 COMMENT,
10 STRING
11 };
12
13 struct Scanner {
14 static void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
15
16 static void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
17
18 static bool scan_sequence(TSLexer *lexer, const char *sequence) {
19 // Try to match all characters in the given 'sequence'
20 for (const char *c = sequence; *c; c++) {
21 if (lexer->lookahead == *c) {
22 // Consume the character in 'c'
23 advance(lexer);
24 } else {
25 return false;
26 }
27 }
28
29 return true;
30 }
31
32 static bool scan_multiline_content(TSLexer *lexer) {
33 // Initialize lua multiline content level count
34 int start_level = 0;
35 int end_level = 0;
36
37 if (lexer->lookahead == '[') {
38 // Consume first appearance of '['
39 advance(lexer);
40
41 if (lexer->lookahead == '[' || lexer->lookahead == '=') {
42 while (lexer->lookahead == '=') {
43 // Increment level count
44 ++start_level;
45
46 // Consume all '=' characters
47 advance(lexer);
48 }
49
50 if (lexer->lookahead == '[') {
51 // Consume last appearance of '['
52 advance(lexer);
53
54 // Loop while not end of file (eof)
55 while (lexer->lookahead != 0) {
56 // Gives the end level count the same as start level count
57 end_level = start_level;
58
59 if (lexer->lookahead == ']') {
60 // Consume first appearance of ']'
61 advance(lexer);
62
63 if (lexer->lookahead == ']' || lexer->lookahead == '=') {
64 while (lexer->lookahead == '=' && end_level > 0) {
65 // Decrement level count
66 --end_level;
67
68 // Consume all '=' characters
69 advance(lexer);
70 }
71
72 if (lexer->lookahead == ']' && end_level == 0) {
73 // Consume last appearance of ']'
74 advance(lexer);
75
76 return true;
77 }
78 }
79 }
80
81 if (lexer->lookahead != 0) {
82 // Consume all but end of file (eof)
83 advance(lexer);
84 }
85 }
86 }
87 }
88 }
89
90 return false;
91 }
92
93 bool scan(TSLexer *lexer, const bool *valid_symbols) {
94 if (valid_symbols[COMMENT] || valid_symbols[STRING]) {
95 while (iswspace(lexer->lookahead)) {
96 skip(lexer);
97 }
98
99 // Try to make a short literal string with single quote
100 if (lexer->lookahead == '\'') {
101 lexer->result_symbol = STRING;
102
103 // Consume first appearance of '\''
104 advance(lexer);
105
106 // Loop when isn't new line neither end of file (eof)
107 while (lexer->lookahead != '\n' && lexer->lookahead != 0) {
108 if (lexer->lookahead == '\\') {
109 // Consume '\\'
110 advance(lexer);
111
112 if (lexer->lookahead != '\n' && lexer->lookahead != 0) {
113 // Consume any character that isn't new line neither end of file (eof)
114 advance(lexer);
115 } else {
116 break;
117 }
118 } else {
119 if (lexer->lookahead == '\'') {
120 // Consume last appearance of '\''
121 advance(lexer);
122
123 return true;
124 } else {
125 if (lexer->lookahead != '\n' && lexer->lookahead != 0) {
126 // Consume any character that isn't new line neither end of file (eof)
127 advance(lexer);
128 } else {
129 break;
130 }
131 }
132 }
133 }
134 }
135
136 // Try to make a short literal string with double quote
137 else if (lexer->lookahead == '"') {
138 lexer->result_symbol = STRING;
139
140 // Consume first appearance of '"'
141 advance(lexer);
142
143 // Loop when next character isn't new line neither end of file (eof)
144 while (lexer->lookahead != '\n' && lexer->lookahead != 0) {
145 if (lexer->lookahead == '\\') {
146 // Consume '\\'
147 advance(lexer);
148
149 if (lexer->lookahead != '\n' && lexer->lookahead != 0) {
150 // Consume any character that isn't new line neither end of file (eof)
151 advance(lexer);
152 } else {
153 break;
154 }
155 } else {
156 if (lexer->lookahead == '"') {
157 // Consume last appearance of '"'
158 advance(lexer);
159
160 return true;
161 } else {
162 if (lexer->lookahead != '\n' && lexer->lookahead != 0) {
163 // Consume any character that isn't new line neither end of file (eof)
164 advance(lexer);
165 } else {
166 break;
167 }
168 }
169 }
170 }
171 }
172
173 // Try to make a comment
174 else if (scan_sequence(lexer, "--")) {
175 while (iswspace(lexer->lookahead) && lexer->lookahead != '\n' && lexer->lookahead != 0) {
176 advance(lexer);
177 }
178
179 lexer->result_symbol = COMMENT;
180
181 if (!scan_multiline_content(lexer)) {
182 while (lexer->lookahead != '\n' && lexer->lookahead != 0) {
183 // Consume any character that isn't new line neither end of file (eof)
184 advance(lexer);
185 }
186 }
187
188 return true;
189 }
190
191 // Try to make a long literal string with double bracket
192 else if (scan_multiline_content(lexer)) {
193 lexer->result_symbol = STRING;
194
195 return true;
196 }
197
198 return false;
199 }
200
201 return false;
202 }
203 };
204
205 }
206
207 extern "C" {
208
209 void *tree_sitter_lua_external_scanner_create() {
210 return new Scanner();
211 }
212
213 void tree_sitter_lua_external_scanner_destroy(void *payload) {
214 Scanner *scanner = static_cast<Scanner *>(payload);
215 delete scanner;
216 }
217
218 bool tree_sitter_lua_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) {
219 Scanner *scanner = static_cast<Scanner *>(payload);
220 return scanner->scan(lexer, valid_symbols);
221 }
222
223 unsigned tree_sitter_lua_external_scanner_serialize(void *payload, char *buffer) {
224 (void)payload, (void)buffer;
225 return 0;
226 }
227
228 void tree_sitter_lua_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
229 (void)payload, (void)buffer, (void)length;
230 }
231
232 }
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/zograscope

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/zograscope

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master