1
2if T==nil then
3  (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a')
4  return
5end
6print "testing code generation and optimizations"
7
8
9-- this code gave an error for the code checker
10do
11  local function f (a)
12  for k,v,w in a do end
13  end
14end
15
16
17function check (f, ...)
18  local c = T.listcode(f)
19  for i=1, arg.n do
20    -- print(arg[i], c[i])
21    assert(string.find(c[i], '- '..arg[i]..' *%d'))
22  end
23  assert(c[arg.n+2] == nil)
24end
25
26
27function checkequal (a, b)
28  a = T.listcode(a)
29  b = T.listcode(b)
30  for i = 1, table.getn(a) do
31    a[i] = string.gsub(a[i], '%b()', '')   -- remove line number
32    b[i] = string.gsub(b[i], '%b()', '')   -- remove line number
33    assert(a[i] == b[i])
34  end
35end
36
37
38-- some basic instructions
39check(function ()
40  (function () end){f()}
41end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN')
42
43
44-- sequence of LOADNILs
45check(function ()
46  local a,b,c
47  local d; local e;
48  a = nil; d=nil
49end, 'RETURN')
50
51
52-- single return
53check (function (a,b,c) return a end, 'RETURN')
54
55
56-- infinite loops
57check(function () while true do local a = -1 end end,
58'LOADK', 'JMP', 'RETURN')
59
60check(function () while 1 do local a = -1 end end,
61'LOADK', 'JMP', 'RETURN')
62
63check(function () repeat local x = 1 until false end,
64'LOADK', 'JMP', 'RETURN')
65
66check(function () repeat local x until nil end,
67'LOADNIL', 'JMP', 'RETURN')
68
69check(function () repeat local x = 1 until true end,
70'LOADK', 'RETURN')
71
72
73-- concat optimization
74check(function (a,b,c,d) return a..b..c..d end,
75  'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
76
77-- not
78check(function () return not not nil end, 'LOADBOOL', 'RETURN')
79check(function () return not not false end, 'LOADBOOL', 'RETURN')
80check(function () return not not true end, 'LOADBOOL', 'RETURN')
81check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
82
83-- direct access to locals
84check(function ()
85  local a,b,c,d
86  a = b*2
87  c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
88end,
89  'MUL',
90  'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
91    'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
92
93
94-- direct access to constants
95check(function ()
96  local a,b
97  a.x = 0
98  a.x = b
99  a[b] = 'y'
100  a = 1 - a
101  b = 1/a
102  b = 5+4
103  a[true] = false
104end,
105  'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
106  'SETTABLE', 'RETURN')
107
108local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end
109
110check(f, 'LOADK', 'RETURN')
111assert(f() == -5)
112
113check(function ()
114  local a,b,c
115  b[c], a = c, b
116  b[a], a = c, b
117  a, b = c, a
118  a = a
119end,
120  'MOVE', 'MOVE', 'SETTABLE',
121  'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
122  'MOVE', 'MOVE', 'MOVE',
123  -- no code for a = a
124  'RETURN')
125
126
127-- x == nil , x ~= nil
128checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
129           function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
130
131check(function () if a==nil then a=1 end end,
132'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN')
133
134-- de morgan
135checkequal(function () local a; if not (a or b) then b=a end end,
136           function () local a; if (not a and not b) then b=a end end)
137
138checkequal(function (l) local a; return 0 <= a and a <= l end,
139           function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
140
141
142print 'OK'
143
144