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