123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- if T==nil then
- (Message or print)('\a\n >>> testC not active: skipping opcode tests <<<\n\a')
- return
- end
- print "testing code generation and optimizations"
- -- this code gave an error for the code checker
- do
- local function f (a)
- for k,v,w in a do end
- end
- end
- function check (f, ...)
- local c = T.listcode(f)
- for i=1, arg.n do
- -- print(arg[i], c[i])
- assert(string.find(c[i], '- '..arg[i]..' *%d'))
- end
- assert(c[arg.n+2] == nil)
- end
- function checkequal (a, b)
- a = T.listcode(a)
- b = T.listcode(b)
- for i = 1, table.getn(a) do
- a[i] = string.gsub(a[i], '%b()', '') -- remove line number
- b[i] = string.gsub(b[i], '%b()', '') -- remove line number
- assert(a[i] == b[i])
- end
- end
- -- some basic instructions
- check(function ()
- (function () end){f()}
- end, 'CLOSURE', 'NEWTABLE', 'GETGLOBAL', 'CALL', 'SETLIST', 'CALL', 'RETURN')
- -- sequence of LOADNILs
- check(function ()
- local a,b,c
- local d; local e;
- a = nil; d=nil
- end, 'RETURN')
- -- single return
- check (function (a,b,c) return a end, 'RETURN')
- -- infinite loops
- check(function () while true do local a = -1 end end,
- 'LOADK', 'JMP', 'RETURN')
- check(function () while 1 do local a = -1 end end,
- 'LOADK', 'JMP', 'RETURN')
- check(function () repeat local x = 1 until false end,
- 'LOADK', 'JMP', 'RETURN')
- check(function () repeat local x until nil end,
- 'LOADNIL', 'JMP', 'RETURN')
- check(function () repeat local x = 1 until true end,
- 'LOADK', 'RETURN')
- -- concat optimization
- check(function (a,b,c,d) return a..b..c..d end,
- 'MOVE', 'MOVE', 'MOVE', 'MOVE', 'CONCAT', 'RETURN')
- -- not
- check(function () return not not nil end, 'LOADBOOL', 'RETURN')
- check(function () return not not false end, 'LOADBOOL', 'RETURN')
- check(function () return not not true end, 'LOADBOOL', 'RETURN')
- check(function () return not not 1 end, 'LOADBOOL', 'RETURN')
- -- direct access to locals
- check(function ()
- local a,b,c,d
- a = b*2
- c[4], a[b] = -((a + d/-20.5 - a[b]) ^ a.x), b
- end,
- 'MUL',
- 'DIV', 'ADD', 'GETTABLE', 'SUB', 'GETTABLE', 'POW',
- 'UNM', 'SETTABLE', 'SETTABLE', 'RETURN')
- -- direct access to constants
- check(function ()
- local a,b
- a.x = 0
- a.x = b
- a[b] = 'y'
- a = 1 - a
- b = 1/a
- b = 5+4
- a[true] = false
- end,
- 'SETTABLE', 'SETTABLE', 'SETTABLE', 'SUB', 'DIV', 'LOADK',
- 'SETTABLE', 'RETURN')
- local function f () return -((2^8 + -(-1)) % 8)/2 * 4 - 3 end
- check(f, 'LOADK', 'RETURN')
- assert(f() == -5)
- check(function ()
- local a,b,c
- b[c], a = c, b
- b[a], a = c, b
- a, b = c, a
- a = a
- end,
- 'MOVE', 'MOVE', 'SETTABLE',
- 'MOVE', 'MOVE', 'MOVE', 'SETTABLE',
- 'MOVE', 'MOVE', 'MOVE',
- -- no code for a = a
- 'RETURN')
- -- x == nil , x ~= nil
- checkequal(function () if (a==nil) then a=1 end; if a~=nil then a=1 end end,
- function () if (a==9) then a=1 end; if a~=9 then a=1 end end)
- check(function () if a==nil then a=1 end end,
- 'GETGLOBAL', 'EQ', 'JMP', 'LOADK', 'SETGLOBAL', 'RETURN')
- -- de morgan
- checkequal(function () local a; if not (a or b) then b=a end end,
- function () local a; if (not a and not b) then b=a end end)
- checkequal(function (l) local a; return 0 <= a and a <= l end,
- function (l) local a; return not (not(a >= 0) or not(a <= l)) end)
- print 'OK'
|