aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/listId2.lua16
-rw-r--r--examples/listId2Rec2Cap.lua20
-rw-r--r--examples/listId3.lua35
-rw-r--r--examples/tiny.lua5
-rw-r--r--examples/toast.lua16
-rwxr-xr-xexamples/typedlua/test.lua2572
-rw-r--r--examples/typedlua/tlerror.lua66
-rw-r--r--examples/typedlua/tllexer.lua105
-rw-r--r--examples/typedlua/tlp.lua20
-rw-r--r--examples/typedlua/tlparser.lua245
10 files changed, 73 insertions, 3027 deletions
diff --git a/examples/listId2.lua b/examples/listId2.lua
index 322d432..dc30ce5 100644
--- a/examples/listId2.lua
+++ b/examples/listId2.lua
@@ -3,19 +3,19 @@ local re = require'relabel'
3 3
4local terror = { 4local terror = {
5 ErrId = "expecting an identifier", 5 ErrId = "expecting an identifier",
6 ErrComma = "expecting ','", 6 ErrEnd = "expecting EOF",
7 fail = "undefined" 7 fail = "undefined"
8} 8}
9 9
10local id = m.R'az'^1 10local id = m.R'az'^1
11 11
12local g = m.P{ 12local g = m.P{
13 "S", 13 'S',
14 S = m.V"Id" * m.V"List", 14 S = m.V'List' * (-m.P(1) + m.T'ErrEnd'),
15 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List", 15 List = m.V'Id' * (m.V'Comma' * (m.V'Id' + m.T'ErrId'))^0,
16 Id = m.V"Sp" * id + m.T'ErrId', 16 Id = m.V'Sp' * id,
17 Comma = m.V"Sp" * "," + m.T'ErrComma', 17 Comma = m.V'Sp' * ',',
18 Sp = m.S" \n\t"^0, 18 Sp = m.S' \n\t'^0,
19} 19}
20 20
21 21
@@ -31,4 +31,4 @@ end
31 31
32print(mymatch(g, "one,two")) 32print(mymatch(g, "one,two"))
33print(mymatch(g, "one two")) 33print(mymatch(g, "one two"))
34print(mymatch(g, "one,\n two,\nthree,")) 34print(mymatch(g, "one,\n two,\nthree,4"))
diff --git a/examples/listId2Rec2Cap.lua b/examples/listId2Rec2Cap.lua
index 7fbe700..952540a 100644
--- a/examples/listId2Rec2Cap.lua
+++ b/examples/listId2Rec2Cap.lua
@@ -3,7 +3,9 @@ local re = require'relabel'
3 3
4local terror = { 4local terror = {
5 ErrId = "expecting an identifier", 5 ErrId = "expecting an identifier",
6 ErrComma = "expecting ','" 6 ErrComma = "expecting ','",
7 ErrList = "expecting a list of identifiers",
8 fail = "undefined"
7} 9}
8 10
9local subject, errors 11local subject, errors
@@ -29,16 +31,16 @@ local id = m.R'az'^1
29 31
30local g = m.P{ 32local g = m.P{
31 "S", 33 "S",
32 S = m.V"Id" * m.V"List", 34 S = m.V"List" + (m.P(1) * m.T'ErrList'),
33 List = -m.P(1) + m.V"Comma" * m.V"Id" * m.V"List", 35 List = m.V'Id' * (#m.P(1) * m.V'Comma' * (m.V'Id' + m.T'ErrId'))^0,
34 Id = m.V"Sp" * m.C(id) + m.T'ErrId', 36 Id = m.V'Sp' * m.C(id),
35 Comma = m.V"Sp" * "," + m.T'ErrComma', 37 Comma = m.V'Sp' * ',' + m.T'ErrComma',
36 Sp = m.S" \n\t"^0, 38 Sp = m.S' \n\t'^0,
37 ErrId = record('ErrId') * sync(m.P",") * defaultValue(), 39 ErrId = record'ErrId' * sync(m.P",") * defaultValue(),
38 ErrComma = record('ErrComma') * sync(id), 40 ErrComma = record'ErrComma' * sync(id),
41 ErrList = record'ErrList' * sync(m.P(-1)) * defaultValue()
39} 42}
40 43
41
42function mymatch (g, s) 44function mymatch (g, s)
43 errors = {} 45 errors = {}
44 subject = s 46 subject = s
diff --git a/examples/listId3.lua b/examples/listId3.lua
new file mode 100644
index 0000000..03da97d
--- /dev/null
+++ b/examples/listId3.lua
@@ -0,0 +1,35 @@
1local m = require'lpeglabel'
2local re = require'relabel'
3
4local terror = {
5 ErrId = "expecting an identifier",
6 ErrComma = "expecting ','",
7 fail = "undefined"
8}
9
10local id = m.R'az'^1
11
12local g = m.P{
13 'S',
14 S = m.V'List',
15 List = m.V'Id' * (#m.P(1) * m.V'Comma' * (m.V'Id' + m.T'ErrId'))^0,
16 Id = m.V'Sp' * id,
17 Comma = m.V'Sp' * ',' + m.T'ErrComma',
18 Sp = m.S' \n\t'^0,
19}
20
21
22function mymatch (g, s)
23 local r, e, pos = g:match(s)
24 if not r then
25 local line, col = re.calcline(s, pos)
26 local msg = "Error at line " .. line .. " (col " .. col .. "): "
27 return r, msg .. terror[e] .. " before '" .. s:sub(pos) .. "'"
28 end
29 return r
30end
31
32print(mymatch(g, "one,two"))
33print(mymatch(g, "one two"))
34print(mymatch(g, "one,\n two,\nthree,4"))
35print(mymatch(g, " 1,2"))
diff --git a/examples/tiny.lua b/examples/tiny.lua
index fe0bced..7548995 100644
--- a/examples/tiny.lua
+++ b/examples/tiny.lua
@@ -19,11 +19,12 @@ local terror = {
19 factor = "Error matching 'Factor'", 19 factor = "Error matching 'Factor'",
20 openParExp = "Error matching expression after '('", 20 openParExp = "Error matching expression after '('",
21 closePar = "Error matching ')'", 21 closePar = "Error matching ')'",
22 eof = "Error, expecting EOF",
22 undefined = "Undefined Error" 23 undefined = "Undefined Error"
23} 24}
24 25
25g = re.compile([[ 26g = re.compile([[
26 Tiny <- CmdSeq^undefined 27 Tiny <- CmdSeq (!. / %{eof})
27 CmdSeq <- (Cmd SEMICOLON^cmdSeq) (Cmd SEMICOLON^cmdSeq)* 28 CmdSeq <- (Cmd SEMICOLON^cmdSeq) (Cmd SEMICOLON^cmdSeq)*
28 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd 29 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd
29 IfCmd <- IF Exp^ifExp THEN^ifThen CmdSeq^ifThenCmdSeq (ELSE CmdSeq^ifElseCmdSeq / '') END^ifEnd 30 IfCmd <- IF Exp^ifExp THEN^ifThen CmdSeq^ifThenCmdSeq (ELSE CmdSeq^ifElseCmdSeq / '') END^ifEnd
@@ -118,5 +119,5 @@ repeat
118print(mymatch(g, s)) 119print(mymatch(g, s))
119 120
120print(mymatch(g, "a : 2")) 121print(mymatch(g, "a : 2"))
121print(mymatch(g, "a := (2")) 122print(mymatch(g, "a := 2; 6"))
122 123
diff --git a/examples/toast.lua b/examples/toast.lua
new file mode 100644
index 0000000..c355642
--- /dev/null
+++ b/examples/toast.lua
@@ -0,0 +1,16 @@
1local m = require'lpeglabel'
2
3local recp = m.P"oast"
4
5local g = m.P{
6 'S',
7 S = m.V'A' * '.',
8 A = m.P't' * (m.P'est' + m.T'Err'),
9 Err = m.P'oast'
10}
11
12print(g:match("test.")) --> 6
13print(g:match("toast.")) --> 7
14print(g:match("oast.")) --> nil 0 oast.
15print(g:match("toward.")) --> nil 0 ward.
16
diff --git a/examples/typedlua/test.lua b/examples/typedlua/test.lua
deleted file mode 100755
index 95474ba..0000000
--- a/examples/typedlua/test.lua
+++ /dev/null
@@ -1,2572 +0,0 @@
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--[[
405
406testing
407unfinished
408
409comment
410 ]=]
411--[=[
412test.lua:3:1: syntax error, unexpected 'comment', expecting '=', ',', 'String', '{', '(', ':', '[', '.'
413]=]
414e = [=[
415test.lua:1:2: unfinished long comment
416]=]
417
418r, m = parse(s)
419assert(m == e)
420
421print("> testing parser...")
422
423-- syntax ok
424
425-- anonymous functions
426
427s = [=[
428local a,b,c = function () end
429]=]
430--[=[
431{ `Local{ { `Id "a", `Id "b", `Id "c" }, { `Function{ { }, { } } } } }
432]=]
433
434r, m = parse(s)
435assert(r == true)
436
437s = [=[
438local test = function ( a , b , ... ) end
439]=]
440--[=[
441{ `Local{ { `Id "test" }, { `Function{ { `Id "a", `Id "b", `Dots }, { } } } } }
442]=]
443
444r, m = parse(s)
445assert(r == true)
446
447s = [=[
448local test = function (...) return ...,0 end
449]=]
450--[=[
451{ `Local{ { `Id "test" }, { `Function{ { `Dots }, { `Return{ `Dots, `Number "0" } } } } } }
452]=]
453
454r, m = parse(s)
455assert(r == true)
456
457-- arithmetic expressions
458
459s = [=[
460local arithmetic = 1 - 2 * 3 + 4
461]=]
462--[=[
463{ `Local{ { `Id "arithmetic" }, { `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" } } } }
464]=]
465
466r, m = parse(s)
467assert(r == true)
468
469s = [=[
470local pow = -3^-2^2
471]=]
472--[=[
473{ `Local{ { `Id "pow" }, { `Op{ "unm", `Op{ "pow", `Number "3", `Op{ "unm", `Op{ "pow", `Number "2", `Number "2" } } } } } } }
474]=]
475
476r, m = parse(s)
477assert(r == true)
478
479s = [=[
480q, r, f = 3//2, 3%2, 3/2
481]=]
482--[=[
483{ `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" } } } }
484]=]
485
486r, m = parse(s)
487assert(r == true)
488
489-- assignments
490
491s = [=[
492a = f()[1]
493]=]
494--[=[
495{ `Set{ { `Index{ `Id "_ENV", `String "a" } }, { `Index{ `Call{ `Index{ `Id "_ENV", `String "f" } }, `Number "1" } } } }
496]=]
497
498r, m = parse(s)
499assert(r == true)
500
501s = [=[
502a()[1] = 1;
503]=]
504--[=[
505{ `Set{ { `Index{ `Call{ `Index{ `Id "_ENV", `String "a" } }, `Number "1" } }, { `Number "1" } } }
506]=]
507
508r, m = parse(s)
509assert(r == true)
510
511s = [=[
512i = a.f(1)
513]=]
514--[=[
515{ `Set{ { `Index{ `Id "_ENV", `String "i" } }, { `Call{ `Index{ `Index{ `Id "_ENV", `String "a" }, `String "f" }, `Number "1" } } } }
516]=]
517
518r, m = parse(s)
519assert(r == true)
520
521s = [=[
522i = a[f(1)]
523]=]
524--[=[
525{ `Set{ { `Index{ `Id "_ENV", `String "i" } }, { `Index{ `Index{ `Id "_ENV", `String "a" }, `Call{ `Index{ `Id "_ENV", `String "f" }, `Number "1" } } } } }
526]=]
527
528r, m = parse(s)
529assert(r == true)
530
531s = [=[
532a[f()] = sub
533i = i + 1
534]=]
535--[=[
536{ `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" } } } }
537]=]
538
539r, m = parse(s)
540assert(r == true)
541
542s = [=[
543a:b(1)._ = some_value
544]=]
545--[=[
546{ `Set{ { `Index{ `Invoke{ `Index{ `Id "_ENV", `String "a" }, `String "b", `Number "1" }, `String "_" } }, { `Index{ `Id "_ENV", `String "some_value" } } } }
547]=]
548
549r, m = parse(s)
550assert(r == true)
551
552-- bitwise expressions
553
554s = [=[
555b = 1 & 0 | 1 ~ 1
556]=]
557--[=[
558{ `Set{ { `Index{ `Id "_ENV", `String "b" } }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Number "1", `Number "1" } } } } }
559]=]
560
561r, m = parse(s)
562assert(r == true)
563
564s = [=[
565b = 1 & 0 | 1 >> 1 ~ 1
566]=]
567--[=[
568{ `Set{ { `Index{ `Id "_ENV", `String "b" } }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Op{ "shr", `Number "1", `Number "1" }, `Number "1" } } } } }
569]=]
570
571r, m = parse(s)
572assert(r == true)
573
574-- break
575
576s = [=[
577while 1 do
578 break
579end
580]=]
581--[=[
582{ `While{ `Number "1", { `Break } } }
583]=]
584
585r, m = parse(s)
586assert(r == true)
587
588s = [=[
589while 1 do
590 while 1 do
591 break
592 end
593 break
594end
595]=]
596--[=[
597{ `While{ `Number "1", { `While{ `Number "1", { `Break } }, `Break } } }
598]=]
599
600r, m = parse(s)
601assert(r == true)
602
603s = [=[
604repeat
605 if 2 > 1 then break end
606until 1
607]=]
608--[=[
609{ `Repeat{ { `If{ `Op{ "lt", `Number "1", `Number "2" }, { `Break } } }, `Number "1" } }
610]=]
611
612r, m = parse(s)
613assert(r == true)
614
615s = [=[
616for i=1,10 do
617 do
618 break
619 break
620 return
621 end
622end
623]=]
624--[=[
625{ `Fornum{ `Id "i", `Number "1", `Number "10", { `Do{ `Break, `Break, `Return } } } }
626]=]
627
628r, m = parse(s)
629assert(r == true)
630
631-- block statements
632
633s = [=[
634do
635 local var = 2+2;
636 return
637end
638]=]
639--[=[
640{ `Do{ `Local{ { `Id "var" }, { `Op{ "add", `Number "2", `Number "2" } } }, `Return } }
641]=]
642
643r, m = parse(s)
644assert(r == true)
645
646-- calls
647
648s = [=[
649f()
650t:m()
651]=]
652--[=[
653{ `Call{ `Index{ `Id "_ENV", `String "f" } }, `Invoke{ `Index{ `Id "_ENV", `String "t" }, `String "m" } }
654]=]
655
656r, m = parse(s)
657assert(r == true)
658
659-- concatenation expressions
660
661s = [=[
662local concat1 = 1 .. 2^3
663]=]
664--[=[
665{ `Local{ { `Id "concat1" }, { `Op{ "concat", `Number "1", `Op{ "pow", `Number "2", `Number "3" } } } } }
666]=]
667
668r, m = parse(s)
669assert(r == true)
670
671-- empty files
672
673s = [=[
674;
675]=]
676--[=[
677{ }
678]=]
679
680r, m = parse(s)
681assert(r == true)
682
683-- for generic
684
685s = [=[
686for k,v in pairs(t) do print (k,v) end
687]=]
688--[=[
689{ `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" } } } }
690]=]
691
692r, m = parse(s)
693assert(r == true)
694
695-- for numeric
696
697s = [=[
698for i = 1 , 10 , 2 do end
699]=]
700--[=[
701{ `Fornum{ `Id "i", `Number "1", `Number "10", `Number "2", { } } }
702]=]
703
704r, m = parse(s)
705assert(r == true)
706
707s = [=[
708for i=1,10 do end
709]=]
710--[=[
711{ `Fornum{ `Id "i", `Number "1", `Number "10", { } } }
712]=]
713
714r, m = parse(s)
715assert(r == true)
716
717-- global functions
718
719s = [=[
720function test(a , b , ...) end
721]=]
722--[=[
723{ `Set{ { `Index{ `Id "_ENV", `String "test" } }, { `Function{ { `Id "a", `Id "b", `Dots }, { } } } } }
724]=]
725
726r, m = parse(s)
727assert(r == true)
728
729s = [=[
730function test (...) end
731]=]
732--[=[
733{ `Set{ { `Index{ `Id "_ENV", `String "test" } }, { `Function{ { `Dots }, { } } } } }
734]=]
735
736r, m = parse(s)
737assert(r == true)
738
739s = [=[
740function t.a:b() end
741]=]
742--[=[
743{ `Set{ { `Index{ `Index{ `Index{ `Id "_ENV", `String "t" }, `String "a" }, `String "b" } }, { `Function{ { `Id "self" }, { } } } } }
744]=]
745
746r, m = parse(s)
747assert(r == true)
748
749s = [=[
750function t.a() end
751]=]
752--[=[
753{ `Set{ { `Index{ `Index{ `Id "_ENV", `String "t" }, `String "a" } }, { `Function{ { }, { } } } } }
754]=]
755
756r, m = parse(s)
757assert(r == true)
758
759s = [=[
760function testando . funcao . com : espcacos ( e, com , parametros, ... ) end
761]=]
762--[=[
763{ `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 }, { } } } } }
764]=]
765
766r, m = parse(s)
767assert(r == true)
768
769-- goto
770
771s = [=[
772goto label
773:: label :: return
774]=]
775--[=[
776{ `Goto{ "label" }, `Label{ "label" }, `Return }
777]=]
778
779r, m = parse(s)
780assert(r == true)
781
782s = [=[
783::label::
784goto label
785]=]
786--[=[
787{ `Label{ "label" }, `Goto{ "label" } }
788]=]
789
790r, m = parse(s)
791assert(r == true)
792
793s = [=[
794goto label
795::label::
796]=]
797--[=[
798{ `Goto{ "label" }, `Label{ "label" } }
799]=]
800
801r, m = parse(s)
802assert(r == true)
803
804s = [=[
805::label::
806do ::label:: goto label end
807]=]
808--[=[
809{ `Label{ "label" }, `Do{ `Label{ "label" }, `Goto{ "label" } } }
810]=]
811
812r, m = parse(s)
813assert(r == true)
814
815s = [=[
816::label::
817do goto label ; ::label:: end
818]=]
819--[=[
820{ `Label{ "label" }, `Do{ `Goto{ "label" }, `Label{ "label" } } }
821]=]
822
823r, m = parse(s)
824assert(r == true)
825
826s = [=[
827::label::
828do goto label end
829]=]
830--[=[
831{ `Label{ "label" }, `Do{ `Goto{ "label" } } }
832]=]
833
834r, m = parse(s)
835assert(r == true)
836
837s = [=[
838do goto label end
839::label::
840]=]
841--[=[
842{ `Do{ `Goto{ "label" } }, `Label{ "label" } }
843]=]
844
845r, m = parse(s)
846assert(r == true)
847
848s = [=[
849do do do do do goto label end end end end end
850::label::
851]=]
852--[=[
853{ `Do{ `Do{ `Do{ `Do{ `Do{ `Goto{ "label" } } } } } }, `Label{ "label" } }
854]=]
855
856r, m = parse(s)
857assert(r == true)
858
859-- if-else
860
861s = [=[
862if a then end
863]=]
864--[=[
865{ `If{ `Index{ `Id "_ENV", `String "a" }, { } } }
866]=]
867
868r, m = parse(s)
869assert(r == true)
870
871s = [=[
872if a then return a else return end
873]=]
874--[=[
875{ `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, { `Return } } }
876]=]
877
878r, m = parse(s)
879assert(r == true)
880
881s = [=[
882if a then
883 return a
884else
885 local c = d
886 d = d + 1
887 return d
888end
889]=]
890--[=[
891{ `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" } } } } }
892]=]
893
894r, m = parse(s)
895assert(r == true)
896
897s = [=[
898if a then
899 return a
900elseif b then
901 return b
902elseif c then
903 return c
904end
905]=]
906--[=[
907{ `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" } } } } }
908]=]
909
910r, m = parse(s)
911assert(r == true)
912
913s = [=[
914if a then return a
915elseif b then return
916else ;
917end
918]=]
919--[=[
920{ `If{ `Index{ `Id "_ENV", `String "a" }, { `Return{ `Index{ `Id "_ENV", `String "a" } } }, `Index{ `Id "_ENV", `String "b" }, { `Return }, { } } }
921]=]
922
923r, m = parse(s)
924assert(r == true)
925
926s = [=[
927if a then
928 return
929elseif c then
930end
931]=]
932--[=[
933{ `If{ `Index{ `Id "_ENV", `String "a" }, { `Return }, `Index{ `Id "_ENV", `String "c" }, { } } }
934]=]
935
936r, m = parse(s)
937assert(r == true)
938
939-- interfaces
940
941s = [=[
942local interface Empty end
943]=]
944--[=[
945{ `Interface{ Empty, `TTable{ } } }
946]=]
947
948r, m = parse(s)
949assert(r == true)
950
951s = [=[
952local interface X
953 x, y, z:number
954end
955]=]
956--[=[
957{ `Interface{ X, `TTable{ `TLiteral x:`TBase number, `TLiteral y:`TBase number, `TLiteral z:`TBase number } } }
958]=]
959
960r, m = parse(s)
961assert(r == true)
962
963s = [=[
964local interface Person
965 firstname:string
966 lastname:string
967end
968]=]
969--[=[
970{ `Interface{ Person, `TTable{ `TLiteral firstname:`TBase string, `TLiteral lastname:`TBase string } } }
971]=]
972
973r, m = parse(s)
974assert(r == true)
975
976s = [=[
977local interface Element
978 info:number
979 next:Element?
980end
981]=]
982--[=[
983{ `Interface{ Element, `TRecursive{ Element, `TTable{ `TLiteral info:`TBase number, `TLiteral next:`TUnion{ `TVariable Element, `TNil } } } } }
984]=]
985
986r, m = parse(s)
987assert(r == true)
988
989-- labels
990
991s = [=[
992::label::
993do ::label:: end
994::other_label::
995]=]
996--[=[
997{ `Label{ "label" }, `Do{ `Label{ "label" } }, `Label{ "other_label" } }
998]=]
999
1000r, m = parse(s)
1001assert(r == true)
1002
1003-- locals
1004
1005s = [=[
1006local a
1007]=]
1008--[=[
1009{ `Local{ { `Id "a" }, { } } }
1010]=]
1011
1012r, m = parse(s)
1013assert(r == true)
1014
1015s = [=[
1016local a,b,c
1017]=]
1018--[=[
1019{ `Local{ { `Id "a", `Id "b", `Id "c" }, { } } }
1020]=]
1021
1022r, m = parse(s)
1023assert(r == true)
1024
1025s = [=[
1026local a = 1 , 1 + 2, 5.1
1027]=]
1028--[=[
1029{ `Local{ { `Id "a" }, { `Number "1", `Op{ "add", `Number "1", `Number "2" }, `Number "5.1" } } }
1030]=]
1031
1032r, m = parse(s)
1033assert(r == true)
1034
1035s = [=[
1036local a,b,c = 1.9
1037]=]
1038--[=[
1039{ `Local{ { `Id "a", `Id "b", `Id "c" }, { `Number "1.9" } } }
1040]=]
1041
1042r, m = parse(s)
1043assert(r == true)
1044
1045s = [=[
1046local function test() end
1047]=]
1048--[=[
1049{ `Localrec{ { `Id "test" }, { `Function{ { }, { } } } } }
1050]=]
1051
1052r, m = parse(s)
1053assert(r == true)
1054
1055s = [=[
1056local function test ( a , b , c , ... ) end
1057]=]
1058--[=[
1059{ `Localrec{ { `Id "test" }, { `Function{ { `Id "a", `Id "b", `Id "c", `Dots }, { } } } } }
1060]=]
1061
1062r, m = parse(s)
1063assert(r == true)
1064
1065s = [=[
1066local function test(...) return ... end
1067]=]
1068--[=[
1069{ `Localrec{ { `Id "test" }, { `Function{ { `Dots }, { `Return{ `Dots } } } } } }
1070]=]
1071
1072r, m = parse(s)
1073assert(r == true)
1074
1075-- relational expressions
1076
1077s = [=[
1078local relational = 1 < 2 >= 3 == 4 ~= 5 < 6 <= 7
1079]=]
1080--[=[
1081{ `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" } } } }
1082]=]
1083
1084r, m = parse(s)
1085assert(r == true)
1086
1087-- repeat
1088
1089s = [=[
1090repeat
1091 local a,b,c = 1+1,2+2,3+3
1092 break
1093until a < 1
1094]=]
1095--[=[
1096{ `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" } } }
1097]=]
1098
1099r, m = parse(s)
1100assert(r == true)
1101
1102-- return
1103
1104s = [=[
1105return
1106]=]
1107--[=[
1108{ `Return }
1109]=]
1110
1111r, m = parse(s)
1112assert(r == true)
1113
1114s = [=[
1115return 1
1116]=]
1117--[=[
1118{ `Return{ `Number "1" } }
1119]=]
1120
1121r, m = parse(s)
1122assert(r == true)
1123
1124s = [=[
1125return 1,1-2*3+4,"alo"
1126]=]
1127--[=[
1128{ `Return{ `Number "1", `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" }, `String "alo" } }
1129]=]
1130
1131r, m = parse(s)
1132assert(r == true)
1133
1134s = [=[
1135return;
1136]=]
1137--[=[
1138{ `Return }
1139]=]
1140
1141r, m = parse(s)
1142assert(r == true)
1143
1144s = [=[
1145return 1;
1146]=]
1147--[=[
1148{ `Return{ `Number "1" } }
1149]=]
1150
1151r, m = parse(s)
1152assert(r == true)
1153
1154s = [=[
1155return 1,1-2*3+4,"alo";
1156]=]
1157--[=[
1158{ `Return{ `Number "1", `Op{ "add", `Op{ "sub", `Number "1", `Op{ "mul", `Number "2", `Number "3" } }, `Number "4" }, `String "alo" } }
1159]=]
1160
1161r, m = parse(s)
1162assert(r == true)
1163
1164-- tables
1165
1166s = [=[
1167local t = { [1] = "alo", alo = 1, 2; }
1168]=]
1169--[=[
1170{ `Local{ { `Id "t" }, { `Table{ `Pair{ `Number "1", `String "alo" }, `Pair{ `String "alo", `Number "1" }, `Number "2" } } } }
1171]=]
1172
1173r, m = parse(s)
1174assert(r == true)
1175
1176s = [=[
1177local t = { 1.5 }
1178]=]
1179--[=[
1180{ `Local{ { `Id "t" }, { `Table{ `Number "1.5" } } } }
1181]=]
1182
1183r, m = parse(s)
1184assert(r == true)
1185
1186s = [=[
1187local t = {1,2;
11883,
11894,
1190
1191
1192
11935}
1194]=]
1195--[=[
1196{ `Local{ { `Id "t" }, { `Table{ `Number "1", `Number "2", `Number "3", `Number "4", `Number "5" } } } }
1197]=]
1198
1199r, m = parse(s)
1200assert(r == true)
1201
1202s = [=[
1203local t = {[1]=1,[2]=2;
1204[3]=3,
1205[4]=4,
1206
1207
1208
1209[5]=5}
1210]=]
1211--[=[
1212{ `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" } } } } }
1213]=]
1214
1215r, m = parse(s)
1216assert(r == true)
1217
1218s = [=[
1219local t = {{{}}, {"alo"}}
1220]=]
1221--[=[
1222{ `Local{ { `Id "t" }, { `Table{ `Table{ `Table }, `Table{ `String "alo" } } } } }
1223]=]
1224
1225r, m = parse(s)
1226assert(r == true)
1227
1228-- vararg
1229
1230s = [=[
1231local f = function (...)
1232 return ...
1233end
1234]=]
1235--[=[
1236{ `Local{ { `Id "f" }, { `Function{ { `Dots }, { `Return{ `Dots } } } } } }
1237]=]
1238
1239r, m = parse(s)
1240assert(r == true)
1241
1242s = [=[
1243local f = function ()
1244 local g = function (x, y, ...)
1245 return ...,...,...
1246 end
1247end
1248]=]
1249--[=[
1250{ `Local{ { `Id "f" }, { `Function{ { }, { `Local{ { `Id "g" }, { `Function{ { `Id "x", `Id "y", `Dots }, { `Return{ `Dots, `Dots, `Dots } } } } } } } } } }
1251]=]
1252
1253r, m = parse(s)
1254assert(r == true)
1255
1256s = [=[
1257local function f (x, ...)
1258 return ...
1259end
1260]=]
1261--[=[
1262{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x", `Dots }, { `Return{ `Dots } } } } } }
1263]=]
1264
1265r, m = parse(s)
1266assert(r == true)
1267
1268s = [=[
1269local f = function (x, ...)
1270 return ...
1271end
1272]=]
1273--[=[
1274{ `Local{ { `Id "f" }, { `Function{ { `Id "x", `Dots }, { `Return{ `Dots } } } } } }
1275]=]
1276
1277r, m = parse(s)
1278assert(r == true)
1279
1280-- while
1281
1282s = [=[
1283local i = 0
1284while (i < 10)
1285do
1286 i = i + 1
1287end
1288]=]
1289--[=[
1290{ `Local{ { `Id "i" }, { `Number "0" } }, `While{ `Paren{ `Op{ "lt", `Id "i", `Number "10" } }, { `Set{ { `Id "i" }, { `Op{ "add", `Id "i", `Number "1" } } } } } }
1291]=]
1292
1293r, m = parse(s)
1294assert(r == true)
1295
1296-- type annotations
1297
1298s = [=[
1299local x:nil
1300]=]
1301--[=[
1302{ `Local{ { `Id "x":`TNil }, { } } }
1303]=]
1304
1305r, m = parse(s)
1306assert(r == true)
1307
1308s = [=[
1309local x:false, y:true
1310]=]
1311--[=[
1312{ `Local{ { `Id "x":`TLiteral false, `Id "y":`TLiteral true }, { } } }
1313]=]
1314
1315r, m = parse(s)
1316assert(r == true)
1317
1318s = [=[
1319local x:1, y:1.1
1320]=]
1321--[=[
1322{ `Local{ { `Id "x":`TLiteral 1, `Id "y":`TLiteral 1.1 }, { } } }
1323]=]
1324
1325r, m = parse(s)
1326assert(r == true)
1327
1328s = [=[
1329local x:"hello", y:'world'
1330]=]
1331--[=[
1332{ `Local{ { `Id "x":`TLiteral hello, `Id "y":`TLiteral world }, { } } }
1333]=]
1334
1335r, m = parse(s)
1336assert(r == true)
1337
1338s = [=[
1339local x:boolean, y:number, z:string
1340]=]
1341--[=[
1342{ `Local{ { `Id "x":`TBase boolean, `Id "y":`TBase number, `Id "z":`TBase string }, { } } }
1343]=]
1344
1345r, m = parse(s)
1346assert(r == true)
1347
1348s = [=[
1349local x:any
1350]=]
1351--[=[
1352{ `Local{ { `Id "x":`TAny }, { } } }
1353]=]
1354
1355r, m = parse(s)
1356assert(r == true)
1357
1358s = [=[
1359local x:number?
1360]=]
1361--[=[
1362{ `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } }
1363]=]
1364
1365r, m = parse(s)
1366assert(r == true)
1367
1368s = [=[
1369local x:number|nil
1370]=]
1371--[=[
1372{ `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } }
1373]=]
1374
1375r, m = parse(s)
1376assert(r == true)
1377
1378s = [=[
1379local x:number|string|nil
1380]=]
1381--[=[
1382{ `Local{ { `Id "x":`TUnion{ `TBase number, `TBase string, `TNil } }, { } } }
1383]=]
1384
1385r, m = parse(s)
1386assert(r == true)
1387
1388s = [=[
1389local x:number|nil|nil|nil|nil
1390]=]
1391--[=[
1392{ `Local{ { `Id "x":`TUnion{ `TBase number, `TNil } }, { } } }
1393]=]
1394
1395r, m = parse(s)
1396assert(r == true)
1397
1398s = [=[
1399local x:number|nil|string|nil|number|boolean|string
1400]=]
1401--[=[
1402{ `Local{ { `Id "x":`TUnion{ `TNil, `TBase number, `TBase boolean, `TBase string } }, { } } }
1403]=]
1404
1405r, m = parse(s)
1406assert(r == true)
1407
1408s = [=[
1409local x:number|string?
1410]=]
1411--[=[
1412{ `Local{ { `Id "x":`TUnion{ `TBase number, `TBase string, `TNil } }, { } } }
1413]=]
1414
1415r, m = parse(s)
1416assert(r == true)
1417
1418s = [=[
1419local x:(number) -> (number)
1420]=]
1421--[=[
1422{ `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TVararg{ `TValue } }, `TTuple{ `TBase number, `TVararg{ `TNil } } } }, { } } }
1423]=]
1424
1425r, m = parse(s)
1426assert(r == true)
1427
1428s = [=[
1429local x:(value*) -> (nil*)
1430]=]
1431--[=[
1432{ `Local{ { `Id "x":`TFunction{ `TTuple{ `TVararg{ `TValue } }, `TTuple{ `TVararg{ `TNil } } } }, { } } }
1433]=]
1434
1435r, m = parse(s)
1436assert(r == true)
1437
1438s = [=[
1439local x:(number,string,boolean) -> (string,number,boolean)
1440]=]
1441--[=[
1442{ `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase string, `TBase boolean, `TVararg{ `TValue } }, `TTuple{ `TBase string, `TBase number, `TBase boolean, `TVararg{ `TNil } } } }, { } } }
1443]=]
1444
1445r, m = parse(s)
1446assert(r == true)
1447
1448s = [=[
1449local x:(number,string,value*) -> (string,number,nil*)
1450]=]
1451--[=[
1452{ `Local{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase string, `TVararg{ `TValue } }, `TTuple{ `TBase string, `TBase number, `TVararg{ `TNil } } } }, { } } }
1453]=]
1454
1455r, m = parse(s)
1456assert(r == true)
1457
1458s = [=[
1459local x:{}
1460]=]
1461--[=[
1462{ `Local{ { `Id "x":`TTable{ } }, { } } }
1463]=]
1464
1465r, m = parse(s)
1466assert(r == true)
1467
1468s = [=[
1469local x:{{{{{}}}}}
1470]=]
1471--[=[
1472{ `Local{ { `Id "x":`TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ `TBase number:`TUnion{ `TTable{ }, `TNil } }, `TNil } }, `TNil } }, `TNil } } }, { } } }
1473]=]
1474
1475r, m = parse(s)
1476assert(r == true)
1477
1478s = [=[
1479local x:{string}
1480]=]
1481--[=[
1482{ `Local{ { `Id "x":`TTable{ `TBase number:`TUnion{ `TBase string, `TNil } } }, { } } }
1483]=]
1484
1485r, m = parse(s)
1486assert(r == true)
1487
1488s = [=[
1489local x:{string:number}
1490]=]
1491--[=[
1492{ `Local{ { `Id "x":`TTable{ `TBase string:`TUnion{ `TBase number, `TNil } } }, { } } }
1493]=]
1494
1495r, m = parse(s)
1496assert(r == true)
1497
1498s = [=[
1499local x:{'firstname':string, 'lastname':string}
1500]=]
1501--[=[
1502{ `Local{ { `Id "x":`TTable{ `TLiteral firstname:`TBase string, `TLiteral lastname:`TBase string } }, { } } }
1503]=]
1504
1505r, m = parse(s)
1506assert(r == true)
1507
1508s = [=[
1509local x:{'tag':string, number:string}
1510]=]
1511--[=[
1512{ `Local{ { `Id "x":`TTable{ `TLiteral tag:`TBase string, `TBase number:`TUnion{ `TBase string, `TNil } } }, { } } }
1513]=]
1514
1515r, m = parse(s)
1516assert(r == true)
1517
1518s = [=[
1519local x:{'f':(number) -> (number), 't':{number:number}}
1520]=]
1521--[=[
1522{ `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 } } } }, { } } }
1523]=]
1524
1525r, m = parse(s)
1526assert(r == true)
1527
1528s = [=[
1529for k:number, v:string in ipairs({"hello", "world"}) do end
1530]=]
1531--[=[
1532{ `Forin{ { `Id "k":`TBase number, `Id "v":`TBase string }, { `Call{ `Index{ `Id "_ENV", `String "ipairs" }, `Table{ `String "hello", `String "world" } } }, { } } }
1533]=]
1534
1535r, m = parse(s)
1536assert(r == true)
1537
1538s = [=[
1539for k:string, v in pairs({}) do end
1540]=]
1541--[=[
1542{ `Forin{ { `Id "k":`TBase string, `Id "v" }, { `Call{ `Index{ `Id "_ENV", `String "pairs" }, `Table } }, { } } }
1543]=]
1544
1545r, m = parse(s)
1546assert(r == true)
1547
1548s = [=[
1549for k, v:boolean in pairs({}) do end
1550]=]
1551--[=[
1552{ `Forin{ { `Id "k", `Id "v":`TBase boolean }, { `Call{ `Index{ `Id "_ENV", `String "pairs" }, `Table } }, { } } }
1553]=]
1554
1555r, m = parse(s)
1556assert(r == true)
1557
1558s = [=[
1559local function f (x:any) end
1560]=]
1561--[=[
1562{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny }, { } } } } }
1563]=]
1564
1565r, m = parse(s)
1566assert(r == true)
1567
1568s = [=[
1569local function f (x:any):(any) end
1570]=]
1571--[=[
1572{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny }:`TTuple{ `TAny, `TVararg{ `TNil } }, { } } } } }
1573]=]
1574
1575r, m = parse(s)
1576assert(r == true)
1577
1578s = [=[
1579local function f (...:any) end
1580]=]
1581--[=[
1582{ `Localrec{ { `Id "f" }, { `Function{ { `Dots:`TAny }, { } } } } }
1583]=]
1584
1585r, m = parse(s)
1586assert(r == true)
1587
1588s = [=[
1589local function f (x:any, ...:any) end
1590]=]
1591--[=[
1592{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots:`TAny }, { } } } } }
1593]=]
1594
1595r, m = parse(s)
1596assert(r == true)
1597
1598s = [=[
1599local function f (x, ...:any) end
1600]=]
1601--[=[
1602{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x", `Dots:`TAny }, { } } } } }
1603]=]
1604
1605r, m = parse(s)
1606assert(r == true)
1607
1608s = [=[
1609local function f (x:any, ...) end
1610]=]
1611--[=[
1612{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots }, { } } } } }
1613]=]
1614
1615r, m = parse(s)
1616assert(r == true)
1617
1618s = [=[
1619local function f (x:any, ...:any):(any) end
1620]=]
1621--[=[
1622{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TAny, `Dots:`TAny }:`TTuple{ `TAny, `TVararg{ `TNil } }, { } } } } }
1623]=]
1624
1625r, m = parse(s)
1626assert(r == true)
1627
1628s = [=[
1629local function f (x:(any) -> (any)):((any) -> (any)) end
1630]=]
1631--[=[
1632{ `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 } }, { } } } } }
1633]=]
1634
1635r, m = parse(s)
1636assert(r == true)
1637
1638s = [=[
1639local function f (x:(number, number) -> (number, nil*)):(number*) end
1640]=]
1641--[=[
1642{ `Localrec{ { `Id "f" }, { `Function{ { `Id "x":`TFunction{ `TTuple{ `TBase number, `TBase number, `TVararg{ `TValue } }, `TTuple{ `TBase number, `TVararg{ `TNil } } } }:`TTuple{ `TVararg{ `TBase number } }, { } } } } }
1643]=]
1644
1645r, m = parse(s)
1646assert(r == true)
1647
1648s = [=[
1649local function f ():(number, nil*) end
1650]=]
1651--[=[
1652{ `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TBase number, `TVararg{ `TNil } }, { } } } } }
1653]=]
1654
1655r, m = parse(s)
1656assert(r == true)
1657
1658s = [=[
1659local function f ():number end
1660]=]
1661--[=[
1662{ `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TBase number, `TVararg{ `TNil } }, { } } } } }
1663]=]
1664
1665r, m = parse(s)
1666assert(r == true)
1667
1668s = [=[
1669local function f ():number? end
1670]=]
1671--[=[
1672{ `Localrec{ { `Id "f" }, { `Function{ { }:`TTuple{ `TUnion{ `TBase number, `TNil }, `TVararg{ `TNil } }, { } } } } }
1673]=]
1674
1675r, m = parse(s)
1676assert(r == true)
1677
1678s = [=[
1679local function f ():(number) | (nil,string) end
1680]=]
1681--[=[
1682{ `Localrec{ { `Id "f" }, { `Function{ { }:`TUnionlist{ `TTuple{ `TBase number, `TVararg{ `TNil } }, `TTuple{ `TNil, `TBase string, `TVararg{ `TNil } } }, { } } } } }
1683]=]
1684
1685r, m = parse(s)
1686assert(r == true)
1687
1688s = [=[
1689local function f ():(number)? end
1690]=]
1691--[=[
1692{ `Localrec{ { `Id "f" }, { `Function{ { }:`TUnionlist{ `TTuple{ `TBase number, `TVararg{ `TNil } }, `TTuple{ `TNil, `TBase string, `TVararg{ `TNil } } }, { } } } } }
1693]=]
1694
1695r, m = parse(s)
1696assert(r == true)
1697
1698-- syntax error
1699
1700-- anonymous functions
1701
1702s = [=[
1703a = function (a,b,) end
1704]=]
1705--[=[
1706test.lua:1:19: syntax error, unexpected ')', expecting '...', 'Name'
1707]=]
1708e = [=[
1709test.lua:1:18: expecting '...'
1710]=]
1711
1712r, m = parse(s)
1713assert(m == e)
1714
1715s = [=[
1716a = function (...,a) end
1717]=]
1718--[=[
1719test.lua:1:18: syntax error, unexpected ',', expecting ')', ':'
1720]=]
1721e = [=[
1722test.lua:1:17: missing ')'
1723]=]
1724
1725r, m = parse(s)
1726assert(m == e)
1727
1728s = [=[
1729local a = function (1) end
1730]=]
1731--[=[
1732test.lua:1:21: syntax error, unexpected '1', expecting ')', '...', 'Name'
1733]=]
1734e = [=[
1735test.lua:1:20: missing ')'
1736]=]
1737
1738r, m = parse(s)
1739assert(m == e)
1740
1741s = [=[
1742local test = function ( a , b , c , ... )
1743]=]
1744--[=[
1745test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ':'
1746]=]
1747e = [=[
1748test.lua:2:1: missing 'end' to close function declaration
1749]=]
1750
1751r, m = parse(s)
1752assert(m == e)
1753
1754-- arithmetic expressions
1755
1756s = [=[
1757a = 3 / / 2
1758]=]
1759--[=[
1760test.lua:1:9: syntax error, unexpected '/', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1761]=]
1762e = [=[
1763test.lua:1:8: malformed multiplication expression
1764]=]
1765
1766r, m = parse(s)
1767assert(m == e)
1768
1769-- bitwise expressions
1770
1771s = [=[
1772b = 1 && 1
1773]=]
1774--[=[
1775test.lua:1:8: syntax error, unexpected '&', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1776]=]
1777e = [=[
1778test.lua:1:7: malformed '&' expression
1779]=]
1780
1781r, m = parse(s)
1782assert(m == e)
1783
1784s = [=[
1785b = 1 <> 0
1786]=]
1787--[=[
1788test.lua:1:8: syntax error, unexpected '>', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1789]=]
1790e = [=[
1791test.lua:1:7: malformed relational expression
1792]=]
1793
1794r, m = parse(s)
1795assert(m == e)
1796
1797s = [=[
1798b = 1 < < 0
1799]=]
1800--[=[
1801test.lua:1:9: syntax error, unexpected '<', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1802]=]
1803e = [=[
1804test.lua:1:8: malformed relational expression
1805]=]
1806
1807r, m = parse(s)
1808assert(m == e)
1809
1810-- concatenation expressions
1811
1812s = [=[
1813concat2 = 2^3..1
1814]=]
1815--[=[
1816test.lua:1:15: syntax error, unexpected '.1', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
1817]=]
1818e = [=[
1819test.lua:1:14: malformed <number>
1820]=]
1821
1822r, m = parse(s)
1823assert(m == e)
1824
1825-- for generic
1826
1827s = [=[
1828for k;v in pairs(t) do end
1829]=]
1830--[=[
1831test.lua:1:6: syntax error, unexpected ';', expecting 'in', ',', ':', '='
1832]=]
1833e = [=[
1834test.lua:1:5: expecting 'in'
1835]=]
1836
1837r, m = parse(s)
1838assert(m == e)
1839
1840s = [=[
1841for k,v in pairs(t:any) do end
1842]=]
1843--[=[
1844test.lua:1:23: syntax error, unexpected ')', expecting 'String', '{', '('
1845]=]
1846e = [=[
1847test.lua:1:22: expecting '(' for method call
1848]=]
1849
1850r, m = parse(s)
1851assert(m == e)
1852
1853-- for numeric
1854
1855s = [=[
1856for i=1,10, do end
1857]=]
1858--[=[
1859test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1860]=]
1861e = [=[
1862test.lua:1:10: missing 'do' in for statement
1863]=]
1864
1865r, m = parse(s)
1866assert(m == e)
1867
1868s = [=[
1869for i=1,n:number do end
1870]=]
1871--[=[
1872test.lua:1:18: syntax error, unexpected 'do', expecting 'String', '{', '('
1873]=]
1874e = [=[
1875test.lua:1:17: expecting '(' for method call
1876]=]
1877
1878r, m = parse(s)
1879assert(m == e)
1880
1881-- global functions
1882
1883s = [=[
1884function func(a,b,c,) end
1885]=]
1886--[=[
1887test.lua:1:21: syntax error, unexpected ')', expecting '...', 'Name'
1888]=]
1889e = [=[
1890test.lua:1:20: expecting '...'
1891]=]
1892
1893r, m = parse(s)
1894assert(m == e)
1895
1896s = [=[
1897function func(...,a) end
1898]=]
1899--[=[
1900test.lua:1:18: syntax error, unexpected ',', expecting ')', ':'
1901]=]
1902e = [=[
1903test.lua:1:17: missing ')'
1904]=]
1905
1906r, m = parse(s)
1907assert(m == e)
1908
1909s = [=[
1910function a.b:c:d () end
1911]=]
1912--[=[
1913test.lua:1:15: syntax error, unexpected ':', expecting '('
1914]=]
1915e = [=[
1916test.lua:1:14: missing '('
1917]=]
1918
1919r, m = parse(s)
1920assert(m == e)
1921
1922-- goto
1923
1924s = [=[
1925:: label :: return
1926goto label
1927]=]
1928--[=[
1929test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1930]=]
1931e = [=[
1932test.lua:2:1: invalid statement after 'return'
1933]=]
1934
1935r, m = parse(s)
1936assert(m == e)
1937
1938-- if-else
1939
1940s = [=[
1941if a then
1942]=]
1943--[=[
1944test.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', ';'
1945]=]
1946e = [=[
1947test.lua:2:1: missing 'end' to close if statement
1948]=]
1949
1950r, m = parse(s)
1951assert(m == e)
1952
1953s = [=[
1954if a then else
1955]=]
1956--[=[
1957test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';'
1958]=]
1959e = [=[
1960test.lua:2:1: missing 'end' to close if statement
1961]=]
1962
1963r, m = parse(s)
1964assert(m == e)
1965
1966s = [=[
1967if a then
1968 return a
1969elseif b then
1970 return b
1971elseif
1972
1973end
1974]=]
1975--[=[
1976test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
1977]=]
1978e = [=[
1979test.lua:7:1: expecting <exp> after 'elseif'
1980]=]
1981
1982r, m = parse(s)
1983assert(m == e)
1984
1985s = [=[
1986if a:any then else end
1987]=]
1988--[=[
1989test.lua:1:10: syntax error, unexpected 'then', expecting 'String', '{', '('
1990]=]
1991e = [=[
1992test.lua:1:9: expecting '(' for method call
1993]=]
1994
1995r, m = parse(s)
1996assert(m == e)
1997
1998-- labels
1999
2000s = [=[
2001:: blah ::
2002:: not ::
2003]=]
2004--[=[
2005test.lua:2:4: syntax error, unexpected 'not', expecting 'Name'
2006]=]
2007e = [=[
2008test.lua:2:3: expecting <name> after '::'
2009]=]
2010
2011r, m = parse(s)
2012assert(m == e)
2013
2014-- locals
2015
2016s = [=[
2017local a =
2018]=]
2019--[=[
2020test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
2021]=]
2022e = [=[
2023test.lua:2:1: expecting expression list after '='
2024]=]
2025
2026r, m = parse(s)
2027assert(m == e)
2028
2029s = [=[
2030local function t.a() end
2031]=]
2032--[=[
2033test.lua:1:17: syntax error, unexpected '.', expecting '('
2034]=]
2035e = [=[
2036test.lua:1:16: missing '('
2037]=]
2038
2039r, m = parse(s)
2040assert(m == e)
2041
2042s = [=[
2043local function test (a,) end
2044]=]
2045--[=[
2046test.lua:1:24: syntax error, unexpected ')', expecting '...', 'Name'
2047]=]
2048e = [=[
2049test.lua:1:23: expecting '...'
2050]=]
2051
2052r, m = parse(s)
2053assert(m == e)
2054
2055s = [=[
2056local function test(...,a) end
2057]=]
2058--[=[
2059test.lua:1:24: syntax error, unexpected ',', expecting ')', ':'
2060]=]
2061e = [=[
2062test.lua:1:23: missing ')'
2063]=]
2064
2065r, m = parse(s)
2066assert(m == e)
2067
2068s = [=[
2069local function (a, b, c, ...) end
2070]=]
2071--[=[
2072test.lua:1:16: syntax error, unexpected '(', expecting 'Name'
2073]=]
2074e = [=[
2075test.lua:1:15: expecting <name> in local function declaration
2076]=]
2077
2078r, m = parse(s)
2079assert(m == e)
2080
2081-- repeat
2082
2083s = [=[
2084repeat
2085 a,b,c = 1+1,2+2,3+3
2086 break
2087]=]
2088--[=[
2089test.lua:4:1: syntax error, unexpected 'EOF', expecting 'until', 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';'
2090]=]
2091e = [=[
2092test.lua:4:1: missing 'until' in repeat statement
2093]=]
2094
2095r, m = parse(s)
2096assert(m == e)
2097
2098-- return
2099
2100s = [=[
2101return
2102return 1
2103return 1,1-2*3+4,"alo"
2104return;
2105return 1;
2106return 1,1-2*3+4,"alo";
2107]=]
2108--[=[
2109test.lua:2:1: syntax error, unexpected 'return', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not'
2110]=]
2111e = [=[
2112test.lua:2:1: invalid statement
2113]=]
2114
2115r, m = parse(s)
2116assert(m == e)
2117
2118-- tables
2119
2120s = [=[
2121t = { , }
2122]=]
2123--[=[
2124test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '~', '-', 'not', 'Name', '[', 'const'
2125]=]
2126e = [=[
2127test.lua:1:6: missing '}'
2128]=]
2129
2130r, m = parse(s)
2131assert(m == e)
2132
2133-- while
2134
2135s = [=[
2136i = 0
2137while (i < 10)
2138 i = i + 1
2139end
2140]=]
2141--[=[
2142test.lua:3:3: syntax error, unexpected 'i', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^', 'String', '{', '(', ':', '[', '.'
2143]=]
2144e = [=[
2145test.lua:3:2: missing 'do' in while statement
2146]=]
2147
2148r, m = parse(s)
2149assert(m == e)
2150
2151-- type annotations
2152
2153s = [=[
2154t[x:any] = 1
2155]=]
2156--[=[
2157test.lua:1:8: syntax error, unexpected ']', expecting 'String', '{', '('
2158]=]
2159e = [=[
2160test.lua:1:7: expecting '(' for method call
2161]=]
2162
2163r, m = parse(s)
2164assert(m == e)
2165
2166s = [=[
2167x:number, y, z:boolean = 1, nil, true
2168]=]
2169--[=[
2170test.lua:1:9: syntax error, unexpected ',', expecting 'String', '{', '('
2171]=]
2172e = [=[
2173test.lua:1:8: expecting '(' for method call
2174]=]
2175
2176r, m = parse(s)
2177assert(m == e)
2178
2179s = [=[
2180x = x:any
2181]=]
2182--[=[
2183test.lua:2:1: syntax error, unexpected 'EOF', expecting 'String', '{', '('
2184]=]
2185e = [=[
2186test.lua:2:1: expecting '(' for method call
2187]=]
2188
2189r, m = parse(s)
2190assert(m == e)
2191
2192s = [=[
2193x = ...:any
2194]=]
2195--[=[
2196test.lua:1:8: syntax error, unexpected ':', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
2197]=]
2198e = [=[
2199test.lua:1:7: invalid statement
2200]=]
2201
2202r, m = parse(s)
2203assert(m == e)
2204
2205s = [=[
2206f(x:any)
2207]=]
2208--[=[
2209test.lua:1:8: syntax error, unexpected ')', expecting 'String', '{', '('
2210]=]
2211e = [=[
2212test.lua:1:7: expecting '(' for method call
2213]=]
2214
2215r, m = parse(s)
2216assert(m == e)
2217
2218s = [=[
2219f(...:any)
2220]=]
2221--[=[
2222test.lua:1:6: syntax error, unexpected ':', expecting ')', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
2223]=]
2224e = [=[
2225test.lua:1:5: missing ')'
2226]=]
2227
2228r, m = parse(s)
2229assert(m == e)
2230
2231s = [=[
2232local x:number*
2233]=]
2234--[=[
2235test.lua:1:15: syntax error, unexpected '*', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', '=', ',', '?', '|'
2236]=]
2237e = [=[
2238test.lua:1:6: invalid local declaration
2239]=]
2240
2241r, m = parse(s)
2242assert(m == e)
2243
2244s = [=[
2245local x:number|
2246]=]
2247--[=[
2248test.lua:2:1: syntax error, unexpected 'EOF', expecting '{', '(', 'Type'
2249]=]
2250e = [=[
2251test.lua:2:1: expecting <type> after '|'
2252]=]
2253
2254r, m = parse(s)
2255assert(m == e)
2256
2257s = [=[
2258local x:number?|string?
2259]=]
2260--[=[
2261test.lua:1:16: syntax error, unexpected '|', expecting 'return', '(', 'Name', 'typealias', 'interface', 'goto', 'break', '::', 'local', 'function', 'const', 'repeat', 'for', 'do', 'while', 'if', ';', '=', ','
2262]=]
2263e = [=[
2264test.lua:1:6: invalid local declaration
2265]=]
2266
2267r, m = parse(s)
2268assert(m == e)
2269
2270s = [=[
2271local x:() -> number
2272]=]
2273--[=[
2274test.lua:1:15: syntax error, unexpected 'number', expecting '('
2275]=]
2276e = [=[
2277test.lua:1:14: expecting <type> after '->'
2278]=]
2279
2280r, m = parse(s)
2281assert(m == e)
2282
2283s = [=[
2284local x:() -> (number)? | (string)?
2285]=]
2286--[=[
2287test.lua:1:35: syntax error, unexpected '?', expecting '->'
2288]=]
2289e = [=[
2290test.lua:1:26: expecting <type> after '|'
2291]=]
2292
2293r, m = parse(s)
2294assert(m == e)
2295
2296s = [=[
2297local x:{()->():string}
2298]=]
2299--[=[
2300test.lua:1:16: syntax error, unexpected ':', expecting '}', '?', '|'
2301]=]
2302e = [=[
2303test.lua:1:15: missing '}'
2304]=]
2305
2306r, m = parse(s)
2307assert(m == e)
2308
2309s = [=[
2310local x:{string:t 1}
2311]=]
2312--[=[
2313test.lua:1:19: syntax error, unexpected '1', expecting '}', '?', '|'
2314]=]
2315e = [=[
2316test.lua:1:18: missing '}'
2317]=]
2318
2319r, m = parse(s)
2320assert(m == e)
2321
2322s = [=[
2323local x:{{{{{}}}}
2324]=]
2325--[=[
2326test.lua:2:1: syntax error, unexpected 'EOF', expecting '}', '?', '|'
2327]=]
2328e = [=[
2329test.lua:2:1: missing '}'
2330]=]
2331
2332r, m = parse(s)
2333assert(m == e)
2334
2335-- syntax errors that depend on some semantic information
2336
2337-- break
2338
2339s = [=[
2340break
2341]=]
2342--[=[
2343test.lua:1:1: syntax error, <break> not inside a loop
2344]=]
2345
2346r, m = parse(s)
2347assert(r == true)
2348
2349s = [=[
2350function f (x)
2351 if 1 then break end
2352end
2353]=]
2354--[=[
2355test.lua:2:13: syntax error, <break> not inside a loop
2356]=]
2357
2358r, m = parse(s)
2359assert(r == true)
2360
2361s = [=[
2362while 1 do
2363end
2364break
2365]=]
2366--[=[
2367test.lua:3:1: syntax error, <break> not inside a loop
2368]=]
2369
2370r, m = parse(s)
2371assert(r == true)
2372
2373-- goto
2374
2375s = [=[
2376goto label
2377]=]
2378--[=[
2379test.lua:1:1: syntax error, no visible label 'label' for <goto>
2380]=]
2381
2382r, m = parse(s)
2383assert(r == true)
2384
2385s = [=[
2386goto label
2387::other_label::
2388]=]
2389--[=[
2390test.lua:1:1: syntax error, no visible label 'label' for <goto>
2391]=]
2392
2393r, m = parse(s)
2394assert(r == true)
2395
2396s = [=[
2397::other_label::
2398do do do goto label end end end
2399]=]
2400--[=[
2401test.lua:2:10: syntax error, no visible label 'label' for <goto>
2402]=]
2403
2404r, m = parse(s)
2405assert(r == true)
2406
2407-- interfaces
2408
2409s = [=[
2410local interface X
2411 x:number
2412 y:number
2413 z:number
2414 x:number
2415end
2416]=]
2417--[=[
2418test.lua:1:7: syntax error, attempt to redeclare field 'x'
2419]=]
2420
2421r, m = parse(s)
2422assert(r == true)
2423
2424s = [=[
2425local interface X
2426 x, y, z, x:number
2427end
2428]=]
2429--[=[
2430test.lua:1:7: syntax error, attempt to redeclare field 'x'
2431]=]
2432
2433r, m = parse(s)
2434assert(r == true)
2435
2436s = [=[
2437local interface boolean end
2438]=]
2439--[=[
2440test.lua:1:7: syntax error, attempt to redeclare type 'boolean'
2441]=]
2442
2443r, m = parse(s)
2444assert(r == true)
2445
2446s = [=[
2447local interface number end
2448]=]
2449--[=[
2450test.lua:1:7: syntax error, attempt to redeclare type 'number'
2451]=]
2452
2453r, m = parse(s)
2454assert(r == true)
2455
2456s = [=[
2457local interface string end
2458]=]
2459--[=[
2460test.lua:1:7: syntax error, attempt to redeclare type 'string'
2461]=]
2462
2463r, m = parse(s)
2464assert(r == true)
2465
2466s = [=[
2467local interface value end
2468]=]
2469--[=[
2470test.lua:1:7: syntax error, attempt to redeclare type 'value'
2471]=]
2472
2473r, m = parse(s)
2474assert(r == true)
2475
2476s = [=[
2477local interface any end
2478]=]
2479--[=[
2480test.lua:1:7: syntax error, attempt to redeclare type 'any'
2481]=]
2482
2483r, m = parse(s)
2484assert(r == true)
2485
2486s = [=[
2487local interface self end
2488]=]
2489--[=[
2490test.lua:1:7: syntax error, attempt to redeclare type 'self'
2491]=]
2492
2493r, m = parse(s)
2494assert(r == true)
2495
2496s = [=[
2497local interface const end
2498]=]
2499--[=[
2500test.lua:1:7: syntax error, attempt to redeclare type 'const'
2501]=]
2502
2503r, m = parse(s)
2504assert(r == true)
2505
2506-- labels
2507
2508s = [=[
2509::label::
2510::other_label::
2511::label::
2512]=]
2513--[=[
2514test.lua:3:1: syntax error, label 'label' already defined
2515]=]
2516
2517r, m = parse(s)
2518assert(r == true)
2519
2520-- vararg
2521
2522s = [=[
2523function f ()
2524 return ...
2525end
2526]=]
2527--[=[
2528test.lua:2:10: syntax error, cannot use '...' outside a vararg function
2529]=]
2530
2531r, m = parse(s)
2532assert(r == true)
2533
2534s = [=[
2535function f ()
2536 function g (x, y)
2537 return ...,...,...
2538 end
2539end
2540]=]
2541--[=[
2542test.lua:3:12: syntax error, cannot use '...' outside a vararg function
2543]=]
2544
2545r, m = parse(s)
2546assert(r == true)
2547
2548s = [=[
2549local function f (x)
2550 return ...
2551end
2552]=]
2553--[=[
2554test.lua:2:10: syntax error, cannot use '...' outside a vararg function
2555]=]
2556
2557r, m = parse(s)
2558assert(r == true)
2559
2560s = [=[
2561local f = function (x)
2562 return ...
2563end
2564]=]
2565--[=[
2566test.lua:2:10: syntax error, cannot use '...' outside a vararg function
2567]=]
2568
2569r, m = parse(s)
2570assert(r == true)
2571
2572print("OK")
diff --git a/examples/typedlua/tlerror.lua b/examples/typedlua/tlerror.lua
deleted file mode 100644
index 94be024..0000000
--- a/examples/typedlua/tlerror.lua
+++ /dev/null
@@ -1,66 +0,0 @@
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
deleted file mode 100644
index 96f296d..0000000
--- a/examples/typedlua/tllexer.lua
+++ /dev/null
@@ -1,105 +0,0 @@
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
12local function setffp (s, i, t, n)
13 if not t.ffp or i > t.ffp then
14 t.ffp = i
15 t.list = {}
16 t.list[n] = true
17 t.expected = "'" .. n .. "'"
18 elseif i == t.ffp then
19 if not t.list[n] then
20 t.list[n] = true
21 t.expected = "'" .. n .. "', " .. t.expected
22 end
23 end
24 return false
25end
26
27local function updateffp (name)
28 return lpeg.Cmt(lpeg.Carg(1) * lpeg.Cc(name), setffp)
29end
30
31tllexer.Shebang = lpeg.P("#") * (lpeg.P(1) - lpeg.P("\n"))^0 * lpeg.P("\n")
32
33local Space = lpeg.space^1
34
35local Equals = lpeg.P("=")^0
36local Open = "[" * lpeg.Cg(Equals, "init") * "[" * lpeg.P("\n")^-1
37local Close = "]" * lpeg.C(Equals) * "]"
38local CloseEQ = lpeg.Cmt(Close * lpeg.Cb("init"),
39 function (s, i, a, b) return a == b end)
40
41local LongString = Open * (lpeg.P(1) - CloseEQ)^0 * tllexer.try(Close, "LongString") /
42 function (s, o) return s end
43
44local LongStringCm1 = Open * (lpeg.P(1) - CloseEQ)^0 * Close /
45 function (s, o) return s end
46
47local Comment = lpeg.Rec(lpeg.P"--" * #Open * (LongStringCm1 / function() return end + lpeg.T(tlerror.labels["LongString"])),
48 lpeg.T(tlerror.labels["LongComment"]), tlerror.labels["LongString"]) +
49 lpeg.P("--") * (lpeg.P(1) - lpeg.P("\n"))^0
50
51tllexer.Skip = (Space + Comment)^0
52
53local idStart = lpeg.alpha + lpeg.P("_")
54local idRest = lpeg.alnum + lpeg.P("_")
55
56local Keywords = lpeg.P("and") + "break" + "do" + "elseif" + "else" + "end" +
57 "false" + "for" + "function" + "goto" + "if" + "in" +
58 "local" + "nil" + "not" + "or" + "repeat" + "return" +
59 "then" + "true" + "until" + "while"
60
61tllexer.Reserved = Keywords * -idRest
62
63local Identifier = idStart * idRest^0
64
65tllexer.Name = -tllexer.Reserved * Identifier * -idRest
66
67function tllexer.token (pat, name)
68 return pat * tllexer.Skip + updateffp(name) * lpeg.P(false)
69end
70
71function tllexer.symb (str)
72 return tllexer.token(lpeg.P(str), str)
73end
74
75function tllexer.kw (str)
76 return tllexer.token(lpeg.P(str) * -idRest, str)
77end
78
79local Hex = (lpeg.P("0x") + lpeg.P("0X")) * tllexer.try(lpeg.xdigit^1, "Number")
80local Expo = lpeg.S("eE") * lpeg.S("+-")^-1 * tllexer.try(lpeg.digit^1, "Number")
81local Float = (((lpeg.digit^1 * lpeg.P(".") * lpeg.digit^0 * tllexer.try(-lpeg.P("."), "Number")) +
82 (lpeg.P(".") * lpeg.digit^1)) * Expo^-1) +
83 (lpeg.digit^1 * Expo)
84local Int = lpeg.digit^1
85
86tllexer.Number = Hex + Float + Int
87
88local ShortString = lpeg.P('"') *
89 ((lpeg.P('\\') * lpeg.P(1)) + (lpeg.P(1) - lpeg.P('"')))^0 *
90 tllexer.try(lpeg.P('"'), "String") +
91 lpeg.P("'") *
92 ((lpeg.P("\\") * lpeg.P(1)) + (lpeg.P(1) - lpeg.P("'")))^0 *
93 tllexer.try(lpeg.P("'"), "String")
94
95tllexer.String = LongString + ShortString
96
97-- for error reporting
98tllexer.OneWord = tllexer.Name +
99 tllexer.Number +
100 tllexer.String +
101 tllexer.Reserved +
102 lpeg.P("...") +
103 lpeg.P(1)
104
105return tllexer
diff --git a/examples/typedlua/tlp.lua b/examples/typedlua/tlp.lua
deleted file mode 100644
index 2a4a736..0000000
--- a/examples/typedlua/tlp.lua
+++ /dev/null
@@ -1,20 +0,0 @@
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
deleted file mode 100644
index 2ede2eb..0000000
--- a/examples/typedlua/tlparser.lua
+++ /dev/null
@@ -1,245 +0,0 @@
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, pos = lpeg.match(G, subject, nil, errorinfo, strict, integer)
230 if not ast then
231 local line, col = lineno(subject, pos)
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