code.lua 3.2 KB

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