Skip to content

Commit 47976de

Browse files
committed
Adding all relational operators to the AST for fixing andremm#12
1 parent 401d284 commit 47976de

File tree

3 files changed

+35
-63
lines changed

3 files changed

+35
-63
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ AST format
8484

8585
lhs: `Id{ <string> } | `Index{ expr expr }
8686

87-
opid: -- includes additional operators from Lua 5.3
87+
opid: -- includes additional operators from Lua 5.3 and all relational operators
8888
'add' | 'sub' | 'mul' | 'div'
8989
| 'idiv' | 'mod' | 'pow' | 'concat'
9090
| 'band' | 'bor' | 'bxor' | 'shl' | 'shr'
91-
| 'eq' | 'lt' | 'le' | 'and' | 'or'
92-
| 'unm' | 'len' | 'bnot' | 'not'
91+
| 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge'
92+
| 'and' | 'or' | 'unm' | 'len' | 'bnot' | 'not'
9393

9494

9595
Usage

lua-parser/parser.lua

+5-16
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ apply:
4141
4242
lhs: `Id{ <string> } | `Index{ expr expr }
4343
44-
opid: -- includes additional operators from Lua 5.3
44+
opid: -- includes additional operators from Lua 5.3 and all relational operators
4545
'add' | 'sub' | 'mul' | 'div'
4646
| 'idiv' | 'mod' | 'pow' | 'concat'
4747
| 'band' | 'bor' | 'bxor' | 'shl' | 'shr'
48-
| 'eq' | 'lt' | 'le' | 'and' | 'or'
49-
| 'unm' | 'len' | 'bnot' | 'not'
48+
| 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge'
49+
| 'and' | 'or' | 'unm' | 'len' | 'bnot' | 'not'
5050
]]
5151

5252
local lpeg = require "lpeglabel"
@@ -197,20 +197,9 @@ end
197197
local function binaryOp (e1, op, e2)
198198
if not op then
199199
return e1
200+
else
201+
return { tag = "Op", pos = e1.pos, [1] = op, [2] = e1, [3] = e2 }
200202
end
201-
202-
local node = { tag = "Op", pos = e1.pos, [1] = op, [2] = e1, [3] = e2 }
203-
204-
if op == "ne" then
205-
node[1] = "eq"
206-
node = unaryOp("not", node)
207-
elseif op == "gt" then
208-
node[1], node[2], node[3] = "lt", e2, e1
209-
elseif op == "ge" then
210-
node[1], node[2], node[3] = "le", e2, e1
211-
end
212-
213-
return node
214203
end
215204

216205
local function sepBy (patt, sep, label)

test.lua

+27-44
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
#!/usr/bin/env lua
22

3-
local metalua = false
4-
5-
if arg[1] == "metalua" then metalua = true end
6-
7-
local parser
8-
if metalua then
9-
parser = require "metalua.compiler".new()
10-
else
11-
parser = require "lua-parser.parser"
12-
end
3+
local parser = require "lua-parser.parser"
134
local pp = require "lua-parser.pp"
145

156
-- expected result, result, subject
@@ -18,12 +9,7 @@ local e, r, s
189
local filename = "test.lua"
1910

2011
local function parse (s)
21-
local t,m
22-
if metalua then
23-
t = parser:src_to_ast(s)
24-
else
25-
t,m = parser.parse(s,filename)
26-
end
12+
local t,m = parser.parse(s,filename)
2713
local r
2814
if not t then
2915
r = m
@@ -352,8 +338,6 @@ assert(r == e)
352338

353339
-- syntax error
354340

355-
if not metalua then
356-
357341
-- floating points
358342

359343
s = [=[
@@ -480,8 +464,6 @@ test.lua:4:1: syntax error, unclosed long string
480464
r = parse(s)
481465
assert(r == e)
482466

483-
end
484-
485467
print("> testing parser...")
486468

487469
-- syntax ok
@@ -670,7 +652,7 @@ repeat
670652
until 1
671653
]=]
672654
e = [=[
673-
{ `Repeat{ { `If{ `Op{ "lt", `Number "1", `Number "2" }, { `Break } } }, `Number "1" } }
655+
{ `Repeat{ { `If{ `Op{ "gt", `Number "2", `Number "1" }, { `Break } } }, `Number "1" } }
674656
]=]
675657

676658
r = parse(s)
@@ -721,17 +703,13 @@ assert(r == e)
721703

