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