diff options
author | Sérgio Medeiros <sqmedeiros@gmail.com> | 2015-10-16 08:52:28 -0300 |
---|---|---|
committer | Sérgio Medeiros <sqmedeiros@gmail.com> | 2015-10-16 08:52:28 -0300 |
commit | 859005d9f0ba728e7f1e9db99fd7b234fc7f3300 (patch) | |
tree | c087edbb70f48c5084d633ef09f90e6ee1b9de36 | |
parent | 4667c095a3adcf76d8fec82af287dcd812457f22 (diff) | |
parent | 53d28a6ff2ffcd6e3779b0f0bf92b6ae39d924fe (diff) | |
download | lpeglabel-859005d9f0ba728e7f1e9db99fd7b234fc7f3300.tar.gz lpeglabel-859005d9f0ba728e7f1e9db99fd7b234fc7f3300.tar.bz2 lpeglabel-859005d9f0ba728e7f1e9db99fd7b234fc7f3300.zip |
Merge pull request #4 from andremm/typedlua
Adding Typed Lua parser to examples
-rwxr-xr-x | examples/typedlua/test.lua | 2569 | ||||
-rw-r--r-- | examples/typedlua/tlerror.lua | 66 | ||||
-rw-r--r-- | examples/typedlua/tllexer.lua | 106 | ||||
-rw-r--r-- | examples/typedlua/tlp.lua | 20 | ||||
-rw-r--r-- | examples/typedlua/tlparser.lua | 245 |
5 files changed, 3006 insertions, 0 deletions
diff --git a/examples/typedlua/test.lua b/examples/typedlua/test.lua new file mode 100755 index 0000000..ed4e7a1 --- /dev/null +++ b/examples/typedlua/test.lua | |||
@@ -0,0 +1,2569 @@ | |||
1 | #!/usr/bin/env lua | ||
2 | |||
3 | local tlparser = require "tlparser" | ||
4 | |||
5 | -- expected result, result, message, subject | ||
6 | local e, r, m, s | ||
7 | |||
8 | local filename = "test.lua" | ||
9 | |||
10 | local function parse (s) | ||
11 | local r, m = tlparser.parse(s,filename,false,false) | ||
12 | if not r then m = m .. "\n" end | ||
13 | return r, m | ||
14 | end | ||
15 | |||
16 | print("> testing lexer...") | ||
17 | |||
18 | -- syntax ok | ||
19 | |||
20 | -- empty files | ||
21 | |||
22 | s = [=[ | ||
23 | ]=] | ||
24 | --[=[ | ||
25 | { } | ||
26 | ]=] | ||
27 | |||
28 | r, m = parse(s) | ||
29 | assert(r == true) | ||
30 | |||
31 | s = [=[ | ||
32 | -- testing empty file | ||
33 | ]=] | ||
34 | --[=[ | ||
35 | { } | ||
36 | ]=] | ||
37 | |||
38 | r, m = parse(s) | ||
39 | assert(r == true) | ||
40 | |||
41 | -- expressions | ||
42 | |||
43 | s = [=[ | ||
44 | local _nil,_false,_true,_dots = nil,false,true,... | ||
45 | ]=] | ||
46 | --[=[ | ||
47 | { `Local{ { `Id "_nil", `Id "_false", `Id "_true", `Id "_dots" }, { `Nil, `False, `True, `Dots } } } | ||
48 | ]=] | ||
49 | |||
50 | r, m = parse(s) | ||
51 | assert(r == true) | ||
52 | |||
53 | -- floating points | ||
54 | |||
55 | s = [=[ | ||
56 | local f1 = 1. | ||
57 | local f2 = 1.1 | ||
58 | ]=] | ||
59 | --[=[ | ||
60 | { `Local{ { `Id "f1" }, { `Number "1.0" } }, `Local{ { `Id "f2" }, { `Number "1.1" } } } | ||
61 | ]=] | ||
62 | |||
63 | r, m = parse(s) | ||
64 | assert(r == true) | ||
65 | |||
66 | s = [=[ | ||
67 | local f1 = 1.e-1 | ||
68 | local f2 = 1.e1 | ||
69 | ]=] | ||
70 | --[=[ | ||
71 | { `Local{ { `Id "f1" }, { `Number "0.1" } }, `Local{ { `Id "f2" }, { `Number "10.0" } } } | ||
72 | ]=] | ||
73 | |||
74 | r, m = parse(s) | ||
75 | assert(r == true) | ||
76 | |||
77 | s = [=[ | ||
78 | local f1 = 1.1e+1 | ||
79 | local f2 = 1.1e1 | ||
80 | ]=] | ||
81 | --[=[ | ||
82 | { `Local{ { `Id "f1" }, { `Number "11.0" } }, `Local{ { `Id "f2" }, { `Number "11.0" } } } | ||
83 | ]=] | ||
84 | |||
85 | r, m = parse(s) | ||
86 | assert(r == true) | ||
87 | |||
88 | s = [=[ | ||
89 | local f1 = .1 | ||
90 | local f2 = .1e1 | ||
91 | ]=] | ||
92 | --[=[ | ||
93 | { `Local{ { `Id "f1" }, { `Number "0.1" } }, `Local{ { `Id "f2" }, { `Number "1.0" } } } | ||
94 | ]=] | ||
95 | |||
96 | r, m = parse(s) | ||
97 | assert(r == true) | ||
98 | |||
99 | s = [=[ | ||
100 | local f1 = 1E1 | ||
101 | local f2 = 1e-1 | ||
102 | ]=] | ||
103 | --[=[ | ||
104 | { `Local{ { `Id "f1" }, { `Number "10.0" } }, `Local{ { `Id "f2" }, { `Number "0.1" } } } | ||
105 | ]=] | ||
106 | |||
107 | r, m = parse(s) | ||
108 | assert(r == true) | ||
109 | |||
110 | -- integers | ||
111 | |||
112 | s = [=[ | ||
113 | local i = 1 | ||
114 | local h = 0xff | ||
115 | ]=] | ||
116 | --[=[ | ||
117 | { `Local{ { `Id "i" }, { `Number "1" } }, `Local{ { `Id "h" }, { `Number "255" } } } | ||
118 | ]=] | ||
119 | |||
120 | r, m = parse(s) | ||
121 | assert(r == true) | ||
122 | |||
123 | s = [=[ | ||
124 | local h = 0x76c | ||
125 | local i = 4294967296 -- 2^32 | ||
126 | ]=] | ||
127 | --[=[ | ||
128 | { `Local{ { `Id "h" }, { `Number "1900" } }, `Local{ { `Id "i" }, { `Number "4294967296" } } } | ||
129 | ]=] | ||
130 | |||
131 | r, m = parse(s) | ||
132 | assert(r == true) | ||
133 | |||
134 | -- long comments | ||
135 | |||
136 | s = [=[ | ||
137 | --[======[ | ||
138 | testing | ||
139 | long | ||
140 | comment | ||
141 | [==[ one ]==] | ||
142 | [===[ more ]===] | ||
143 | [====[ time ]====] | ||
144 | bye | ||
145 | ]======] | ||
146 | ]=] | ||
147 | --[=[ | ||
148 | { } | ||
149 | ]=] | ||
150 | |||
151 | r, m = parse(s) | ||
152 | assert(r == true) | ||
153 | |||
154 | -- long strings | ||
155 | |||
156 | s = [=[ | ||
157 | --[[ | ||
158 | testing long string1 begin | ||
159 | ]] | ||
160 | |||
161 | local ls1 = | ||
162 | [[ | ||
163 | testing long string | ||
164 | ]] | ||
165 | |||
166 | --[[ | ||
167 | testing long string1 end | ||
168 | ]] | ||
169 | ]=] | ||
170 | --[=[ | ||
171 | { `Local{ { `Id "ls1" }, { `String "testing long string\n" } } } | ||
172 | ]=] | ||
173 | |||
174 | r, m = parse(s) | ||
175 | assert(r == true) | ||
176 | |||
177 | s = [=[ | ||
178 | --[==[ | ||
179 | testing long string2 begin | ||
180 | ]==] | ||
181 | |||
182 | local ls2 = [==[ testing \n [[ long ]] \t [===[ string ]===] | ||
183 | \a ]==] | ||
184 | |||
185 | --[==[ | ||
186 | [[ testing long string2 end ]] | ||
187 | ]==] | ||
188 | ]=] | ||
189 | --[=[ | ||
190 | { `Local{ { `Id "ls2" }, { `String " testing \\n [[ long ]] \\t [===[ string ]===]\n\\a " } } } | ||
191 | ]=] | ||
192 | |||
193 | r, m = parse(s) | ||
194 | assert(r == true) | ||
195 | |||
196 | -- short strings | ||
197 | |||
198 | s = [=[ | ||
199 | -- short string test begin | ||
200 | |||
201 | local ss1_a = "ola mundo\a" | ||
202 | local ss1_b = 'ola mundo\a' | ||
203 | |||
204 | -- short string test end | ||
205 | ]=] | ||
206 | --[=[ | ||
207 | { `Local{ { `Id "ss1_a" }, { `String "ola mundo\a" } }, `Local{ { `Id "ss1_b" }, { `String "ola mundo\a" } } } | ||
208 | ]=] | ||
209 | |||
210 | r, m = parse(s) | ||
211 | assert(r == true) | ||
212 | |||
213 | s = [=[ | ||
214 | -- short string test begin | ||
215 | |||
216 | local ss2_a = "testando,\tteste\n1\n2\n3 --> \"tchau\"" | ||
217 | local ss2_b = 'testando,\tteste\n1\n2\n3 --> \'tchau\'' | ||
218 | |||
219 | -- short string test end | ||
220 | ]=] | ||
221 | --[=[ | ||
222 | { `Local{ { `Id "ss2_a" }, { `String "testando,\tteste\n1\n2\n3 --> \"tchau\"" } }, `Local{ { `Id "ss2_b" }, { `String "testando,\tteste\n1\n2\n3 --> 'tchau'" } } } | ||
223 | ]=] | ||
224 | |||
225 | r, m = parse(s) | ||
226 | assert(r == true) | ||
227 | |||
228 | s = [=[ | ||
229 | -- short string test begin | ||
230 | |||
231 | local ss3_a = "ola \ | ||
232 | 'mundo'!" | ||
233 | |||
234 | local ss3_b = 'ola \ | ||
235 | "mundo"!' | ||
236 | |||
237 | -- short string test end | ||
238 | ]=] | ||
239 | --[=[ | ||
240 | { `Local{ { `Id "ss3_a" }, { `String "ola \n'mundo'!" } }, `Local{ { `Id "ss3_b" }, { `String "ola \n\"mundo\"!" } } } | ||
241 | ]=] | ||
242 | |||
243 | r, m = parse(s) | ||
244 | assert(r == true) | ||
245 | |||
246 | s = [=[ | ||
247 | -- short string test begin | ||
248 | |||
249 | local ss4_a = "C:\\Temp/" | ||
250 | |||
251 | local ss4_b = 'C:\\Temp/' | ||
252 | |||
253 | -- short string test end | ||
254 | ]=] | ||
255 | --[=[ | ||
256 | { `Local{ { `Id "ss4_a" }, { `String "C:\\Temp/" } }, `Local{ { `Id "ss4_b" }, { `String "C:\\Temp/" } } } | ||
257 | ]=] | ||
258 | |||
259 | r, m = parse(s) | ||
260 | assert(r == true) | ||
261 | |||
262 | s = [=[ | ||
263 | -- short string test begin | ||
264 | |||
265 | local ss5_a = "ola \ | ||
266 | mundo \\ \ | ||
267 | cruel" | ||
268 | |||
269 | local ss5_b = 'ola \ | ||
270 | mundo \\ \ | ||
271 | cruel' | ||
272 | |||
273 | -- short string test end | ||
274 | ]=] | ||
275 | --[=[ | ||
276 | { `Local{ { `Id "ss5_a" }, { `String "ola \nmundo \\ \ncruel" } }, `Local{ { `Id "ss5_b" }, { `String "ola \nmundo \\ \ncruel" } } } | ||
277 | ]=] | ||
278 | |||
279 | r, m = parse(s) | ||
280 | assert(r == true) | ||
281 | |||
282 | -- syntax error | ||
283 | |||
284 | -- floating points | ||
285 | |||
286 | s = [=[ | ||
287 | local f = 9e | ||
288 | ]=] | ||
289 | --[=[ | ||
290 | test.lua:2:1: syntax error, unexpected 'EOF', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
291 | ]=] | ||
292 | e = [=[ | ||
293 | test.lua:1:12: malformed <number> | ||
294 | ]=] | ||
295 | |||
296 | r, m = parse(s) | ||
297 | assert(m == e) | ||
298 | |||
299 | s = [=[ | ||
300 | local f = 5.e | ||
301 | ]=] | ||
302 | --[=[ | ||
303 | test.lua:2:1: syntax error, unexpected 'EOF', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
304 | ]=] | ||
305 | e = [=[ | ||
306 | test.lua:1:13: malformed <number> | ||
307 | ]=] | ||
308 | |||
309 | r, m = parse(s) | ||
310 | assert(m == e) | ||
311 | |||
312 | s = [=[ | ||
313 | local f = .9e- | ||
314 | ]=] | ||
315 | --[=[ | ||
316 | test.lua:1:14: syntax error, unexpected '-', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
317 | ]=] | ||
318 | e = [=[ | ||
319 | test.lua:1:14: malformed <number> | ||
320 | ]=] | ||
321 | |||
322 | r, m = parse(s) | ||
323 | assert(m == e) | ||
324 | |||
325 | s = [=[ | ||
326 | local f = 5.9e+ | ||
327 | ]=] | ||
328 | --[=[ | ||
329 | test.lua:1:15: syntax error, unexpected '+', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
330 | ]=] | ||
331 | e = [=[ | ||
332 | test.lua:1:15: malformed <number> | ||
333 | ]=] | ||
334 | |||
335 | r, m = parse(s) | ||
336 | assert(m == e) | ||
337 | |||
338 | -- integers | ||
339 | |||
340 | s = [=[ | ||
341 | -- invalid hexadecimal number | ||
342 | |||
343 | local hex = 0xG | ||
344 | ]=] | ||
345 | --[=[ | ||
346 | test.lua:4:1: syntax error, unexpected 'EOF', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
347 | ]=] | ||
348 | e = [=[ | ||
349 | test.lua:3:14: malformed <number> | ||
350 | ]=] | ||
351 | |||
352 | r, m = parse(s) | ||
353 | assert(m == e) | ||
354 | |||
355 | -- long strings | ||
356 | |||
357 | s = [=[ | ||
358 | --[==[ | ||
359 | testing long string3 begin | ||
360 | ]==] | ||
361 | |||
362 | local ls3 = [===[ | ||
363 | testing | ||
364 | unfinised | ||
365 | long string | ||
366 | ]==] | ||
367 | |||
368 | --[==[ | ||
369 | [[ testing long string3 end ]] | ||
370 | ]==] | ||
371 | ]=] | ||
372 | --[=[ | ||
373 | test.lua:5:13: syntax error, unexpected '[', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
374 | ]=] | ||
375 | e = [=[ | ||
376 | test.lua:14:1: unfinished long string | ||
377 | ]=] | ||
378 | |||
379 | r, m = parse(s) | ||
380 | assert(m == e) | ||
381 | |||
382 | -- short strings | ||
383 | |||
384 | s = [=[ | ||
385 | -- short string test begin | ||
386 | |||
387 | local ss6 = "testing unfinished string | ||
388 | |||
389 | -- short string test end | ||
390 | ]=] | ||
391 | --[=[ | ||
392 | test.lua:3:13: syntax error, unexpected '"', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
393 | ]=] | ||
394 | e = [=[ | ||
395 | test.lua:6:1: malformed <string> | ||
396 | ]=] | ||
397 | |||
398 | r, m = parse(s) | ||
399 | assert(m == e) | ||
400 | |||
401 | -- unfinished comments | ||
402 | |||
403 | s = [=[ | ||
404 | --[[ testing | ||
405 | unfinished | ||
406 | comment | ||
407 | ]=] | ||
408 | --[=[ | ||
409 | test.lua:3:1: syntax error, unexpected 'comment', expecting '=', ',', 'String', '{', '(', ':', '[', '.' | ||
410 | ]=] | ||
411 | e = [=[ | ||
412 | test.lua:1:1: unfinished long comment | ||
413 | ]=] | ||
414 | |||
415 | r, m = parse(s) | ||
416 | assert(m == e) | ||
417 | |||
418 | print("> testing parser...") | ||
419 | |||
420 | -- syntax ok | ||
421 | |||
422 | -- anonymous functions | ||
423 | |||
424 | s = [=[ | ||
425 | local a,b,c = function () end | ||
426 | ]=] | ||
427 | --[=[ | ||
428 | { `Local{ { `Id "a", `Id "b", `Id "c" }, { `Function{ { }, { } } } } } | ||
429 | ]=] | ||
430 | |||
431 | r, m = parse(s) | ||
432 | assert(r == true) | ||
433 | |||
434 | s = [=[ | ||
435 | local test = function ( a , b , ... ) end | ||
436 | ]=] | ||
437 | --[=[ | ||
438 | { `Local{ { `Id "test" }, { `Function{ { `Id "a", `Id "b", `Dots }, { } } } } } | ||
439 | ]=] | ||
440 | |||
441 | r, m = parse(s) | ||
442 | assert(r == true) | ||
443 | |||
444 | s = [=[ | ||
445 | local test = function (...) return ...,0 end | ||
446 | ]=] | ||
447 | --[=[ | ||
448 | { `Local{ { `Id "test" }, { `Function{ { `Dots }, { `Return{ `Dots, `Number "0" } } } } } } | ||
449 | ]=] | ||
450 | |||
451 | r, m = parse(s) | ||
452 | assert(r == true) | ||
453 | |||
454 | -- arithmetic expressions | ||
455 | |||
456 | s = [=[ | ||
457 | local arithmetic = 1 - 2 * 3 + 4 | ||
458 | ]=] | ||
459 | --[=[ | ||
460 | { `Local{ { `Id "arithmetic" }, { `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" } } } } | ||
461 | ]=] | ||
462 | |||
463 | r, m = parse(s) | ||
464 | assert(r == true) | ||
465 | |||
466 | s = [=[ | ||
467 | local pow = -3^-2^2 | ||
468 | ]=] | ||
469 | --[=[ | ||
470 | { `Local{ { `Id "pow" }, { `Op{ "unm", `Op{ "pow", `Number "3", `Op{ "unm", `Op{ "pow", `Number "2", `Number "2" } } } } } } } | ||
471 | ]=] | ||
472 | |||
473 | r, m = parse(s) | ||
474 | assert(r == true) | ||
475 | |||
476 | s = [=[ | ||
477 | q, r, f = 3//2, 3%2, 3/2 | ||
478 | ]=] | ||
479 | --[=[ | ||
480 | { `Set{ { `Index{ `Id "_ENV", `String "q" }, `Index{ `Id "_ENV", `String "r" }, `Index{ `Id "_ENV", `String "f" } }, { `Op{ "idiv", `Number "3", `Number "2" }, `Op{ "mod", `Number "3", `Number "2" }, `Op{ "div", `Number "3", `Number "2" } } } } | ||
481 | ]=] | ||
482 | |||
483 | r, m = parse(s) | ||
484 | assert(r == true) | ||
485 | |||
486 | -- assignments | ||
487 | |||
488 | s = [=[ | ||
489 | a = f()[1] | ||
490 | ]=] | ||
491 | --[=[ | ||
492 | { `Set{ { `Index{ `Id "_ENV", `String "a" } }, { `Index{ `Call{ `Index{ `Id "_ENV", `String "f" } }, `Number "1" } } } } | ||
493 | ]=] | ||
494 | |||
495 | r, m = parse(s) | ||
496 | assert(r == true) | ||
497 | |||
498 | s = [=[ | ||
499 | a()[1] = 1; | ||
500 | ]=] | ||
501 | --[=[ | ||
502 | { `Set{ { `Index{ `Call{ `Index{ `Id "_ENV", `String "a" } }, `Number "1" } }, { `Number "1" } } } | ||
503 | ]=] | ||
504 | |||
505 | r, m = parse(s) | ||
506 | assert(r == true) | ||
507 | |||
508 | s = [=[ | ||
509 | i = a.f(1) | ||
510 | ]=] | ||
511 | --[=[ | ||
512 | { `Set{ { `Index{ `Id "_ENV", `String "i" } }, { `Call{ `Index{ `Index{ `Id "_ENV", `String "a" }, `String "f" }, `Number "1" } } } } | ||
513 | ]=] | ||
514 | |||
515 | r, m = parse(s) | ||
516 | assert(r == true) | ||
517 | |||
518 | s = [=[ | ||
519 | i = a[f(1)] | ||
520 | ]=] | ||
521 | --[=[ | ||
522 | { `Set{ { `Index{ `Id "_ENV", `String "i" } }, { `Index{ `Index{ `Id "_ENV", `String "a" }, `Call{ `Index{ `Id "_ENV", `String "f" }, `Number "1" } } } } } | ||
523 | ]=] | ||
524 | |||
525 | r, m = parse(s) | ||
526 | assert(r == true) | ||
527 | |||
528 | s = [=[ | ||
529 | a[f()] = sub | ||
530 | i = i + 1 | ||
531 | ]=] | ||
532 | --[=[ | ||
533 | { `Set{ { `Index{ `Index{ `Id "_ENV", `String "a" }, `Call{ `Index{ `Id "_ENV", `String "f" } } } }, { `Index{ `Id "_ENV", `String "sub" } } }, `Set{ { `Index{ `Id "_ENV", `String "i" } }, { `Op{ "add", `Index{ `Id "_ENV", `String "i" }, `Number "1" } } } } | ||
534 | ]=] | ||
535 | |||
536 | r, m = parse(s) | ||
537 | assert(r == true) | ||
538 | |||
539 | s = [=[ | ||
540 | a:b(1)._ = some_value | ||
541 | ]=] | ||
542 | --[=[ | ||
543 | { `Set{ { `Index{ `Invoke{ `Index{ `Id "_ENV", `String "a" }, `String "b", `Number "1" }, `String "_" } }, { `Index{ `Id "_ENV", `String "some_value" } } } } | ||
544 | ]=] | ||
545 | |||
546 | r, m = parse(s) | ||
547 | assert(r == true) | ||
548 | |||
549 | -- bitwise expressions | ||
550 | |||
551 | s = [=[ | ||
552 | b = 1 & 0 | 1 ~ 1 | ||
553 | ]=] | ||
554 | --[=[ | ||
555 | { `Set{ { `Index{ `Id "_ENV", `String "b" } }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Number "1", `Number "1" } } } } } | ||
556 | ]=] | ||
557 | |||
558 | r, m = parse(s) | ||
559 | assert(r == true) | ||
560 | |||
561 | s = [=[ | ||
562 | b = 1 & 0 | 1 >> 1 ~ 1 | ||
563 | ]=] | ||
564 | --[=[ | ||
565 | { `Set{ { `Index{ `Id "_ENV", `String "b" } }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Op{ "shr", `Number "1", `Number "1" }, `Number "1" } } } } } | ||
566 | ]=] | ||
567 | |||
568 | r, m = parse(s) | ||
569 | assert(r == true) | ||
570 | |||
571 | -- break | ||
572 | |||
573 | s = [=[ | ||
574 | while 1 do | ||
575 | break | ||
576 | end | ||
577 | ]=] | ||
578 | --[=[ | ||
579 | { `While{ `Number "1", { `Break } } } | ||
580 | ]=] | ||
581 | |||
582 | r, m = parse(s) | ||
583 | assert(r == true) | ||
584 | |||
585 | s = [=[ | ||
586 | while 1 do | ||
587 | while 1 do | ||
588 | break | ||
589 | end | ||
590 | break | ||
591 | end | ||
592 | ]=] | ||
593 | --[=[ | ||
594 | { `While{ `Number "1", { `While{ `Number "1", { `Break } }, `Break } } } | ||
595 | ]=] | ||
596 | |||
597 | r, m = parse(s) | ||
598 | assert(r == true) | ||
599 | |||
600 | s = [=[ | ||
601 | repeat | ||
602 | if 2 > 1 then break end | ||
603 | until 1 | ||
604 | ]=] | ||
605 | --[=[ | ||
606 | { `Repeat{ { `If{ `Op{ "lt", `Number "1", `Number "2" }, { `Break } } }, `Number "1" } } | ||
607 | ]=] | ||
608 | |||
609 | r, m = parse(s) | ||
610 | assert(r == true) | ||
611 | |||
612 | s = [=[ | ||
613 | for i=1,10 do | ||
614 | do | ||
615 | break | ||
616 | break | ||
617 | return | ||
618 | end | ||
619 | end | ||
620 | ]=] | ||
621 | --[=[ | ||
622 | { `Fornum{ `Id "i", `Number "1", `Number "10", { `Do{ `Break, `Break, `Return } } } } | ||
623 | ]=] | ||
624 | |||
625 | r, m = parse(s) | ||
626 | assert(r == true) | ||
627 | |||
628 | -- block statements | ||
629 | |||
630 | s = [=[ | ||
631 | do | ||
632 | local var = 2+2; | ||
633 | return | ||
634 | end | ||
635 | ]=] | ||
636 | --[=[ | ||
637 | { `Do{ `Local{ { `Id "var" }, { `Op{ "add", `Number "2", `Number "2" } } }, `Return } } | ||
638 | ]=] | ||
639 | |||
640 | r, m = parse(s) | ||
641 | assert(r == true) | ||
642 | |||
643 | -- calls | ||
644 | |||
645 | s = [=[ | ||
646 | f() | ||
647 | t:m() | ||
648 | ]=] | ||
649 | --[=[ | ||
650 | { `Call{ `Index{ `Id "_ENV", `String "f" } }, `Invoke{ `Index{ `Id "_ENV", `String "t" }, `String "m" } } | ||
651 | ]=] | ||
652 | |||
653 | r, m = parse(s) | ||
654 | assert(r == true) | ||
655 | |||
656 | -- concatenation expressions | ||
657 | |||
658 | s = [=[ | ||
659 | local concat1 = 1 .. 2^3 | ||
660 | ]=] | ||
661 | --[=[ | ||
662 | { `Local{ { `Id "concat1" }, { `Op{ "concat", `Number "1", `Op{ "pow", `Number "2", `Number "3" } } } } } | ||
663 | ]=] | ||
664 | |||
665 | r, m = parse(s) | ||
666 | assert(r == true) | ||
667 | |||
668 | -- empty files | ||
669 | |||
670 | s = [=[ | ||
671 | ; | ||
672 | ]=] | ||
673 | --[=[ | ||
674 | { } | ||
675 | ]=] | ||
676 | |||
677 | r, m = parse(s) | ||
678 | assert(r == true) | ||
679 | |||
680 | -- for generic | ||
681 | |||
682 | s = [=[ | ||
683 | for k,v in pairs(t) do print (k,v) end | ||
684 | ]=] | ||
685 | --[=[ | ||
686 | { `Forin{ { `Id "k", `Id "v" }, { `Call{ `Index{ `Id "_ENV", `String "pairs" }, `Index{ `Id "_ENV", `String "t" } } }, { `Call{ `Index{ `Id "_ENV", `String "print" }, `Id "k", `Id "v" } } } } | ||
687 | ]=] | ||
688 | |||
689 | r, m = parse(s) | ||
690 | assert(r == true) | ||
691 | |||
692 | -- for numeric | ||
693 | |||
694 | s = [=[ | ||
695 | for i = 1 , 10 , 2 do end | ||
696 | ]=] | ||
697 | --[=[ | ||
698 | { `Fornum{ `Id "i", `Number "1", `Number "10", `Number "2", { } } } | ||
699 | ]=] | ||
700 | |||
701 | r, m = parse(s) | ||
702 | assert(r == true) | ||
703 | |||
704 | s = [=[ | ||
705 | for i=1,10 do end | ||
706 | ]=] | ||
707 | --[=[ | ||
708 | { `Fornum{ `Id "i", `Number "1", `Number "10", { } } } | ||
709 | ]=] | ||
710 | |||
711 | r, m = parse(s) | ||
712 | assert(r == true) | ||
713 | |||
714 | -- global functions | ||
715 | |||
716 | s = [=[ | ||
717 | function test(a , b , ...) end | ||
718 | ]=] | ||
719 | --[=[ | ||
720 | { `Set{ { `Index{ `Id "_ENV", `String "test" } }, { `Function{ { `Id "a", `Id "b", `Dots }, { } } } } } | ||
721 | ]=] | ||
722 | |||
723 | r, m = parse(s) | ||
724 | assert(r == true) | ||
725 | |||
726 | s = [=[ | ||
727 | function test (...) end | ||
728 | ]=] | ||
729 | --[=[ | ||
730 | { `Set{ { `Index{ `Id "_ENV", `String "test" } }, { `Function{ { `Dots }, { } } } } } | ||
731 | ]=] | ||
732 | |||
733 | r, m = parse(s) | ||
734 | assert(r == true) | ||
735 | |||
736 | s = [=[ | ||
737 | function t.a:b() end | ||
738 | ]=] | ||
739 | --[=[ | ||
740 | { `Set{ { `Index{ `Index{ `Index{ `Id "_ENV", `String "t" }, `String "a" }, `String "b" } }, { `Function{ { `Id "self" }, { } } } } } | ||
741 | ]=] | ||
742 | |||
743 | r, m = parse(s) | ||
744 | assert(r == true) | ||
745 | |||
746 | s = [=[ | ||
747 | function t.a() end | ||
748 | ]=] | ||
749 | --[=[ | ||
750 | { `Set{ { `Index{ `Index{ `Id "_ENV", `String "t" }, `String "a" } }, { `Function{ { }, { } } } } } | ||
751 | ]=] | ||
752 | |||
753 | r, m = parse(s) | ||
754 | assert(r == true) | ||
755 | |||
756 | s = [=[ | ||
757 | function testando . funcao . com : espcacos ( e, com , parametros, ... ) end | ||
758 | ]=] | ||
759 | --[=[ | ||
760 | { `Set{ { `Index{ `Index{ `Index{ `Index{ `Id "_ENV", `String "testando" }, `String "funcao" }, `String "com" }, `String "espcacos" } }, { `Function{ { `Id "self", `Id "e", `Id "com", `Id "parametros", `Dots }, { } } } } } | ||
761 | ]=] | ||
762 | |||
763 | r, m = parse(s) | ||
764 | assert(r == true) | ||
765 | |||
766 | -- goto | ||
767 | |||
768 | s = [=[ | ||
769 | goto label | ||
770 | :: label :: return | ||
771 | ]=] | ||
772 | --[=[ | ||
773 | { `Goto{ "label" }, `Label{ "label" }, `Return } | ||
774 | ]=] | ||
775 | |||
776 | r, m = parse(s) | ||
777 | assert(r == true) | ||
778 | |||
779 | s = [=[ | ||
780 | ::label:: | ||
781 | goto label | ||
782 | ]=] | ||
783 | --[=[ | ||
784 | { `Label{ "label" }, `Goto{ "label" } } | ||
785 | ]=] | ||
786 | |||
787 | r, m = parse(s) | ||
788 | assert(r == true) | ||
789 | |||
790 | s = [=[ | ||
791 | goto label | ||
792 | ::label:: | ||
793 | ]=] | ||
794 | --[=[ | ||
795 | { `Goto{ "label" }, `Label{ "label" } } | ||
796 | ]=] | ||
797 | |||
798 | r, m = parse(s) | ||
799 | assert(r == true) | ||
800 | |||
801 | s = [=[ | ||
802 | ::label:: | ||
803 | do ::label:: goto label end | ||
804 | ]=] | ||
805 | --[=[ | ||
806 | { `Label{ "label" }, `Do{ `Label{ "label" }, `Goto{ "label" } } } | ||
807 | ]=] | ||
808 | |||
809 | r, m = parse(s) | ||
810 | assert(r == true) | ||
811 | |||
812 | s = [=[ | ||
813 | ::label:: | ||
814 | do goto label ; ::label:: end | ||
815 | ]=] | ||
816 | --[=[ | ||
817 | { `Label{ "label" }, `Do{ `Goto{ "label" }, `Label{ "label" } } } | ||
818 | ]=] | ||
819 | |||
820 | r, m = parse(s) | ||
821 | assert(r == true) | ||
822 | |||
823 | s = [=[ | ||
824 | ::label:: | ||
825 | do goto label end | ||
826 | ]=] | ||
827 | --[=[ | ||
828 | { `Label{ "label" }, `Do{ `Goto{ "label" } } } | ||
829 | ]=] | ||
830 | |||
831 | r, m = parse(s) | ||
832 | assert(r == true) | ||
833 | |||
834 | s = [=[ | ||
835 | do goto label end | ||
836 | ::label:: | ||
837 | ]=] | ||
838 | --[=[ | ||
839 | { `Do{ `Goto{ "label" } }, `Label{ "label" } } | ||
840 | ]=] | ||
841 | |||
842 | r, m = parse(s) | ||
843 | assert(r == true) | ||
844 | |||
845 | s = [=[ | ||
846 | do do do do do goto label end end end end end | ||
847 | ::label:: | ||
848 | ]=] | ||
849 | --[=[ | ||
850 | { `Do{ `Do{ `Do{ `Do{ `Do{ `Goto{ "label" } } } } } }, `Label{ "label" } } | ||
851 | ]=] | ||
852 | |||
853 | r, m = parse(s) | ||
854 | assert(r == true) | ||
855 | |||
856 | -- if-else | ||
857 | |||
858 | s = [=[ | ||
859 | if a then end | ||
860 | ]=] | ||
861 | --[=[ | ||
862 | { `If{ `Index{ `Id "_ENV", `String "a" }, { } } } | ||
863 | ]=] | ||
864 | |||
865 | r, m = parse(s) | ||
866 | assert(r == true) | ||
867 | |||
868 | s = [=[ | ||
869 | if a then return a else return end | ||
870 | ]=] | ||
871 | --[=[ | ||
872 | { `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, { `Return } } } | ||
873 | ]=] | ||
874 | |||
875 | r, m = parse(s) | ||
876 | assert(r == true) | ||
877 | |||
878 | s = [=[ | ||
879 | if a then | ||
880 | return a | ||
881 | else | ||
882 | local c = d | ||
883 | d = d + 1 | ||
884 | return d | ||
885 | end | ||
886 | ]=] | ||
887 | --[=[ | ||
888 | { `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, { `Local{ { `Id "c" }, { `Index{ `Id "_ENV", `String "d" } } }, `Set{ { `Index{ `Id "_ENV", `String "d" } }, { `Op{ "add", `Index{ `Id "_ENV", `String "d" }, `Number "1" } } }, `Return{ `Index{ `Id "_ENV", `String "d" } } } } } | ||
889 | ]=] | ||
890 | |||
891 | r, m = parse(s) | ||
892 | assert(r == true) | ||
893 | |||
894 | s = [=[ | ||
895 | if a then | ||
896 | return a | ||
897 | elseif b then | ||
898 | return b | ||
899 | elseif c then | ||
900 | return c | ||
901 | end | ||
902 | ]=] | ||
903 | --[=[ | ||
904 | { `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, `Index{ `Id "_ENV", `String "b" }, { `Return{ `Index{ `Id "_ENV", `String "b" } } }, `Index{ `Id "_ENV", `String "c" }, { `Return{ `Index{ `Id "_ENV", `String "c" } } } } } | ||
905 | ]=] | ||
906 | |||
907 | r, m = parse(s) | ||
908 | assert(r == true) | ||
909 | |||
910 | s = [=[ | ||
911 | if a then return a | ||
912 | elseif b then return | ||
913 | else ; | ||
914 | end | ||
915 | ]=] | ||
916 | --[=[ | ||
917 | { `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, `Index{ `Id "_ENV", `String "b" }, { `Return }, { } } } | ||
918 | ]=] | ||
919 | |||
920 | r, m = parse(s) | ||
921 | assert(r == true) | ||
922 | |||
923 | s = [=[ | ||
924 | if a then | ||
925 | return | ||
926 | elseif c then | ||
927 | end | ||
928 | ]=] | ||
929 | --[=[ | ||
930 | { `If{ `Index{ `Id "_ENV", `String "a" }, { `Return }, `Index{ `Id "_ENV", `String "c" }, { } } } | ||
931 | ]=] | ||
932 | |||
933 | r, m = parse(s) | ||
934 | assert(r == true) | ||
935 | |||
936 | -- interfaces | ||
937 | |||
938 | s = [=[ | ||
939 | local interface Empty end | ||
940 | ]=] | ||
941 | --[=[ | ||
942 | { `Interface{ Empty, `TTable{ } } } | ||
943 | ]=] | ||
944 | |||
945 | r, m = parse(s) | ||
946 | assert(r == true) | ||
947 | |||
948 | s = [=[ | ||
949 | local interface X | ||
950 | x, y, z:number | ||
951 | end | ||
952 | ]=] | ||
953 | --[=[ | ||
954 | { `Interface{ X, `TTable{ `TLiteral x:`TBase number, `TLiteral y:`TBase number, `TLiteral z:`TBase number } } } | ||
955 | ]=] | ||
956 | |||
957 | r, m = parse(s) | ||
958 | assert(r == true) | ||
959 | |||
960 | s = [=[ | ||
961 | local interface Person | ||
962 | firstname:string | ||
963 | lastname:string | ||
964 | end | ||
965 | ]=] | ||
966 | --[=[ | ||
967 | { `Interface{ Person, `TTable{ `TLiteral firstname:`TBase string, `TLiteral lastname:`TBase string } } } | ||
968 | ]=] | ||
969 | |||
970 | r, m = parse(s) | ||
971 | assert(r == true) | ||
972 | |||
973 | s = [=[ | ||
974 | local interface Element | ||
975 | info:number | ||
976 | next:Element? | ||
977 | end | ||
978 | ]=] | ||
979 | --[=[ | ||
980 | { `Interface{ Element, `TRecursive{ Element, `TTable{ `TLiteral info:`TBase number, `TLiteral next:`TUnion{ `TVariable Element, `TNil } } } } } | ||
981 | ]=] | ||
982 | |||
983 | r, m = parse(s) | ||
984 | assert(r == true) | ||
985 | |||
986 | -- labels | ||
987 | |||
988 | s = [=[ | ||
989 | ::label:: | ||
990 | do ::label:: end | ||
991 | ::other_label:: | ||
992 | ]=] | ||
993 | --[=[ | ||
994 | { `Label{ "label" }, `Do{ `Label{ "label" } }, `Label{ "other_label" } } | ||
995 | ]=] | ||
996 | |||
997 | r, m = parse(s) | ||
998 | assert(r == true) | ||
999 | |||
1000 | -- locals | ||
1001 | |||
1002 | s = [=[ | ||
1003 | local a | ||
1004 | ]=] | ||
1005 | --[=[ | ||
1006 | { `Local{ { `Id "a" }, { } } } | ||
1007 | ]=] | ||
1008 | |||
1009 | r, m = parse(s) | ||
1010 | assert(r == true) | ||
1011 | |||
1012 | s = [=[ | ||
1013 | local a,b,c | ||
1014 | ]=] | ||
1015 | --[=[ | ||
1016 | { `Local{ { `Id "a", `Id "b", `Id "c" }, { } } } | ||
1017 | ]=] | ||
1018 | |||
1019 | r, m = parse(s) | ||
1020 | assert(r == true) | ||
1021 | |||
1022 | s = [=[ | ||
1023 | local a = 1 , 1 + 2, 5.1 | ||
1024 | ]=] | ||
1025 | --[=[ | ||
1026 | { `Local{ { `Id "a" }, { `Number "1", `Op{ "add", `Number "1", `Number "2" }, `Number "5.1" } } } | ||
1027 | ]=] | ||
1028 | |||
1029 | r, m = parse(s) | ||
1030 | assert(r == true) | ||
1031 | |||
1032 | s = [=[ | ||
1033 | local a,b,c = 1.9 | ||
1034 | ]=] | ||
1035 | --[=[ | ||
1036 | { `Local{ { `Id "a", `Id "b", `Id "c" }, { `Number "1.9" } } } | ||
1037 | ]=] | ||
1038 | |||
1039 | r, m = parse(s) | ||
1040 | assert(r == true) | ||
1041 | |||
1042 | s = [=[ | ||
1043 | local function test() end | ||
1044 | ]=] | ||
1045 | --[=[ | ||
1046 | { `Localrec{ { `Id "test" }, { `Function{ { }, { } } } } } | ||
1047 | ]=] | ||
1048 | |||
1049 | r, m = parse(s) | ||
1050 | assert(r == true) | ||
1051 | |||
1052 | s = [=[ | ||
1053 | local function test ( a , b , c , ... ) end | ||
1054 | ]=] | ||
1055 | --[=[ | ||
1056 | { `Localrec{ { `Id "test" }, { `Function{ { `Id "a", `Id "b", `Id "c", `Dots }, { } } } } } | ||
1057 | ]=] | ||
1058 | |||
1059 | r, m = parse(s) | ||
1060 | assert(r == true) | ||
1061 | |||
1062 | s = [=[ | ||
1063 | local function test(...) return ... end | ||
1064 | ]=] | ||
1065 | --[=[ | ||
1066 | { `Localrec{ { `Id "test" }, { `Function{ { `Dots }, { `Return{ `Dots } } } } } } | ||
1067 | ]=] | ||
1068 | |||
1069 | r, m = parse(s) | ||
1070 | assert(r == true) | ||
1071 | |||
1072 | -- relational expressions | ||
1073 | |||
1074 | s = [=[ | ||
1075 | local relational = 1 < 2 >= 3 == 4 ~= 5 < 6 <= 7 | ||
1076 | ]=] | ||
1077 | --[=[ | ||
1078 | { `Local{ { `Id "relational" }, { `Op{ "le", `Op{ "lt", `Op{ "not", `Op{ "eq", `Op{ "eq", `Op{ "le", `Number "3", `Op{ "lt", `Number "1", `Number "2" } }, `Number "4" }, `Number "5" } }, `Number "6" }, `Number "7" } } } } | ||
1079 | ]=] | ||
1080 | |||
1081 | r, m = parse(s) | ||
1082 | assert(r == true) | ||
1083 | |||
1084 | -- repeat | ||
1085 | |||
1086 | s = [=[ | ||
1087 | repeat | ||
1088 | local a,b,c = 1+1,2+2,3+3 | ||
1089 | break | ||
1090 | until a < 1 | ||
1091 | ]=] | ||
1092 | --[=[ | ||
1093 | { `Repeat{ { `Local{ { `Id "a", `Id "b", `Id "c" }, { `Op{ "add", `Number "1", `Number "1" }, `Op{ "add", `Number "2", `Number "2" }, `Op{ "add", `Number "3", `Number "3" } } }, `Break }, `Op{ "lt", `Index{ `Id "_ENV", `String "a" }, `Number "1" } } } | ||
1094 | ]=] | ||
1095 | |||
1096 | r, m = parse(s) | ||
1097 | assert(r == true) | ||
1098 | |||
1099 | -- return | ||
1100 | |||
1101 | s = [=[ | ||
1102 | return | ||
1103 | ]=] | ||
1104 | --[=[ | ||
1105 | { `Return } | ||
1106 | ]=] | ||
1107 | |||
1108 | r, m = parse(s) | ||
1109 | assert(r == true) | ||
1110 | |||
1111 | s = [=[ | ||
1112 | return 1 | ||
1113 | ]=] | ||
1114 | --[=[ | ||
1115 | { `Return{ `Number "1" } } | ||
1116 | ]=] | ||
1117 | |||
1118 | r, m = parse(s) | ||
1119 | assert(r == true) | ||
1120 | |||
1121 | s = [=[ | ||
1122 | return 1,1-2*3+4,"alo" | ||
1123 | ]=] | ||
1124 | --[=[ | ||
1125 | { `Return{ `Number "1", `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" }, `String "alo" } } | ||
1126 | ]=] | ||
1127 | |||
1128 | r, m = parse(s) | ||
1129 | assert(r == true) | ||
1130 | |||
1131 | s = [=[ | ||
1132 | return; | ||
1133 | ]=] | ||
1134 | --[=[ | ||
1135 | { `Return } | ||
1136 | ]=] | ||
1137 | |||
1138 | r, m = parse(s) | ||
1139 | assert(r == true) | ||
1140 | |||
1141 | s = [=[ | ||
1142 | return 1; | ||
1143 | ]=] | ||
1144 | --[=[ | ||
1145 | { `Return{ `Number "1" } } | ||
1146 | ]=] | ||
1147 | |||
1148 | r, m = parse(s) | ||
1149 | assert(r == true) | ||
1150 | |||
1151 | s = [=[ | ||
1152 | return 1,1-2*3+4,"alo"; | ||
1153 | ]=] | ||
1154 | --[=[ | ||
1155 | { `Return{ `Number "1", `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" }, `String "alo" } } | ||
1156 | ]=] | ||
1157 | |||
1158 | r, m = parse(s) | ||
1159 | assert(r == true) | ||
1160 | |||
1161 | -- tables | ||
1162 | |||
1163 | s = [=[ | ||
1164 | local t = { [1] = "alo", alo = 1, 2; } | ||
1165 | ]=] | ||
1166 | --[=[ | ||
1167 | { `Local{ { `Id "t" }, { `Table{ `Pair{ `Number "1", `String "alo" }, `Pair{ `String "alo", `Number "1" }, `Number "2" } } } } | ||
1168 | ]=] | ||
1169 | |||
1170 | r, m = parse(s) | ||
1171 | assert(r == true) | ||
1172 | |||
1173 | s = [=[ | ||
1174 | local t = { 1.5 } | ||
1175 | ]=] | ||
1176 | --[=[ | ||
1177 | { `Local{ { `Id "t" }, { `Table{ `Number "1.5" } } } } | ||
1178 | ]=] | ||
1179 | |||
1180 | r, m = parse(s) | ||
1181 | assert(r == true) | ||
1182 | |||
1183 | s = [=[ | ||
1184 | local t = {1,2; | ||
1185 | 3, | ||
1186 | 4, | ||
1187 | |||
1188 | |||
1189 | |||
1190 | 5} | ||
1191 | ]=] | ||
1192 | --[=[ | ||
1193 | { `Local{ { `Id "t" }, { `Table{ `Number "1", `Number "2", `Number "3", `Number "4", `Number "5" } } } } | ||
1194 | ]=] | ||
1195 | |||
1196 | r, m = parse(s) | ||
1197 | assert(r == true) | ||
1198 | |||
1199 | s = [=[ | ||
1200 | local t = {[1]=1,[2]=2; | ||
1201 | [3]=3, | ||
1202 | [4]=4, | ||
1203 | |||
1204 | |||
1205 | |||
1206 | [5]=5} | ||
1207 | ]=] | ||
1208 | --[=[ | ||
1209 | { `Local{ { `Id "t" }, { `Table{ `Pair{ `Number "1", `Number "1" }, `Pair{ `Number "2", `Number "2" }, `Pair{ `Number "3", `Number "3" }, `Pair{ `Number "4", `Number "4" }, `Pair{ `Number "5", `Number "5" } } } } } | ||
1210 | ]=] | ||
1211 | |||
1212 | r, m = parse(s) | ||
1213 | assert(r == true) | ||
1214 | |||
1215 | s = [=[ | ||
1216 | local t = {{{}}, {"alo"}} | ||
1217 | ]=] | ||
1218 | --[=[ | ||
1219 | { `Local{ { `Id "t" }, { `Table{ `Table{ `Table }, `Table{ `String "alo" } } } } } | ||
1220 | ]=] | ||
1221 | |||
1222 | r, m = parse(s) | ||
1223 | assert(r == true) | ||
1224 | |||
1225 | -- vararg | ||
1226 | |||
1227 | s = [=[ | ||
1228 | local f = function (...) | ||
1229 | return ... | ||
1230 | end | ||
1231 | ]=] | ||
1232 | --[=[ | ||
1233 | { `Local{ { `Id "f" }, { `Function{ { `Dots }, { `Return{ `Dots } } } } } } | ||
1234 | ]=] | ||
1235 | |||
1236 | r, m = parse(s) | ||
1237 | assert(r == true) | ||
1238 | |||
1239 | s = [=[ | ||
1240 | local f = function () | ||
1241 | local g = function (x, y, ...) | ||
1242 | return ...,...,... | ||
1243 | end | ||
1244 | end | ||
1245 | ]=] | ||
1246 | --[=[ | ||
1247 | { `Local{ { `Id "f" }, { `Function{ { }, { `Local{ { `Id "g" }, { `Function{ { `Id "x", `Id "y", `Dots }, { `Return{ `Dots, `Dots, `Dots } } } } } } } } } } | ||
1248 | ]=] | ||
1249 | |||
1250 | r, m = parse(s) | ||
1251 | assert(r == true) | ||
1252 | |||
1253 | s = [=[ | ||
1254 | local function f (x, ...) | ||
1255 | return ... | ||
1256 | end | ||
1257 | ]=] | ||
1258 | --[=[ | ||
1259 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x", `Dots }, { `Return{ `Dots } } } } } } | ||
1260 | ]=] | ||
1261 | |||
1262 | r, m = parse(s) | ||
1263 | assert(r == true) | ||
1264 | |||
1265 | s = [=[ | ||
1266 | local f = function (x, ...) | ||
1267 | return ... | ||
1268 | end | ||
1269 | ]=] | ||
1270 | --[=[ | ||
1271 | { `Local{ { `Id "f" }, { `Function{ { `Id "x", `Dots }, { `Return{ `Dots } } } } } } | ||
1272 | ]=] | ||
1273 | |||
1274 | r, m = parse(s) | ||
1275 | assert(r == true) | ||
1276 | |||
1277 | -- while | ||
1278 | |||
1279 | s = [=[ | ||
1280 | local i = 0 | ||
1281 | while (i < 10) | ||
1282 | do | ||
1283 | i = i + 1 | ||
1284 | end | ||
1285 | ]=] | ||
1286 | --[=[ | ||
1287 | { `Local{ { `Id "i" }, { `Number "0" } }, `While{ `Paren{ `Op{ "lt", `Id "i", `Number "10" } }, { `Set{ { `Id "i" }, { `Op{ "add", `Id "i", `Number "1" } } } } } } | ||
1288 | ]=] | ||
1289 | |||
1290 | r, m = parse(s) | ||
1291 | assert(r == true) | ||
1292 | |||
1293 | -- type annotations | ||
1294 | |||
1295 | s = [=[ | ||
1296 | local x:nil | ||
1297 | ]=] | ||
1298 | --[=[ | ||
1299 | { `Local{ { `Id "x":`TNil }, { } } } | ||
1300 | ]=] | ||
1301 | |||
1302 | r, m = parse(s) | ||
1303 | assert(r == true) | ||
1304 | |||
1305 | s = [=[ | ||
1306 | local x:false, y:true | ||
1307 | ]=] | ||
1308 | --[=[ | ||
1309 | { `Local{ { `Id "x":`TLiteral false, `Id "y":`TLiteral true }, { } } } | ||
1310 | ]=] | ||
1311 | |||
1312 | r, m = parse(s) | ||
1313 | assert(r == true) | ||
1314 | |||
1315 | s = [=[ | ||
1316 | local x:1, y:1.1 | ||
1317 | ]=] | ||
1318 | --[=[ | ||
1319 | { `Local{ { `Id "x":`TLiteral 1, `Id "y":`TLiteral 1.1 }, { } } } | ||
1320 | ]=] | ||
1321 | |||
1322 | r, m = parse(s) | ||
1323 | assert(r == true) | ||
1324 | |||
1325 | s = [=[ | ||
1326 | local x:"hello", y:'world' | ||
1327 | ]=] | ||
1328 | --[=[ | ||
1329 | { `Local{ { `Id "x":`TLiteral hello, `Id "y":`TLiteral world }, { } } } | ||
1330 | ]=] | ||
1331 | |||
1332 | r, m = parse(s) | ||
1333 | assert(r == true) | ||
1334 | |||
1335 | s = [=[ | ||
1336 | local x:boolean, y:number, z:string | ||
1337 | ]=] | ||
1338 | --[=[ | ||
1339 | { `Local{ { `Id "x":`TBase boolean, `Id "y":`TBase number, `Id "z":`TBase string }, { } } } | ||
1340 | ]=] | ||
1341 | |||
1342 | r, m = parse(s) | ||
1343 | assert(r == true) | ||
1344 | |||
1345 | s = [=[ | ||
1346 | local x:any | ||
1347 | ]=] | ||
1348 | --[=[ | ||
1349 | { `Local{ { `Id "x":`TAny }, { } } } | ||
1350 | ]=] | ||
1351 | |||
1352 | r, m = parse(s) | ||
1353 | assert(r == true) | ||
1354 | |||
1355 | s = [=[ | ||
1356 | local x:number? | ||
1357 | ]=] | ||
1358 | --[=[ | ||
1359 | { `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } } | ||
1360 | ]=] | ||
1361 | |||
1362 | r, m = parse(s) | ||
1363 | assert(r == true) | ||
1364 | |||
1365 | s = [=[ | ||
1366 | local x:number|nil | ||
1367 | ]=] | ||
1368 | --[=[ | ||
1369 | { `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } } | ||
1370 | ]=] | ||
1371 | |||
1372 | r, m = parse(s) | ||
1373 | assert(r == true) | ||
1374 | |||
1375 | s = [=[ | ||
1376 | local x:number|string|nil | ||
1377 | ]=] | ||
1378 | --[=[ | ||
1379 | { `Local{ { `Id "x":`TUnion{ `TBase number, `TBase string, `TNil } }, { } } } | ||
1380 | ]=] | ||
1381 | |||
1382 | r, m = parse(s) | ||
1383 | assert(r == true) | ||
1384 | |||
1385 | s = [=[ | ||
1386 | local x:number|nil|nil|nil|nil | ||
1387 | ]=] | ||
1388 | --[=[ | ||
1389 | { `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } } | ||
1390 | ]=] | ||
1391 | |||
1392 | r, m = parse(s) | ||
1393 | assert(r == true) | ||
1394 | |||
1395 | s = [=[ | ||
1396 | local x:number|nil|string|nil|number|boolean|string | ||
1397 | ]=] | ||
1398 | --[=[ | ||
1399 | { `Local{ { `Id "x":`TUnion{ `TNil, `TBase number, `TBase boolean, `TBase string } }, { } } } | ||
1400 | ]=] | ||
1401 | |||
1402 | r, m = parse(s) | ||
1403 | assert(r == true) | ||
1404 | |||
1405 | s = [=[ | ||
1406 | local x:number|string? | ||
1407 | ]=] | ||
1408 | --[=[ | ||
1409 | { `Local{ { `Id "x":`TUnion{ `TBase number, `TBase string, `TNil } }, { } } } | ||
1410 | ]=] | ||
1411 | |||
1412 | r, m = parse(s) | ||
1413 | assert(r == true) | ||
1414 | |||
1415 | s = [=[ | ||
1416 | local x:(number) -> (number) | ||
1417 | ]=] | ||
1418 | --[=[ | ||
1419 | { `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TVararg{ `TValue } }, `TTuple{ `TBase number, `TVararg{ `TNil } } } }, { } } } | ||
1420 | ]=] | ||
1421 | |||
1422 | r, m = parse(s) | ||
1423 | assert(r == true) | ||
1424 | |||
1425 | s = [=[ | ||
1426 | local x:(value*) -> (nil*) | ||
1427 | ]=] | ||
1428 | --[=[ | ||
1429 | { `Local{ { `Id "x":`TFunction{ `TTuple{ `TVararg{ `TValue } }, `TTuple{ `TVararg{ `TNil } } } }, { } } } | ||
1430 | ]=] | ||
1431 | |||
1432 | r, m = parse(s) | ||
1433 | assert(r == true) | ||
1434 | |||
1435 | s = [=[ | ||
1436 | local x:(number,string,boolean) -> (string,number,boolean) | ||
1437 | ]=] | ||
1438 | --[=[ | ||
1439 | { `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase string, `TBase boolean, `TVararg{ `TValue } }, `TTuple{ `TBase string, `TBase number, `TBase boolean, `TVararg{ `TNil } } } }, { } } } | ||
1440 | ]=] | ||
1441 | |||
1442 | r, m = parse(s) | ||
1443 | assert(r == true) | ||
1444 | |||
1445 | s = [=[ | ||
1446 | local x:(number,string,value*) -> (string,number,nil*) | ||
1447 | ]=] | ||
1448 | --[=[ | ||
1449 | { `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase string, `TVararg{ `TValue } }, `TTuple{ `TBase string, `TBase number, `TVararg{ `TNil } } } }, { } } } | ||
1450 | ]=] | ||
1451 | |||
1452 | r, m = parse(s) | ||
1453 | assert(r == true) | ||
1454 | |||
1455 | s = [=[ | ||
1456 | local x:{} | ||
1457 | ]=] | ||
1458 | --[=[ | ||
1459 | { `Local{ { `Id "x":`TTable{ } }, { } } } | ||
1460 | ]=] | ||
1461 | |||
1462 | r, m = parse(s) | ||
1463 | assert(r == true) | ||
1464 | |||
1465 | s = [=[ | ||
1466 | local x:{{{{{}}}}} | ||
1467 | ]=] | ||
1468 | --[=[ | ||
1469 | { `Local{ { `Id "x":`TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ }, `TNil } }, `TNil } }, `TNil } }, `TNil } } }, { } } } | ||
1470 | ]=] | ||
1471 | |||
1472 | r, m = parse(s) | ||
1473 | assert(r == true) | ||
1474 | |||
1475 | s = [=[ | ||
1476 | local x:{string} | ||
1477 | ]=] | ||
1478 | --[=[ | ||
1479 | { `Local{ { `Id "x":`TTable{ `TBase number:`TUnion{ `TBase string, `TNil } } }, { } } } | ||
1480 | ]=] | ||
1481 | |||
1482 | r, m = parse(s) | ||
1483 | assert(r == true) | ||
1484 | |||
1485 | s = [=[ | ||
1486 | local x:{string:number} | ||
1487 | ]=] | ||
1488 | --[=[ | ||
1489 | { `Local{ { `Id "x":`TTable{ `TBase string:`TUnion{ `TBase number, `TNil } } }, { } } } | ||
1490 | ]=] | ||
1491 | |||
1492 | r, m = parse(s) | ||
1493 | assert(r == true) | ||
1494 | |||
1495 | s = [=[ | ||
1496 | local x:{'firstname':string, 'lastname':string} | ||
1497 | ]=] | ||
1498 | --[=[ | ||
1499 | { `Local{ { `Id "x":`TTable{ `TLiteral firstname:`TBase string, `TLiteral lastname:`TBase string } }, { } } } | ||
1500 | ]=] | ||
1501 | |||
1502 | r, m = parse(s) | ||
1503 | assert(r == true) | ||
1504 | |||
1505 | s = [=[ | ||
1506 | local x:{'tag':string, number:string} | ||
1507 | ]=] | ||
1508 | --[=[ | ||
1509 | { `Local{ { `Id "x":`TTable{ `TLiteral tag:`TBase string, `TBase number:`TUnion{ `TBase string, `TNil } } }, { } } } | ||
1510 | ]=] | ||
1511 | |||
1512 | r, m = parse(s) | ||
1513 | assert(r == true) | ||
1514 | |||
1515 | s = [=[ | ||
1516 | local x:{'f':(number) -> (number), 't':{number:number}} | ||
1517 | ]=] | ||
1518 | --[=[ | ||
1519 | { `Local{ { `Id "x":`TTable{ `TLiteral f:`TFunction{ `TTuple{ `TBase number, `TVararg{ `TValue } }, `TTuple{ `TBase number, `TVararg{ `TNil } } }, `TLiteral t:`TTable{ `TBase number:`TUnion{ `TBase number, `TNil } } } }, { } } } | ||
1520 | ]=] | ||
1521 | |||
1522 | r, m = parse(s) | ||
1523 | assert(r == true) | ||
1524 | |||
1525 | s = [=[ | ||
1526 | for k:number, v:string in ipairs({"hello", "world"}) do end | ||
1527 | ]=] | ||
1528 | --[=[ | ||
1529 | { `Forin{ { `Id "k":`TBase number, `Id "v":`TBase string }, { `Call{ `Index{ `Id "_ENV", `String "ipairs" }, `Table{ `String "hello", `String "world" } } }, { } } } | ||
1530 | ]=] | ||
1531 | |||
1532 | r, m = parse(s) | ||
1533 | assert(r == true) | ||
1534 | |||
1535 | s = [=[ | ||
1536 | for k:string, v in pairs({}) do end | ||
1537 | ]=] | ||
1538 | --[=[ | ||
1539 | { `Forin{ { `Id "k":`TBase string, `Id "v" }, { `Call{ `Index{ `Id "_ENV", `String "pairs" }, `Table } }, { } } } | ||
1540 | ]=] | ||
1541 | |||
1542 | r, m = parse(s) | ||
1543 | assert(r == true) | ||
1544 | |||
1545 | s = [=[ | ||
1546 | for k, v:boolean in pairs({}) do end | ||
1547 | ]=] | ||
1548 | --[=[ | ||
1549 | { `Forin{ { `Id "k", `Id "v":`TBase boolean }, { `Call{ `Index{ `Id "_ENV", `String "pairs" }, `Table } }, { } } } | ||
1550 | ]=] | ||
1551 | |||
1552 | r, m = parse(s) | ||
1553 | assert(r == true) | ||
1554 | |||
1555 | s = [=[ | ||
1556 | local function f (x:any) end | ||
1557 | ]=] | ||
1558 | --[=[ | ||
1559 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny }, { } } } } } | ||
1560 | ]=] | ||
1561 | |||
1562 | r, m = parse(s) | ||
1563 | assert(r == true) | ||
1564 | |||
1565 | s = [=[ | ||
1566 | local function f (x:any):(any) end | ||
1567 | ]=] | ||
1568 | --[=[ | ||
1569 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny }:`TTuple{ `TAny, `TVararg{ `TNil } }, { } } } } } | ||
1570 | ]=] | ||
1571 | |||
1572 | r, m = parse(s) | ||
1573 | assert(r == true) | ||
1574 | |||
1575 | s = [=[ | ||
1576 | local function f (...:any) end | ||
1577 | ]=] | ||
1578 | --[=[ | ||
1579 | { `Localrec{ { `Id "f" }, { `Function{ { `Dots:`TAny }, { } } } } } | ||
1580 | ]=] | ||
1581 | |||
1582 | r, m = parse(s) | ||
1583 | assert(r == true) | ||
1584 | |||
1585 | s = [=[ | ||
1586 | local function f (x:any, ...:any) end | ||
1587 | ]=] | ||
1588 | --[=[ | ||
1589 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots:`TAny }, { } } } } } | ||
1590 | ]=] | ||
1591 | |||
1592 | r, m = parse(s) | ||
1593 | assert(r == true) | ||
1594 | |||
1595 | s = [=[ | ||
1596 | local function f (x, ...:any) end | ||
1597 | ]=] | ||
1598 | --[=[ | ||
1599 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x", `Dots:`TAny }, { } } } } } | ||
1600 | ]=] | ||
1601 | |||
1602 | r, m = parse(s) | ||
1603 | assert(r == true) | ||
1604 | |||
1605 | s = [=[ | ||
1606 | local function f (x:any, ...) end | ||
1607 | ]=] | ||
1608 | --[=[ | ||
1609 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots }, { } } } } } | ||
1610 | ]=] | ||
1611 | |||
1612 | r, m = parse(s) | ||
1613 | assert(r == true) | ||
1614 | |||
1615 | s = [=[ | ||
1616 | local function f (x:any, ...:any):(any) end | ||
1617 | ]=] | ||
1618 | --[=[ | ||
1619 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots:`TAny }:`TTuple{ `TAny, `TVararg{ `TNil } }, { } } } } } | ||
1620 | ]=] | ||
1621 | |||
1622 | r, m = parse(s) | ||
1623 | assert(r == true) | ||
1624 | |||
1625 | s = [=[ | ||
1626 | local function f (x:(any) -> (any)):((any) -> (any)) end | ||
1627 | ]=] | ||
1628 | --[=[ | ||
1629 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TFunction{ `TTuple{ `TAny, `TVararg{ `TValue } }, `TTuple{ `TAny, `TVararg{ `TNil } } } }:`TTuple{ `TFunction{ `TTuple{ `TAny, `TVararg{ `TValue } }, `TTuple{ `TAny, `TVararg{ `TNil } } }, `TVararg{ `TNil } }, { } } } } } | ||
1630 | ]=] | ||
1631 | |||
1632 | r, m = parse(s) | ||
1633 | assert(r == true) | ||
1634 | |||
1635 | s = [=[ | ||
1636 | local function f (x:(number, number) -> (number, nil*)):(number*) end | ||
1637 | ]=] | ||
1638 | --[=[ | ||
1639 | { `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase number, `TVararg{ `TValue } }, `TTuple{ `TBase number, `TVararg{ `TNil } } } }:`TTuple{ `TVararg{ `TBase number } }, { } } } } } | ||
1640 | ]=] | ||
1641 | |||
1642 | r, m = parse(s) | ||
1643 | assert(r == true) | ||
1644 | |||
1645 | s = [=[ | ||
1646 | local function f ():(number, nil*) end | ||
1647 | ]=] | ||
1648 | --[=[ | ||
1649 | { `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TBase number, `TVararg{ `TNil } }, { } } } } } | ||
1650 | ]=] | ||
1651 | |||
1652 | r, m = parse(s) | ||
1653 | assert(r == true) | ||
1654 | |||
1655 | s = [=[ | ||
1656 | local function f ():number end | ||
1657 | ]=] | ||
1658 | --[=[ | ||
1659 | { `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TBase number, `TVararg{ `TNil } }, { } } } } } | ||
1660 | ]=] | ||
1661 | |||
1662 | r, m = parse(s) | ||
1663 | assert(r == true) | ||
1664 | |||
1665 | s = [=[ | ||
1666 | local function f ():number? end | ||
1667 | ]=] | ||
1668 | --[=[ | ||
1669 | { `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TUnion{ `TBase number, `TNil }, `TVararg{ `TNil } }, { } } } } } | ||
1670 | ]=] | ||
1671 | |||
1672 | r, m = parse(s) | ||
1673 | assert(r == true) | ||
1674 | |||
1675 | s = [=[ | ||
1676 | local function f ():(number) | (nil,string) end | ||
1677 | ]=] | ||
1678 | --[=[ | ||
1679 | { `Localrec{ { `Id "f" }, { `Function{ { }:`TUnionlist{ `TTuple{ `TBase number, `TVararg{ `TNil } }, `TTuple{ `TNil, `TBase string, `TVararg{ `TNil } } }, { } } } } } | ||
1680 | ]=] | ||
1681 | |||
1682 | r, m = parse(s) | ||
1683 | assert(r == true) | ||
1684 | |||
1685 | s = [=[ | ||
1686 | local function f ():(number)? end | ||
1687 | ]=] | ||
1688 | --[=[ | ||
1689 | { `Localrec{ { `Id "f" }, { `Function{ { }:`TUnionlist{ `TTuple{ `TBase number, `TVararg{ `TNil } }, `TTuple{ `TNil, `TBase string, `TVararg{ `TNil } } }, { } } } } } | ||
1690 | ]=] | ||
1691 | |||
1692 | r, m = parse(s) | ||
1693 | assert(r == true) | ||
1694 | |||
1695 | -- syntax error | ||
1696 | |||
1697 | -- anonymous functions | ||
1698 | |||
1699 | s = [=[ | ||
1700 | a = function (a,b,) end | ||
1701 | ]=] | ||
1702 | --[=[ | ||
1703 | test.lua:1:19: syntax error, unexpected ')', expecting '...', 'Name' | ||
1704 | ]=] | ||
1705 | e = [=[ | ||
1706 | test.lua:1:18: expecting '...' | ||
1707 | ]=] | ||
1708 | |||
1709 | r, m = parse(s) | ||
1710 | assert(m == e) | ||
1711 | |||
1712 | s = [=[ | ||
1713 | a = function (...,a) end | ||
1714 | ]=] | ||
1715 | --[=[ | ||
1716 | test.lua:1:18: syntax error, unexpected ',', expecting ')', ':' | ||
1717 | ]=] | ||
1718 | e = [=[ | ||
1719 | test.lua:1:17: missing ')' | ||
1720 | ]=] | ||
1721 | |||
1722 | r, m = parse(s) | ||
1723 | assert(m == e) | ||
1724 | |||
1725 | s = [=[ | ||
1726 | local a = function (1) end | ||
1727 | ]=] | ||
1728 | --[=[ | ||
1729 | test.lua:1:21: syntax error, unexpected '1', expecting ')', '...', 'Name' | ||
1730 | ]=] | ||
1731 | e = [=[ | ||
1732 | test.lua:1:20: missing ')' | ||
1733 | ]=] | ||
1734 | |||
1735 | r, m = parse(s) | ||
1736 | assert(m == e) | ||
1737 | |||
1738 | s = [=[ | ||
1739 | local test = function ( a , b , c , ... ) | ||
1740 | ]=] | ||
1741 | --[=[ | ||
1742 | test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ':' | ||
1743 | ]=] | ||
1744 | e = [=[ | ||
1745 | test.lua:2:1: missing 'end' to close function declaration | ||
1746 | ]=] | ||
1747 | |||
1748 | r, m = parse(s) | ||
1749 | assert(m == e) | ||
1750 | |||
1751 | -- arithmetic expressions | ||
1752 | |||
1753 | s = [=[ | ||
1754 | a = 3 / / 2 | ||
1755 | ]=] | ||
1756 | --[=[ | ||
1757 | test.lua:1:9: syntax error, unexpected '/', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1758 | ]=] | ||
1759 | e = [=[ | ||
1760 | test.lua:1:8: malformed multiplication expression | ||
1761 | ]=] | ||
1762 | |||
1763 | r, m = parse(s) | ||
1764 | assert(m == e) | ||
1765 | |||
1766 | -- bitwise expressions | ||
1767 | |||
1768 | s = [=[ | ||
1769 | b = 1 && 1 | ||
1770 | ]=] | ||
1771 | --[=[ | ||
1772 | test.lua:1:8: syntax error, unexpected '&', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1773 | ]=] | ||
1774 | e = [=[ | ||
1775 | test.lua:1:7: malformed '&' expression | ||
1776 | ]=] | ||
1777 | |||
1778 | r, m = parse(s) | ||
1779 | assert(m == e) | ||
1780 | |||
1781 | s = [=[ | ||
1782 | b = 1 <> 0 | ||
1783 | ]=] | ||
1784 | --[=[ | ||
1785 | test.lua:1:8: syntax error, unexpected '>', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1786 | ]=] | ||
1787 | e = [=[ | ||
1788 | test.lua:1:7: malformed relational expression | ||
1789 | ]=] | ||
1790 | |||
1791 | r, m = parse(s) | ||
1792 | assert(m == e) | ||
1793 | |||
1794 | s = [=[ | ||
1795 | b = 1 < < 0 | ||
1796 | ]=] | ||
1797 | --[=[ | ||
1798 | test.lua:1:9: syntax error, unexpected '<', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1799 | ]=] | ||
1800 | e = [=[ | ||
1801 | test.lua:1:8: malformed relational expression | ||
1802 | ]=] | ||
1803 | |||
1804 | r, m = parse(s) | ||
1805 | assert(m == e) | ||
1806 | |||
1807 | -- concatenation expressions | ||
1808 | |||
1809 | s = [=[ | ||
1810 | concat2 = 2^3..1 | ||
1811 | ]=] | ||
1812 | --[=[ | ||
1813 | test.lua:1:15: syntax error, unexpected '.1', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^' | ||
1814 | ]=] | ||
1815 | e = [=[ | ||
1816 | test.lua:1:14: malformed <number> | ||
1817 | ]=] | ||
1818 | |||
1819 | r, m = parse(s) | ||
1820 | assert(m == e) | ||
1821 | |||
1822 | -- for generic | ||
1823 | |||
1824 | s = [=[ | ||
1825 | for k;v in pairs(t) do end | ||
1826 | ]=] | ||
1827 | --[=[ | ||
1828 | test.lua:1:6: syntax error, unexpected ';', expecting 'in', ',', ':', '=' | ||
1829 | ]=] | ||
1830 | e = [=[ | ||
1831 | test.lua:1:5: expecting 'in' | ||
1832 | ]=] | ||
1833 | |||
1834 | r, m = parse(s) | ||
1835 | assert(m == e) | ||
1836 | |||
1837 | s = [=[ | ||
1838 | for k,v in pairs(t:any) do end | ||
1839 | ]=] | ||
1840 | --[=[ | ||
1841 | test.lua:1:23: syntax error, unexpected ')', expecting 'String', '{', '(' | ||
1842 | ]=] | ||
1843 | e = [=[ | ||
1844 | test.lua:1:22: expecting '(' for method call | ||
1845 | ]=] | ||
1846 | |||
1847 | r, m = parse(s) | ||
1848 | assert(m == e) | ||
1849 | |||
1850 | -- for numeric | ||
1851 | |||
1852 | s = [=[ | ||
1853 | for i=1,10, do end | ||
1854 | ]=] | ||
1855 | --[=[ | ||
1856 | test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1857 | ]=] | ||
1858 | e = [=[ | ||
1859 | test.lua:1:10: missing 'do' in for statement | ||
1860 | ]=] | ||
1861 | |||
1862 | r, m = parse(s) | ||
1863 | assert(m == e) | ||
1864 | |||
1865 | s = [=[ | ||
1866 | for i=1,n:number do end | ||
1867 | ]=] | ||
1868 | --[=[ | ||
1869 | test.lua:1:18: syntax error, unexpected 'do', expecting 'String', '{', '(' | ||
1870 | ]=] | ||
1871 | e = [=[ | ||
1872 | test.lua:1:17: expecting '(' for method call | ||
1873 | ]=] | ||
1874 | |||
1875 | r, m = parse(s) | ||
1876 | assert(m == e) | ||
1877 | |||
1878 | -- global functions | ||
1879 | |||
1880 | s = [=[ | ||
1881 | function func(a,b,c,) end | ||
1882 | ]=] | ||
1883 | --[=[ | ||
1884 | test.lua:1:21: syntax error, unexpected ')', expecting '...', 'Name' | ||
1885 | ]=] | ||
1886 | e = [=[ | ||
1887 | test.lua:1:20: expecting '...' | ||
1888 | ]=] | ||
1889 | |||
1890 | r, m = parse(s) | ||
1891 | assert(m == e) | ||
1892 | |||
1893 | s = [=[ | ||
1894 | function func(...,a) end | ||
1895 | ]=] | ||
1896 | --[=[ | ||
1897 | test.lua:1:18: syntax error, unexpected ',', expecting ')', ':' | ||
1898 | ]=] | ||
1899 | e = [=[ | ||
1900 | test.lua:1:17: missing ')' | ||
1901 | ]=] | ||
1902 | |||
1903 | r, m = parse(s) | ||
1904 | assert(m == e) | ||
1905 | |||
1906 | s = [=[ | ||
1907 | function a.b:c:d () end | ||
1908 | ]=] | ||
1909 | --[=[ | ||
1910 | test.lua:1:15: syntax error, unexpected ':', expecting '(' | ||
1911 | ]=] | ||
1912 | e = [=[ | ||
1913 | test.lua:1:14: missing '(' | ||
1914 | ]=] | ||
1915 | |||
1916 | r, m = parse(s) | ||
1917 | assert(m == e) | ||
1918 | |||
1919 | -- goto | ||
1920 | |||
1921 | s = [=[ | ||
1922 | :: label :: return | ||
1923 | goto label | ||
1924 | ]=] | ||
1925 | --[=[ | ||
1926 | test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1927 | ]=] | ||
1928 | e = [=[ | ||
1929 | test.lua:2:1: invalid statement after 'return' | ||
1930 | ]=] | ||
1931 | |||
1932 | r, m = parse(s) | ||
1933 | assert(m == e) | ||
1934 | |||
1935 | -- if-else | ||
1936 | |||
1937 | s = [=[ | ||
1938 | if a then | ||
1939 | ]=] | ||
1940 | --[=[ | ||
1941 | test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'else', 'elseif', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';' | ||
1942 | ]=] | ||
1943 | e = [=[ | ||
1944 | test.lua:2:1: missing 'end' to close if statement | ||
1945 | ]=] | ||
1946 | |||
1947 | r, m = parse(s) | ||
1948 | assert(m == e) | ||
1949 | |||
1950 | s = [=[ | ||
1951 | if a then else | ||
1952 | ]=] | ||
1953 | --[=[ | ||
1954 | test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';' | ||
1955 | ]=] | ||
1956 | e = [=[ | ||
1957 | test.lua:2:1: missing 'end' to close if statement | ||
1958 | ]=] | ||
1959 | |||
1960 | r, m = parse(s) | ||
1961 | assert(m == e) | ||
1962 | |||
1963 | s = [=[ | ||
1964 | if a then | ||
1965 | return a | ||
1966 | elseif b then | ||
1967 | return b | ||
1968 | elseif | ||
1969 | |||
1970 | end | ||
1971 | ]=] | ||
1972 | --[=[ | ||
1973 | test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
1974 | ]=] | ||
1975 | e = [=[ | ||
1976 | test.lua:7:1: expecting <exp> after 'elseif' | ||
1977 | ]=] | ||
1978 | |||
1979 | r, m = parse(s) | ||
1980 | assert(m == e) | ||
1981 | |||
1982 | s = [=[ | ||
1983 | if a:any then else end | ||
1984 | ]=] | ||
1985 | --[=[ | ||
1986 | test.lua:1:10: syntax error, unexpected 'then', expecting 'String', '{', '(' | ||
1987 | ]=] | ||
1988 | e = [=[ | ||
1989 | test.lua:1:9: expecting '(' for method call | ||
1990 | ]=] | ||
1991 | |||
1992 | r, m = parse(s) | ||
1993 | assert(m == e) | ||
1994 | |||
1995 | -- labels | ||
1996 | |||
1997 | s = [=[ | ||
1998 | :: blah :: | ||
1999 | :: not :: | ||
2000 | ]=] | ||
2001 | --[=[ | ||
2002 | test.lua:2:4: syntax error, unexpected 'not', expecting 'Name' | ||
2003 | ]=] | ||
2004 | e = [=[ | ||
2005 | test.lua:2:3: expecting <name> after '::' | ||
2006 | ]=] | ||
2007 | |||
2008 | r, m = parse(s) | ||
2009 | assert(m == e) | ||
2010 | |||
2011 | -- locals | ||
2012 | |||
2013 | s = [=[ | ||
2014 | local a = | ||
2015 | ]=] | ||
2016 | --[=[ | ||
2017 | test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
2018 | ]=] | ||
2019 | e = [=[ | ||
2020 | test.lua:2:1: expecting expression list after '=' | ||
2021 | ]=] | ||
2022 | |||
2023 | r, m = parse(s) | ||
2024 | assert(m == e) | ||
2025 | |||
2026 | s = [=[ | ||
2027 | local function t.a() end | ||
2028 | ]=] | ||
2029 | --[=[ | ||
2030 | test.lua:1:17: syntax error, unexpected '.', expecting '(' | ||
2031 | ]=] | ||
2032 | e = [=[ | ||
2033 | test.lua:1:16: missing '(' | ||
2034 | ]=] | ||
2035 | |||
2036 | r, m = parse(s) | ||
2037 | assert(m == e) | ||
2038 | |||
2039 | s = [=[ | ||
2040 | local function test (a,) end | ||
2041 | ]=] | ||
2042 | --[=[ | ||
2043 | test.lua:1:24: syntax error, unexpected ')', expecting '...', 'Name' | ||
2044 | ]=] | ||
2045 | e = [=[ | ||
2046 | test.lua:1:23: expecting '...' | ||
2047 | ]=] | ||
2048 | |||
2049 | r, m = parse(s) | ||
2050 | assert(m == e) | ||
2051 | |||
2052 | s = [=[ | ||
2053 | local function test(...,a) end | ||
2054 | ]=] | ||
2055 | --[=[ | ||
2056 | test.lua:1:24: syntax error, unexpected ',', expecting ')', ':' | ||
2057 | ]=] | ||
2058 | e = [=[ | ||
2059 | test.lua:1:23: missing ')' | ||
2060 | ]=] | ||
2061 | |||
2062 | r, m = parse(s) | ||
2063 | assert(m == e) | ||
2064 | |||
2065 | s = [=[ | ||
2066 | local function (a, b, c, ...) end | ||
2067 | ]=] | ||
2068 | --[=[ | ||
2069 | test.lua:1:16: syntax error, unexpected '(', expecting 'Name' | ||
2070 | ]=] | ||
2071 | e = [=[ | ||
2072 | test.lua:1:15: expecting <name> in local function declaration | ||
2073 | ]=] | ||
2074 | |||
2075 | r, m = parse(s) | ||
2076 | assert(m == e) | ||
2077 | |||
2078 | -- repeat | ||
2079 | |||
2080 | s = [=[ | ||
2081 | repeat | ||
2082 | a,b,c = 1+1,2+2,3+3 | ||
2083 | break | ||
2084 | ]=] | ||
2085 | --[=[ | ||
2086 | test.lua:4:1: syntax error, unexpected 'EOF', expecting 'until', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';' | ||
2087 | ]=] | ||
2088 | e = [=[ | ||
2089 | test.lua:4:1: missing 'until' in repeat statement | ||
2090 | ]=] | ||
2091 | |||
2092 | r, m = parse(s) | ||
2093 | assert(m == e) | ||
2094 | |||
2095 | -- return | ||
2096 | |||
2097 | s = [=[ | ||
2098 | return | ||
2099 | return 1 | ||
2100 | return 1,1-2*3+4,"alo" | ||
2101 | return; | ||
2102 | return 1; | ||
2103 | return 1,1-2*3+4,"alo"; | ||
2104 | ]=] | ||
2105 | --[=[ | ||
2106 | test.lua:2:1: syntax error, unexpected 'return', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not' | ||
2107 | ]=] | ||
2108 | e = [=[ | ||
2109 | test.lua:2:1: invalid statement | ||
2110 | ]=] | ||
2111 | |||
2112 | r, m = parse(s) | ||
2113 | assert(m == e) | ||
2114 | |||
2115 | -- tables | ||
2116 | |||
2117 | s = [=[ | ||
2118 | t = { , } | ||
2119 | ]=] | ||
2120 | --[=[ | ||
2121 | test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not', 'Name', '[', 'const' | ||
2122 | ]=] | ||
2123 | e = [=[ | ||
2124 | test.lua:1:6: missing '}' | ||
2125 | ]=] | ||
2126 | |||
2127 | r, m = parse(s) | ||
2128 | assert(m == e) | ||
2129 | |||
2130 | -- while | ||
2131 | |||
2132 | s = [=[ | ||
2133 | i = 0 | ||
2134 | while (i < 10) | ||
2135 | i = i + 1 | ||
2136 | end | ||
2137 | ]=] | ||
2138 | --[=[ | ||
2139 | test.lua:3:3: syntax error, unexpected 'i', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^', 'String', '{', '(', ':', '[', '.' | ||
2140 | ]=] | ||
2141 | e = [=[ | ||
2142 | test.lua:3:2: missing 'do' in while statement | ||
2143 | ]=] | ||
2144 | |||
2145 | r, m = parse(s) | ||
2146 | assert(m == e) | ||
2147 | |||
2148 | -- type annotations | ||
2149 | |||
2150 | s = [=[ | ||
2151 | t[x:any] = 1 | ||
2152 | ]=] | ||
2153 | --[=[ | ||
2154 | test.lua:1:8: syntax error, unexpected ']', expecting 'String', '{', '(' | ||
2155 | ]=] | ||
2156 | e = [=[ | ||
2157 | test.lua:1:7: expecting '(' for method call | ||
2158 | ]=] | ||
2159 | |||
2160 | r, m = parse(s) | ||
2161 | assert(m == e) | ||
2162 | |||
2163 | s = [=[ | ||
2164 | x:number, y, z:boolean = 1, nil, true | ||
2165 | ]=] | ||
2166 | --[=[ | ||
2167 | test.lua:1:9: syntax error, unexpected ',', expecting 'String', '{', '(' | ||
2168 | ]=] | ||
2169 | e = [=[ | ||
2170 | test.lua:1:8: expecting '(' for method call | ||
2171 | ]=] | ||
2172 | |||
2173 | r, m = parse(s) | ||
2174 | assert(m == e) | ||
2175 | |||
2176 | s = [=[ | ||
2177 | x = x:any | ||
2178 | ]=] | ||
2179 | --[=[ | ||
2180 | test.lua:2:1: syntax error, unexpected 'EOF', expecting 'String', '{', '(' | ||
2181 | ]=] | ||
2182 | e = [=[ | ||
2183 | test.lua:2:1: expecting '(' for method call | ||
2184 | ]=] | ||
2185 | |||
2186 | r, m = parse(s) | ||
2187 | assert(m == e) | ||
2188 | |||
2189 | s = [=[ | ||
2190 | x = ...:any | ||
2191 | ]=] | ||
2192 | --[=[ | ||
2193 | test.lua:1:8: syntax error, unexpected ':', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^' | ||
2194 | ]=] | ||
2195 | e = [=[ | ||
2196 | test.lua:1:7: invalid statement | ||
2197 | ]=] | ||
2198 | |||
2199 | r, m = parse(s) | ||
2200 | assert(m == e) | ||
2201 | |||
2202 | s = [=[ | ||
2203 | f(x:any) | ||
2204 | ]=] | ||
2205 | --[=[ | ||
2206 | test.lua:1:8: syntax error, unexpected ')', expecting 'String', '{', '(' | ||
2207 | ]=] | ||
2208 | e = [=[ | ||
2209 | test.lua:1:7: expecting '(' for method call | ||
2210 | ]=] | ||
2211 | |||
2212 | r, m = parse(s) | ||
2213 | assert(m == e) | ||
2214 | |||
2215 | s = [=[ | ||
2216 | f(...:any) | ||
2217 | ]=] | ||
2218 | --[=[ | ||
2219 | test.lua:1:6: syntax error, unexpected ':', expecting ')', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^' | ||
2220 | ]=] | ||
2221 | e = [=[ | ||
2222 | test.lua:1:5: missing ')' | ||
2223 | ]=] | ||
2224 | |||
2225 | r, m = parse(s) | ||
2226 | assert(m == e) | ||
2227 | |||
2228 | s = [=[ | ||
2229 | local x:number* | ||
2230 | ]=] | ||
2231 | --[=[ | ||
2232 | test.lua:1:15: syntax error, unexpected '*', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', '=', ',', '?', '|' | ||
2233 | ]=] | ||
2234 | e = [=[ | ||
2235 | test.lua:1:6: invalid local declaration | ||
2236 | ]=] | ||
2237 | |||
2238 | r, m = parse(s) | ||
2239 | assert(m == e) | ||
2240 | |||
2241 | s = [=[ | ||
2242 | local x:number| | ||
2243 | ]=] | ||
2244 | --[=[ | ||
2245 | test.lua:2:1: syntax error, unexpected 'EOF', expecting '{', '(', 'Type' | ||
2246 | ]=] | ||
2247 | e = [=[ | ||
2248 | test.lua:2:1: expecting <type> after '|' | ||
2249 | ]=] | ||
2250 | |||
2251 | r, m = parse(s) | ||
2252 | assert(m == e) | ||
2253 | |||
2254 | s = [=[ | ||
2255 | local x:number?|string? | ||
2256 | ]=] | ||
2257 | --[=[ | ||
2258 | test.lua:1:16: syntax error, unexpected '|', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', '=', ',' | ||
2259 | ]=] | ||
2260 | e = [=[ | ||
2261 | test.lua:1:6: invalid local declaration | ||
2262 | ]=] | ||
2263 | |||
2264 | r, m = parse(s) | ||
2265 | assert(m == e) | ||
2266 | |||
2267 | s = [=[ | ||
2268 | local x:() -> number | ||
2269 | ]=] | ||
2270 | --[=[ | ||
2271 | test.lua:1:15: syntax error, unexpected 'number', expecting '(' | ||
2272 | ]=] | ||
2273 | e = [=[ | ||
2274 | test.lua:1:14: expecting <type> after '->' | ||
2275 | ]=] | ||
2276 | |||
2277 | r, m = parse(s) | ||
2278 | assert(m == e) | ||
2279 | |||
2280 | s = [=[ | ||
2281 | local x:() -> (number)? | (string)? | ||
2282 | ]=] | ||
2283 | --[=[ | ||
2284 | test.lua:1:35: syntax error, unexpected '?', expecting '->' | ||
2285 | ]=] | ||
2286 | e = [=[ | ||
2287 | test.lua:1:26: expecting <type> after '|' | ||
2288 | ]=] | ||
2289 | |||
2290 | r, m = parse(s) | ||
2291 | assert(m == e) | ||
2292 | |||
2293 | s = [=[ | ||
2294 | local x:{()->():string} | ||
2295 | ]=] | ||
2296 | --[=[ | ||
2297 | test.lua:1:16: syntax error, unexpected ':', expecting '}', '?', '|' | ||
2298 | ]=] | ||
2299 | e = [=[ | ||
2300 | test.lua:1:15: missing '}' | ||
2301 | ]=] | ||
2302 | |||
2303 | r, m = parse(s) | ||
2304 | assert(m == e) | ||
2305 | |||
2306 | s = [=[ | ||
2307 | local x:{string:t 1} | ||
2308 | ]=] | ||
2309 | --[=[ | ||
2310 | test.lua:1:19: syntax error, unexpected '1', expecting '}', '?', '|' | ||
2311 | ]=] | ||
2312 | e = [=[ | ||
2313 | test.lua:1:18: missing '}' | ||
2314 | ]=] | ||
2315 | |||
2316 | r, m = parse(s) | ||
2317 | assert(m == e) | ||
2318 | |||
2319 | s = [=[ | ||
2320 | local x:{{{{{}}}} | ||
2321 | ]=] | ||
2322 | --[=[ | ||
2323 | test.lua:2:1: syntax error, unexpected 'EOF', expecting '}', '?', '|' | ||
2324 | ]=] | ||
2325 | e = [=[ | ||
2326 | test.lua:2:1: missing '}' | ||
2327 | ]=] | ||
2328 | |||
2329 | r, m = parse(s) | ||
2330 | assert(m == e) | ||
2331 | |||
2332 | -- syntax errors that depend on some semantic information | ||
2333 | |||
2334 | -- break | ||
2335 | |||
2336 | s = [=[ | ||
2337 | break | ||
2338 | ]=] | ||
2339 | --[=[ | ||
2340 | test.lua:1:1: syntax error, <break> not inside a loop | ||
2341 | ]=] | ||
2342 | |||
2343 | r, m = parse(s) | ||
2344 | assert(r == true) | ||
2345 | |||
2346 | s = [=[ | ||
2347 | function f (x) | ||
2348 | if 1 then break end | ||
2349 | end | ||
2350 | ]=] | ||
2351 | --[=[ | ||
2352 | test.lua:2:13: syntax error, <break> not inside a loop | ||
2353 | ]=] | ||
2354 | |||
2355 | r, m = parse(s) | ||
2356 | assert(r == true) | ||
2357 | |||
2358 | s = [=[ | ||
2359 | while 1 do | ||
2360 | end | ||
2361 | break | ||
2362 | ]=] | ||
2363 | --[=[ | ||
2364 | test.lua:3:1: syntax error, <break> not inside a loop | ||
2365 | ]=] | ||
2366 | |||
2367 | r, m = parse(s) | ||
2368 | assert(r == true) | ||
2369 | |||
2370 | -- goto | ||
2371 | |||
2372 | s = [=[ | ||
2373 | goto label | ||
2374 | ]=] | ||
2375 | --[=[ | ||
2376 | test.lua:1:1: syntax error, no visible label 'label' for <goto> | ||
2377 | ]=] | ||
2378 | |||
2379 | r, m = parse(s) | ||
2380 | assert(r == true) | ||
2381 | |||
2382 | s = [=[ | ||
2383 | goto label | ||
2384 | ::other_label:: | ||
2385 | ]=] | ||
2386 | --[=[ | ||
2387 | test.lua:1:1: syntax error, no visible label 'label' for <goto> | ||
2388 | ]=] | ||
2389 | |||
2390 | r, m = parse(s) | ||
2391 | assert(r == true) | ||
2392 | |||
2393 | s = [=[ | ||
2394 | ::other_label:: | ||
2395 | do do do goto label end end end | ||
2396 | ]=] | ||
2397 | --[=[ | ||
2398 | test.lua:2:10: syntax error, no visible label 'label' for <goto> | ||
2399 | ]=] | ||
2400 | |||
2401 | r, m = parse(s) | ||
2402 | assert(r == true) | ||
2403 | |||
2404 | -- interfaces | ||
2405 | |||
2406 | s = [=[ | ||
2407 | local interface X | ||
2408 | x:number | ||
2409 | y:number | ||
2410 | z:number | ||
2411 | x:number | ||
2412 | end | ||
2413 | ]=] | ||
2414 | --[=[ | ||
2415 | test.lua:1:7: syntax error, attempt to redeclare field 'x' | ||
2416 | ]=] | ||
2417 | |||
2418 | r, m = parse(s) | ||
2419 | assert(r == true) | ||
2420 | |||
2421 | s = [=[ | ||
2422 | local interface X | ||
2423 | x, y, z, x:number | ||
2424 | end | ||
2425 | ]=] | ||
2426 | --[=[ | ||
2427 | test.lua:1:7: syntax error, attempt to redeclare field 'x' | ||
2428 | ]=] | ||
2429 | |||
2430 | r, m = parse(s) | ||
2431 | assert(r == true) | ||
2432 | |||
2433 | s = [=[ | ||
2434 | local interface boolean end | ||
2435 | ]=] | ||
2436 | --[=[ | ||
2437 | test.lua:1:7: syntax error, attempt to redeclare type 'boolean' | ||
2438 | ]=] | ||
2439 | |||
2440 | r, m = parse(s) | ||
2441 | assert(r == true) | ||
2442 | |||
2443 | s = [=[ | ||
2444 | local interface number end | ||
2445 | ]=] | ||
2446 | --[=[ | ||
2447 | test.lua:1:7: syntax error, attempt to redeclare type 'number' | ||
2448 | ]=] | ||
2449 | |||
2450 | r, m = parse(s) | ||
2451 | assert(r == true) | ||
2452 | |||
2453 | s = [=[ | ||
2454 | local interface string end | ||
2455 | ]=] | ||
2456 | --[=[ | ||
2457 | test.lua:1:7: syntax error, attempt to redeclare type 'string' | ||
2458 | ]=] | ||
2459 | |||
2460 | r, m = parse(s) | ||
2461 | assert(r == true) | ||
2462 | |||
2463 | s = [=[ | ||
2464 | local interface value end | ||
2465 | ]=] | ||
2466 | --[=[ | ||
2467 | test.lua:1:7: syntax error, attempt to redeclare type 'value' | ||
2468 | ]=] | ||
2469 | |||
2470 | r, m = parse(s) | ||
2471 | assert(r == true) | ||
2472 | |||
2473 | s = [=[ | ||
2474 | local interface any end | ||
2475 | ]=] | ||
2476 | --[=[ | ||
2477 | test.lua:1:7: syntax error, attempt to redeclare type 'any' | ||
2478 | ]=] | ||
2479 | |||
2480 | r, m = parse(s) | ||
2481 | assert(r == true) | ||
2482 | |||
2483 | s = [=[ | ||
2484 | local interface self end | ||
2485 | ]=] | ||
2486 | --[=[ | ||
2487 | test.lua:1:7: syntax error, attempt to redeclare type 'self' | ||
2488 | ]=] | ||
2489 | |||
2490 | r, m = parse(s) | ||
2491 | assert(r == true) | ||
2492 | |||
2493 | s = [=[ | ||
2494 | local interface const end | ||
2495 | ]=] | ||
2496 | --[=[ | ||
2497 | test.lua:1:7: syntax error, attempt to redeclare type 'const' | ||
2498 | ]=] | ||
2499 | |||
2500 | r, m = parse(s) | ||
2501 | assert(r == true) | ||
2502 | |||
2503 | -- labels | ||
2504 | |||
2505 | s = [=[ | ||
2506 | ::label:: | ||
2507 | ::other_label:: | ||
2508 | ::label:: | ||
2509 | ]=] | ||
2510 | --[=[ | ||
2511 | test.lua:3:1: syntax error, label 'label' already defined | ||
2512 | ]=] | ||
2513 | |||
2514 | r, m = parse(s) | ||
2515 | assert(r == true) | ||
2516 | |||
2517 | -- vararg | ||
2518 | |||
2519 | s = [=[ | ||
2520 | function f () | ||
2521 | return ... | ||
2522 | end | ||
2523 | ]=] | ||
2524 | --[=[ | ||
2525 | test.lua:2:10: syntax error, cannot use '...' outside a vararg function | ||
2526 | ]=] | ||
2527 | |||
2528 | r, m = parse(s) | ||
2529 | assert(r == true) | ||
2530 | |||
2531 | s = [=[ | ||
2532 | function f () | ||
2533 | function g (x, y) | ||
2534 | return ...,...,... | ||
2535 | end | ||
2536 | end | ||
2537 | ]=] | ||
2538 | --[=[ | ||
2539 | test.lua:3:12: syntax error, cannot use '...' outside a vararg function | ||
2540 | ]=] | ||
2541 | |||
2542 | r, m = parse(s) | ||
2543 | assert(r == true) | ||
2544 | |||
2545 | s = [=[ | ||
2546 | local function f (x) | ||
2547 | return ... | ||
2548 | end | ||
2549 | ]=] | ||
2550 | --[=[ | ||
2551 | test.lua:2:10: syntax error, cannot use '...' outside a vararg function | ||
2552 | ]=] | ||
2553 | |||
2554 | r, m = parse(s) | ||
2555 | assert(r == true) | ||
2556 | |||
2557 | s = [=[ | ||
2558 | local f = function (x) | ||
2559 | return ... | ||
2560 | end | ||
2561 | ]=] | ||
2562 | --[=[ | ||
2563 | test.lua:2:10: syntax error, cannot use '...' outside a vararg function | ||
2564 | ]=] | ||
2565 | |||
2566 | r, m = parse(s) | ||
2567 | assert(r == true) | ||
2568 | |||
2569 | print("OK") | ||
diff --git a/examples/typedlua/tlerror.lua b/examples/typedlua/tlerror.lua new file mode 100644 index 0000000..94be024 --- /dev/null +++ b/examples/typedlua/tlerror.lua | |||
@@ -0,0 +1,66 @@ | |||
1 | |||
2 | local errors = {} | ||
3 | local function new_error (label, msg) | ||
4 | table.insert(errors, { label = label, msg = msg }) | ||
5 | end | ||
6 | |||
7 | new_error("Number", "malformed <number>") | ||
8 | new_error("String", "malformed <string>") | ||
9 | new_error("LongString", "unfinished long string") | ||
10 | new_error("LongComment", "unfinished long comment") | ||
11 | new_error("MissingOP", "missing '('") | ||
12 | new_error("MissingCP", "missing ')'") | ||
13 | new_error("MissingCC", "missing '}'") | ||
14 | new_error("MissingCB", "missing ']'") | ||
15 | new_error("UnionType", "expecting <type> after '|'") | ||
16 | new_error("FunctionType", "expecting <type> after '->'") | ||
17 | new_error("MethodType", "expecting <type> after '=>'") | ||
18 | new_error("TupleType", "expecting <type> after ','") | ||
19 | new_error("Type", "expecting <type> after ':'") | ||
20 | new_error("TypeDecEnd", "missing 'end' in type declaration") | ||
21 | new_error("TypeAliasName", "expecting <name> after 'typealias'") | ||
22 | new_error("MissingEqTypeAlias", "missing '=' in 'typealias'") | ||
23 | new_error("DotIndex", "expecting <name> after '.'") | ||
24 | new_error("MethodName", "expecting <name> after ':'") | ||
25 | new_error("Then", "missing 'then'") | ||
26 | new_error("IfEnd", "missing 'end' to close if statement") | ||
27 | new_error("WhileDo", "missing 'do' in while statement") | ||
28 | new_error("WhileEnd", "missing 'end' to close while statement") | ||
29 | new_error("BlockEnd", "missing 'end' to close block") | ||
30 | new_error("ForDo", "missing 'do' in for statement") | ||
31 | new_error("ForEnd", "missing 'end' to close for statement") | ||
32 | new_error("Until", "missing 'until' in repeat statement") | ||
33 | new_error("FuncEnd", "missing 'end' to close function declaration") | ||
34 | new_error("ParList", "expecting '...'") | ||
35 | new_error("MethodCall", "expecting '(' for method call") | ||
36 | new_error("Label1", "expecting <name> after '::'") | ||
37 | new_error("Label2", "expecting '::' to close label declaration") | ||
38 | new_error("LocalAssign1", "expecting expression list after '='") | ||
39 | new_error("LocalAssign2", "invalid local declaration") | ||
40 | new_error("ForGen", "expecting 'in'") | ||
41 | new_error("LocalFunc", "expecting <name> in local function declaration") | ||
42 | new_error("RetStat", "invalid statement after 'return'") | ||
43 | new_error("ElseIf", "expecting <exp> after 'elseif'") | ||
44 | new_error("SubExpr_1", "malformed 'or' expression") | ||
45 | new_error("SubExpr_2", "malformed 'and' expression") | ||
46 | new_error("SubExpr_3", "malformed relational expression") | ||
47 | new_error("SubExpr_4", "malformed '|' expression") | ||
48 | new_error("SubExpr_5", "malformed '~' expression") | ||
49 | new_error("SubExpr_6", "malformed '&' expression") | ||
50 | new_error("SubExpr_7", "malformed shift expression") | ||
51 | new_error("SubExpr_8", "malformed '..' expression") | ||
52 | new_error("SubExpr_9", "malformed addition expression") | ||
53 | new_error("SubExpr_10", "malformed multiplication expression") | ||
54 | new_error("SubExpr_11", "malformed unary expression") | ||
55 | new_error("SubExpr_12", "malformed '^' expression") | ||
56 | new_error("Stat", "invalid statement") | ||
57 | |||
58 | local labels = {} | ||
59 | for k, v in ipairs(errors) do | ||
60 | labels[v.label] = k | ||
61 | end | ||
62 | |||
63 | return { | ||
64 | errors = errors, | ||
65 | labels = labels, | ||
66 | } | ||
diff --git a/examples/typedlua/tllexer.lua b/examples/typedlua/tllexer.lua new file mode 100644 index 0000000..6517ba5 --- /dev/null +++ b/examples/typedlua/tllexer.lua | |||
@@ -0,0 +1,106 @@ | |||
1 | local tllexer = {} | ||
2 | |||
3 | local lpeg = require "lpeglabel" | ||
4 | lpeg.locale(lpeg) | ||
5 | |||
6 | local tlerror = require "tlerror" | ||
7 | |||
8 | function tllexer.try (pat, label) | ||
9 | return pat + lpeg.T(tlerror.labels[label]) | ||
10 | end | ||
11 | |||
12 | function tllexer.catch (pat, label) | ||
13 | return lpeg.Lc(pat, lpeg.P(false), tlerror.labels[label]) | ||
14 | end | ||
15 | |||
16 | local function setffp (s, i, t, n) | ||
17 | if not t.ffp or i > t.ffp then | ||
18 | t.ffp = i | ||
19 | t.list = {} | ||
20 | t.list[n] = true | ||
21 | t.expected = "'" .. n .. "'" | ||
22 | elseif i == t.ffp then | ||
23 | if not t.list[n] then | ||
24 | t.list[n] = true | ||
25 | t.expected = "'" .. n .. "', " .. t.expected | ||
26 | end | ||
27 | end | ||
28 | return false | ||
29 | end | ||
30 | |||
31 | local function updateffp (name) | ||
32 | return lpeg.Cmt(lpeg.Carg(1) * lpeg.Cc(name), setffp) | ||
33 | end | ||
34 | |||
35 | tllexer.Shebang = lpeg.P("#") * (lpeg.P(1) - lpeg.P("\n"))^0 * lpeg.P("\n") | ||
36 | |||
37 | local Space = lpeg.space^1 | ||
38 | |||
39 | local Equals = lpeg.P("=")^0 | ||
40 | local Open = "[" * lpeg.Cg(Equals, "init") * "[" * lpeg.P("\n")^-1 | ||
41 | local Close = "]" * lpeg.C(Equals) * "]" | ||
42 | local CloseEQ = lpeg.Cmt(Close * lpeg.Cb("init"), | ||
43 | function (s, i, a, b) return a == b end) | ||
44 | |||
45 | local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") / | ||
46 | function (s, o) return s end | ||
47 | |||
48 | local Comment = lpeg.Lc(lpeg.P("--") * LongString / function () return end, | ||
49 | lpeg.T(tlerror.labels["LongComment"]), tlerror.labels["LongString"]) + | ||
50 | lpeg.P("--") * (lpeg.P(1) - lpeg.P("\n"))^0 | ||
51 | |||
52 | tllexer.Skip = (Space + Comment)^0 | ||
53 | |||
54 | local idStart = lpeg.alpha + lpeg.P("_") | ||
55 | local idRest = lpeg.alnum + lpeg.P("_") | ||
56 | |||
57 | local Keywords = lpeg.P("and") + "break" + "do" + "elseif" + "else" + "end" + | ||
58 | "false" + "for" + "function" + "goto" + "if" + "in" + | ||
59 | "local" + "nil" + "not" + "or" + "repeat" + "return" + | ||
60 | "then" + "true" + "until" + "while" | ||
61 | |||
62 | tllexer.Reserved = Keywords * -idRest | ||
63 | |||
64 | local Identifier = idStart * idRest^0 | ||
65 | |||
66 | tllexer.Name = -tllexer.Reserved * Identifier * -idRest | ||
67 | |||
68 | function tllexer.token (pat, name) | ||
69 | return pat * tllexer.Skip + updateffp(name) * lpeg.P(false) | ||
70 | end | ||
71 | |||
72 | function tllexer.symb (str) | ||
73 | return tllexer.token(lpeg.P(str), str) | ||
74 | end | ||
75 | |||
76 | function tllexer.kw (str) | ||
77 | return tllexer.token(lpeg.P(str) * -idRest, str) | ||
78 | end | ||
79 | |||
80 | local Hex = (lpeg.P("0x") + lpeg.P("0X")) * tllexer.try(lpeg.xdigit^1, "Number") | ||
81 | local Expo = lpeg.S("eE") * lpeg.S("+-")^-1 * tllexer.try(lpeg.digit^1, "Number") | ||
82 | local Float = (((lpeg.digit^1 * lpeg.P(".") * lpeg.digit^0 * tllexer.try(-lpeg.P("."), "Number")) + | ||
83 | (lpeg.P(".") * lpeg.digit^1)) * Expo^-1) + | ||
84 | (lpeg.digit^1 * Expo) | ||
85 | local Int = lpeg.digit^1 | ||
86 | |||
87 | tllexer.Number = Hex + Float + Int | ||
88 | |||
89 | local ShortString = lpeg.P('"') * | ||
90 | ((lpeg.P('\\') * lpeg.P(1)) + (lpeg.P(1) - lpeg.P('"')))^0 * | ||
91 | tllexer.try(lpeg.P('"'), "String") + | ||
92 | lpeg.P("'") * | ||
93 | ((lpeg.P("\\") * lpeg.P(1)) + (lpeg.P(1) - lpeg.P("'")))^0 * | ||
94 | tllexer.try(lpeg.P("'"), "String") | ||
95 | |||
96 | tllexer.String = LongString + ShortString | ||
97 | |||
98 | -- for error reporting | ||
99 | tllexer.OneWord = tllexer.Name + | ||
100 | tllexer.Number + | ||
101 | tllexer.String + | ||
102 | tllexer.Reserved + | ||
103 | lpeg.P("...") + | ||
104 | lpeg.P(1) | ||
105 | |||
106 | return tllexer | ||
diff --git a/examples/typedlua/tlp.lua b/examples/typedlua/tlp.lua new file mode 100644 index 0000000..2a4a736 --- /dev/null +++ b/examples/typedlua/tlp.lua | |||
@@ -0,0 +1,20 @@ | |||
1 | local tlparser = require "tlparser" | ||
2 | |||
3 | local function getcontents(filename) | ||
4 | file = assert(io.open(filename, "r")) | ||
5 | contents = file:read("*a") | ||
6 | file:close() | ||
7 | return contents | ||
8 | end | ||
9 | |||
10 | if #arg ~= 1 then | ||
11 | print ("Usage: lua tlp.lua <file>") | ||
12 | os.exit(1) | ||
13 | end | ||
14 | |||
15 | local filename = arg[1] | ||
16 | local subject = getcontents(filename) | ||
17 | local r, msg = tlparser.parse(subject, filename, false, true) | ||
18 | if not r then print(msg) end | ||
19 | |||
20 | os.exit(0) | ||
diff --git a/examples/typedlua/tlparser.lua b/examples/typedlua/tlparser.lua new file mode 100644 index 0000000..a301fa6 --- /dev/null +++ b/examples/typedlua/tlparser.lua | |||
@@ -0,0 +1,245 @@ | |||
1 | local tlparser = {} | ||
2 | |||
3 | local lpeg = require "lpeglabel" | ||
4 | lpeg.locale(lpeg) | ||
5 | |||
6 | local tllexer = require "tllexer" | ||
7 | local tlerror = require "tlerror" | ||
8 | |||
9 | local function chainl1 (pat, sep, label) | ||
10 | return pat * (sep * tllexer.try(pat, label))^0 | ||
11 | end | ||
12 | |||
13 | local G = lpeg.P { "TypedLua"; | ||
14 | TypedLua = tllexer.Shebang^-1 * tllexer.Skip * lpeg.V("Chunk") * tllexer.try(-1, "Stat"); | ||
15 | -- type language | ||
16 | Type = lpeg.V("NilableType"); | ||
17 | NilableType = lpeg.V("UnionType") * tllexer.symb("?")^-1; | ||
18 | UnionType = lpeg.V("PrimaryType") * (tllexer.symb("|") * tllexer.try(lpeg.V("PrimaryType"), "UnionType"))^0; | ||
19 | PrimaryType = lpeg.V("LiteralType") + | ||
20 | lpeg.V("BaseType") + | ||
21 | lpeg.V("NilType") + | ||
22 | lpeg.V("ValueType") + | ||
23 | lpeg.V("AnyType") + | ||
24 | lpeg.V("SelfType") + | ||
25 | lpeg.V("FunctionType") + | ||
26 | lpeg.V("TableType") + | ||
27 | lpeg.V("VariableType"); | ||
28 | LiteralType = tllexer.token("false", "false") + | ||
29 | tllexer.token("true", "true") + | ||
30 | tllexer.token(tllexer.Number, "Number") + | ||
31 | tllexer.token(tllexer.String, "String"); | ||
32 | BaseType = tllexer.token("boolean", "boolean") + | ||
33 | tllexer.token("number", "number") + | ||
34 | tllexer.token("string", "string") + | ||
35 | tllexer.token("integer", "integer"); | ||
36 | NilType = tllexer.token("nil", "nil"); | ||
37 | ValueType = tllexer.token("value", "value"); | ||
38 | AnyType = tllexer.token("any", "any"); | ||
39 | SelfType = tllexer.token("self", "self"); | ||
40 | FunctionType = lpeg.V("InputType") * tllexer.symb("->") * tllexer.try(lpeg.V("NilableTuple"), "FunctionType"); | ||
41 | MethodType = lpeg.V("InputType") * tllexer.symb("=>") * tllexer.try(lpeg.V("NilableTuple"), "MethodType"); | ||
42 | InputType = tllexer.symb("(") * lpeg.V("TupleType")^-1 * tllexer.try(tllexer.symb(")"), "MissingCP"); | ||
43 | NilableTuple = lpeg.V("UnionlistType") * tllexer.symb("?")^-1; | ||
44 | UnionlistType = lpeg.V("OutputType") * (tllexer.symb("|") * tllexer.try(lpeg.V("OutputType"), "UnionType"))^0; | ||
45 | OutputType = tllexer.symb("(") * lpeg.V("TupleType")^-1 * tllexer.try(tllexer.symb(")"), "MissingCP"); | ||
46 | TupleType = lpeg.V("Type") * (tllexer.symb(",") * tllexer.try(lpeg.V("Type"), "TupleType"))^0 * tllexer.symb("*")^-1; | ||
47 | TableType = tllexer.symb("{") * lpeg.V("TableTypeBody")^-1 * tllexer.try(tllexer.symb("}"), "MissingCC"); | ||
48 | TableTypeBody = lpeg.V("RecordType") + | ||
49 | lpeg.V("HashType") + | ||
50 | lpeg.V("ArrayType"); | ||
51 | RecordType = lpeg.V("RecordField") * (tllexer.symb(",") * lpeg.V("RecordField"))^0 * | ||
52 | (tllexer.symb(",") * (lpeg.V("HashType") + lpeg.V("ArrayType")))^-1; | ||
53 | RecordField = tllexer.kw("const")^-1 * | ||
54 | lpeg.V("LiteralType") * tllexer.symb(":") * tllexer.try(lpeg.V("Type"), "Type"); | ||
55 | HashType = lpeg.V("KeyType") * tllexer.symb(":") * tllexer.try(lpeg.V("FieldType"), "Type"); | ||
56 | ArrayType = lpeg.V("FieldType"); | ||
57 | KeyType = lpeg.V("BaseType") + lpeg.V("ValueType") + lpeg.V("AnyType"); | ||
58 | FieldType = lpeg.V("Type"); | ||
59 | VariableType = tllexer.token(tllexer.Name, "Name"); | ||
60 | RetType = lpeg.V("NilableTuple") + | ||
61 | lpeg.V("Type"); | ||
62 | Id = tllexer.token(tllexer.Name, "Name"); | ||
63 | TypeDecId = (tllexer.kw("const") * lpeg.V("Id")) + | ||
64 | lpeg.V("Id"); | ||
65 | IdList = lpeg.V("TypeDecId") * (tllexer.symb(",") * tllexer.try(lpeg.V("TypeDecId"), "TupleType"))^0; | ||
66 | IdDec = lpeg.V("IdList") * tllexer.symb(":") * tllexer.try((lpeg.V("Type") + lpeg.V("MethodType")), "Type"); | ||
67 | IdDecList = (lpeg.V("IdDec")^1)^-1; | ||
68 | TypeDec = tllexer.token(tllexer.Name, "Name") * lpeg.V("IdDecList") * tllexer.try(tllexer.kw("end"), "TypeDecEnd"); | ||
69 | Interface = tllexer.kw("interface") * lpeg.V("TypeDec") + | ||
70 | tllexer.kw("typealias") * | ||
71 | tllexer.try(tllexer.token(tllexer.Name, "Name"), "TypeAliasName") * | ||
72 | tllexer.try(tllexer.symb("="), "MissingEqTypeAlias") * lpeg.V("Type"); | ||
73 | -- parser | ||
74 | Chunk = lpeg.V("Block"); | ||
75 | StatList = (tllexer.symb(";") + lpeg.V("Stat"))^0; | ||
76 | Var = lpeg.V("Id"); | ||
77 | TypedId = tllexer.token(tllexer.Name, "Name") * (tllexer.symb(":") * tllexer.try(lpeg.V("Type"), "Type"))^-1; | ||
78 | FunctionDef = tllexer.kw("function") * lpeg.V("FuncBody"); | ||
79 | FieldSep = tllexer.symb(",") + tllexer.symb(";"); | ||
80 | Field = ((tllexer.symb("[") * lpeg.V("Expr") * tllexer.try(tllexer.symb("]"), "MissingCB")) + | ||
81 | (tllexer.token(tllexer.Name, "Name"))) * | ||
82 | tllexer.symb("=") * lpeg.V("Expr") + | ||
83 | lpeg.V("Expr"); | ||
84 | TField = (tllexer.kw("const") * lpeg.V("Field")) + | ||
85 | lpeg.V("Field"); | ||
86 | FieldList = (lpeg.V("TField") * (lpeg.V("FieldSep") * lpeg.V("TField"))^0 * | ||
87 | lpeg.V("FieldSep")^-1)^-1; | ||
88 | Constructor = tllexer.symb("{") * lpeg.V("FieldList") * tllexer.try(tllexer.symb("}"), "MissingCC"); | ||
89 | NameList = lpeg.V("TypedId") * (tllexer.symb(",") * lpeg.V("TypedId"))^0; | ||
90 | ExpList = lpeg.V("Expr") * (tllexer.symb(",") * lpeg.V("Expr"))^0; | ||
91 | FuncArgs = tllexer.symb("(") * | ||
92 | (lpeg.V("Expr") * (tllexer.symb(",") * lpeg.V("Expr"))^0)^-1 * | ||
93 | tllexer.try(tllexer.symb(")"), "MissingCP") + | ||
94 | lpeg.V("Constructor") + | ||
95 | tllexer.token(tllexer.String, "String"); | ||
96 | OrOp = tllexer.kw("or"); | ||
97 | AndOp = tllexer.kw("and"); | ||
98 | RelOp = tllexer.symb("~=") + | ||
99 | tllexer.symb("==") + | ||
100 | tllexer.symb("<=") + | ||
101 | tllexer.symb(">=") + | ||
102 | tllexer.symb("<") + | ||
103 | tllexer.symb(">"); | ||
104 | BOrOp = tllexer.symb("|"); | ||
105 | BXorOp = tllexer.symb("~") * -lpeg.P("="); | ||
106 | BAndOp = tllexer.symb("&"); | ||
107 | ShiftOp = tllexer.symb("<<") + | ||
108 | tllexer.symb(">>"); | ||
109 | ConOp = tllexer.symb(".."); | ||
110 | AddOp = tllexer.symb("+") + | ||
111 | tllexer.symb("-"); | ||
112 | MulOp = tllexer.symb("*") + | ||
113 | tllexer.symb("//") + | ||
114 | tllexer.symb("/") + | ||
115 | tllexer.symb("%"); | ||
116 | UnOp = tllexer.kw("not") + | ||
117 | tllexer.symb("-") + | ||
118 | tllexer.symb("~") + | ||
119 | tllexer.symb("#"); | ||
120 | PowOp = tllexer.symb("^"); | ||
121 | Expr = lpeg.V("SubExpr_1"); | ||
122 | SubExpr_1 = chainl1(lpeg.V("SubExpr_2"), lpeg.V("OrOp"), "SubExpr_1"); | ||
123 | SubExpr_2 = chainl1(lpeg.V("SubExpr_3"), lpeg.V("AndOp"), "SubExpr_2"); | ||
124 | SubExpr_3 = chainl1(lpeg.V("SubExpr_4"), lpeg.V("RelOp"), "SubExpr_3"); | ||
125 | SubExpr_4 = chainl1(lpeg.V("SubExpr_5"), lpeg.V("BOrOp"), "SubExpr_4"); | ||
126 | SubExpr_5 = chainl1(lpeg.V("SubExpr_6"), lpeg.V("BXorOp"), "SubExpr_5"); | ||
127 | SubExpr_6 = chainl1(lpeg.V("SubExpr_7"), lpeg.V("BAndOp"), "SubExpr_6"); | ||
128 | SubExpr_7 = chainl1(lpeg.V("SubExpr_8"), lpeg.V("ShiftOp"), "SubExpr_7"); | ||
129 | SubExpr_8 = lpeg.V("SubExpr_9") * lpeg.V("ConOp") * tllexer.try(lpeg.V("SubExpr_8"), "SubExpr_8") + | ||
130 | lpeg.V("SubExpr_9"); | ||
131 | SubExpr_9 = chainl1(lpeg.V("SubExpr_10"), lpeg.V("AddOp"), "SubExpr_9"); | ||
132 | SubExpr_10 = chainl1(lpeg.V("SubExpr_11"), lpeg.V("MulOp"), "SubExpr_10"); | ||
133 | SubExpr_11 = lpeg.V("UnOp") * tllexer.try(lpeg.V("SubExpr_11"), "SubExpr_11") + | ||
134 | lpeg.V("SubExpr_12"); | ||
135 | SubExpr_12 = lpeg.V("SimpleExp") * (lpeg.V("PowOp") * tllexer.try(lpeg.V("SubExpr_11"), "SubExpr_12"))^-1; | ||
136 | SimpleExp = tllexer.token(tllexer.Number, "Number") + | ||
137 | tllexer.token(tllexer.String, "String") + | ||
138 | tllexer.kw("nil") + | ||
139 | tllexer.kw("false") + | ||
140 | tllexer.kw("true") + | ||
141 | tllexer.symb("...") + | ||
142 | lpeg.V("FunctionDef") + | ||
143 | lpeg.V("Constructor") + | ||
144 | lpeg.V("SuffixedExp"); | ||
145 | SuffixedExp = lpeg.V("PrimaryExp") * ( | ||
146 | (tllexer.symb(".") * tllexer.try(tllexer.token(tllexer.Name, "Name"), "DotIndex")) / "index" + | ||
147 | (tllexer.symb("[") * lpeg.V("Expr") * tllexer.try(tllexer.symb("]"), "MissingCB")) / "index" + | ||
148 | (tllexer.symb(":") * tllexer.try(tllexer.token(tllexer.Name, "Name"), "MethodName") * tllexer.try(lpeg.V("FuncArgs"), "MethodCall")) / "call" + | ||
149 | lpeg.V("FuncArgs") / "call")^0 / function (...) local l = {...}; return l[#l] end; | ||
150 | PrimaryExp = lpeg.V("Var") / "var" + | ||
151 | tllexer.symb("(") * lpeg.V("Expr") * tllexer.try(tllexer.symb(")"), "MissingCP"); | ||
152 | Block = lpeg.V("StatList") * lpeg.V("RetStat")^-1; | ||
153 | IfStat = tllexer.kw("if") * lpeg.V("Expr") * tllexer.try(tllexer.kw("then"), "Then") * lpeg.V("Block") * | ||
154 | (tllexer.kw("elseif") * tllexer.try(lpeg.V("Expr"), "ElseIf") * tllexer.try(tllexer.kw("then"), "Then") * lpeg.V("Block"))^0 * | ||
155 | (tllexer.kw("else") * lpeg.V("Block"))^-1 * | ||
156 | tllexer.try(tllexer.kw("end"), "IfEnd"); | ||
157 | WhileStat = tllexer.kw("while") * lpeg.V("Expr") * | ||
158 | tllexer.try(tllexer.kw("do"), "WhileDo") * lpeg.V("Block") * tllexer.try(tllexer.kw("end"), "WhileEnd"); | ||
159 | DoStat = tllexer.kw("do") * lpeg.V("Block") * tllexer.try(tllexer.kw("end"), "BlockEnd"); | ||
160 | ForBody = tllexer.try(tllexer.kw("do"), "ForDo") * lpeg.V("Block"); | ||
161 | ForNum = lpeg.V("Id") * tllexer.symb("=") * lpeg.V("Expr") * tllexer.symb(",") * | ||
162 | lpeg.V("Expr") * (tllexer.symb(",") * lpeg.V("Expr"))^-1 * | ||
163 | lpeg.V("ForBody"); | ||
164 | ForGen = lpeg.V("NameList") * tllexer.try(tllexer.kw("in"), "ForGen") * | ||
165 | lpeg.V("ExpList") * lpeg.V("ForBody"); | ||
166 | ForStat = tllexer.kw("for") * (lpeg.V("ForNum") + lpeg.V("ForGen")) * tllexer.try(tllexer.kw("end"), "ForEnd"); | ||
167 | RepeatStat = tllexer.kw("repeat") * lpeg.V("Block") * | ||
168 | tllexer.try(tllexer.kw("until"), "Until") * lpeg.V("Expr"); | ||
169 | FuncName = lpeg.V("Id") * (tllexer.symb(".") * | ||
170 | (tllexer.token(tllexer.Name, "Name")))^0 * | ||
171 | (tllexer.symb(":") * (tllexer.token(tllexer.Name, "Name")))^-1; | ||
172 | ParList = lpeg.V("NameList") * (tllexer.symb(",") * tllexer.try(lpeg.V("TypedVarArg"), "ParList"))^-1 + | ||
173 | lpeg.V("TypedVarArg"); | ||
174 | TypedVarArg = tllexer.symb("...") * (tllexer.symb(":") * tllexer.try(lpeg.V("Type"), "Type"))^-1; | ||
175 | FuncBody = tllexer.try(tllexer.symb("("), "MissingOP") * lpeg.V("ParList")^-1 * tllexer.try(tllexer.symb(")"), "MissingCP") * | ||
176 | (tllexer.symb(":") * tllexer.try(lpeg.V("RetType"), "Type"))^-1 * | ||
177 | lpeg.V("Block") * tllexer.try(tllexer.kw("end"), "FuncEnd"); | ||
178 | FuncStat = tllexer.kw("const")^-1 * | ||
179 | tllexer.kw("function") * lpeg.V("FuncName") * lpeg.V("FuncBody"); | ||
180 | LocalFunc = tllexer.kw("function") * | ||
181 | tllexer.try(lpeg.V("Id"), "LocalFunc") * lpeg.V("FuncBody"); | ||
182 | LocalAssign = lpeg.V("NameList") * tllexer.symb("=") * tllexer.try(lpeg.V("ExpList"), "LocalAssign1") + | ||
183 | lpeg.V("NameList") * (#(-tllexer.symb("=") * (lpeg.V("Stat") + -1)) * lpeg.P(true)) + lpeg.T(tlerror.labels["LocalAssign2"]); | ||
184 | LocalStat = tllexer.kw("local") * | ||
185 | (lpeg.V("LocalTypeDec") + lpeg.V("LocalFunc") + lpeg.V("LocalAssign")); | ||
186 | LabelStat = tllexer.symb("::") * tllexer.try(tllexer.token(tllexer.Name, "Name"), "Label1") * tllexer.try(tllexer.symb("::"), "Label2"); | ||
187 | BreakStat = tllexer.kw("break"); | ||
188 | GoToStat = tllexer.kw("goto") * tllexer.token(tllexer.Name, "Name"); | ||
189 | RetStat = tllexer.kw("return") * tllexer.try(-lpeg.V("Stat"), "RetStat") * | ||
190 | (lpeg.V("Expr") * (tllexer.symb(",") * lpeg.V("Expr"))^0)^-1 * | ||
191 | tllexer.symb(";")^-1; | ||
192 | TypeDecStat = lpeg.V("Interface"); | ||
193 | LocalTypeDec = lpeg.V("TypeDecStat"); | ||
194 | LVar = (tllexer.kw("const") * lpeg.V("SuffixedExp")) + | ||
195 | lpeg.V("SuffixedExp"); | ||
196 | ExprStat = lpeg.Cmt(lpeg.V("LVar") * lpeg.V("Assignment"), | ||
197 | function (s, i, ...) | ||
198 | local l = {...} | ||
199 | local i = 1 | ||
200 | while l[i] ~= "=" do | ||
201 | local se = l[i] | ||
202 | if se ~= "var" and se ~= "index" then return false end | ||
203 | i = i + 1 | ||
204 | end | ||
205 | return true | ||
206 | end) + | ||
207 | lpeg.Cmt(lpeg.V("SuffixedExp"), | ||
208 | function (s, i, se) | ||
209 | if se ~= "call" then return false end | ||
210 | return true | ||
211 | end); | ||
212 | Assignment = ((tllexer.symb(",") * lpeg.V("LVar"))^1)^-1 * (tllexer.symb("=") / "=") * lpeg.V("ExpList"); | ||
213 | Stat = lpeg.V("IfStat") + lpeg.V("WhileStat") + lpeg.V("DoStat") + lpeg.V("ForStat") + | ||
214 | lpeg.V("RepeatStat") + lpeg.V("FuncStat") + lpeg.V("LocalStat") + | ||
215 | lpeg.V("LabelStat") + lpeg.V("BreakStat") + lpeg.V("GoToStat") + | ||
216 | lpeg.V("TypeDecStat") + lpeg.V("ExprStat"); | ||
217 | } | ||
218 | |||
219 | local function lineno (s, i) | ||
220 | if i == 1 then return 1, 1 end | ||
221 | local rest, num = s:sub(1,i):gsub("[^\n]*\n", "") | ||
222 | local r = #rest | ||
223 | return 1 + num, r ~= 0 and r or 1 | ||
224 | end | ||
225 | |||
226 | function tlparser.parse (subject, filename, strict, integer) | ||
227 | local errorinfo = {} | ||
228 | lpeg.setmaxstack(1000) | ||
229 | local ast, label, suffix = lpeg.match(G, subject, nil, errorinfo, strict, integer) | ||
230 | if not ast then | ||
231 | local line, col = lineno(subject, string.len(subject) - string.len(suffix)) | ||
232 | local error_msg = string.format("%s:%d:%d: ", filename, line, col) | ||
233 | if label ~= 0 then | ||
234 | error_msg = error_msg .. tlerror.errors[label].msg | ||
235 | else | ||
236 | local u = lpeg.match(lpeg.C(tllexer.OneWord) + lpeg.Cc("EOF"), subject, errorinfo.ffp) | ||
237 | error_msg = error_msg .. string.format("unexpected '%s', expecting %s", u, errorinfo.expected) | ||
238 | end | ||
239 | return nil, error_msg | ||
240 | else | ||
241 | return true | ||
242 | end | ||
243 | end | ||
244 | |||
245 | return tlparser | ||