722704
-- empty files
723705

724-
if not metalua then
725-
726706
s = [=[
727707
;
728708
]=]
729709
e = [=[
730710
{ }
731711
]=]
732712

733-
end
734-
735713
r = parse(s)
736714
assert(r == e)
737715

@@ -823,8 +801,6 @@ assert(r == e)
823801

824802
-- goto
825803

826-
if not metalua then
827-
828804
s = [=[
829805
goto label
830806
:: label :: return
@@ -913,8 +889,6 @@ e = [=[
913889
r = parse(s)
914890
assert(r == e)
915891

916-
end
917-
918892
-- if-else
919893

920894
s = [=[
@@ -969,8 +943,6 @@ e = [=[
969943
r = parse(s)
970944
assert(r == e)
971945

972-
if not metalua then
973-
974946
s = [=[
975947
if a then return a
976948
elseif b then return
@@ -984,8 +956,6 @@ e = [=[
984956
r = parse(s)
985957
assert(r == e)
986958

987-
end
988-
989959
s = [=[
990960
if a then
991961
return
@@ -1001,8 +971,6 @@ assert(r == e)
1001971

1002972
-- labels
1003973

1004-
if not metalua then
1005-
1006974
s = [=[
1007975
::label::
1008976
do ::label:: end
@@ -1027,8 +995,6 @@ e = [=[
1027995
r = parse(s)
1028996
assert(r == e)
1029997

1030-
end
1031-
1032998
-- locals
1033999

10341000
s = [=[
@@ -1107,7 +1073,7 @@ s = [=[
11071073
relational = 1 < 2 >= 3 == 4 ~= 5 < 6 <= 7
11081074
]=]
11091075
e = [=[
1110-
{ `Set{ { `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" } } } }
1076+
{ `Set{ { `Id "relational" }, { `Op{ "le", `Op{ "lt", `Op{ "ne", `Op{ "eq", `Op{ "ge", `Op{ "lt", `Number "1", `Number "2" }, `Number "3" }, `Number "4" }, `Number "5" }, `Number "6" }, `Number "7" } } } }
11111077
]=]
11121078

11131079
r = parse(s)
@@ -1357,8 +1323,6 @@ assert(r == e)
13571323

13581324
-- syntax error
13591325

1360-
if not metalua then
1361-
13621326
-- anonymous functions
13631327

13641328
s = [=[
@@ -1860,10 +1824,6 @@ test.lua:3:3: syntax error, expected 'do' after the condition
18601824
r = parse(s)
18611825
assert(r == e)
18621826

1863-
end
1864-
1865-
if not metalua then
1866-
18671827
print("> testing more syntax errors...")
18681828

18691829
-- ErrExtra
@@ -3770,6 +3730,29 @@ test.lua:6:1: syntax error, unclosed long string
37703730
r = parse(s)
37713731
assert(r == e)
37723732

3733+
print("> testing issues...")
3734+
3735+
-- issue #12
3736+
s = [===[
3737+
gl_f_ct = 0
3738+
3739+
function f()
3740+
if gl_f_ct <= 0 then
3741+
gl_f_ct=1
3742+
return 1000
3743+
end
3744+
return -1000
37733745
end
37743746
3747+
print( f("1st call") > f("2nd call") )
3748+
gl_f_ct = 0
3749+
print( f("1st call") < f("2nd call") )
3750+
]===]
3751+
e = [=[
3752+
{ `Set{ { `Id "gl_f_ct" }, { `Number "0" } }, `Set{ { `Id "f" }, { `Function{ { }, { `If{ `Op{ "le", `Id "gl_f_ct", `Number "0" }, { `Set{ { `Id "gl_f_ct" }, { `Number "1" } }, `Return{ `Number "1000" } } }, `Return{ `Op{ "unm", `Number "1000" } } } } } }, `Call{ `Id "print", `Op{ "gt", `Call{ `Id "f", `String "1st call" }, `Call{ `Id "f", `String "2nd call" } } }, `Set{ { `Id "gl_f_ct" }, { `Number "0" } }, `Call{ `Id "print", `Op{ "lt", `Call{ `Id "f", `String "1st call" }, `Call{ `Id "f", `String "2nd call" } } } }
3753+
]=]
3754+
3755+
r = parse(s)
3756+
assert(r == e)
3757+
37753758
print("OK")

0 commit comments

Comments
 (0)