DrawingJhon

Loadstring

Nov 17th, 2020 (edited)
1,452
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 188.88 KB | None | 0 0
  1. script = script or Instance.new("Script")
  2. script.Name = "Loadstring"
  3.  
  4. local RealScript = script
  5. local RequireCache = {}
  6. function require(module)
  7.     local name = module.Name
  8.     local func = getfenv()[name]
  9.     return RequireCache[name] or (function()
  10.         local result = func()
  11.         RequireCache[name] = result
  12.         return result
  13.     end)()
  14. end
  15.  
  16. function Loadstring()
  17.  
  18. local Dependencies = {
  19.     'FiOne',
  20.     'LuaK',
  21.     'LuaP',
  22.     'LuaU',
  23.     'LuaX',
  24.     'LuaY',
  25.     'LuaZ',
  26. }
  27.  
  28. for _,v in next, Dependencies do script:WaitForChild(v) end
  29.  
  30. local LuaX = require(script.LuaX)
  31. local LuaY = require(script.LuaY)
  32. local LuaZ = require(script.LuaZ)
  33. local LuaU = require(script.LuaU)
  34. local FiOne = require(script.FiOne)
  35.  
  36. LuaX:init()
  37.  
  38. local LuaState = {}
  39.  
  40. --getfenv().script = nil
  41.  
  42. return function(str,env)
  43.     local f,writer,buff,name
  44.     local env = env or getfenv(2)
  45.     local name = (env.script and env.script:GetFullName())
  46.    
  47.     local ran,error = pcall(function()
  48.        
  49.         local zio = LuaZ:init(LuaZ:make_getS(str), nil)
  50.         if not zio then return error("Failed to initalize LuaZ") end
  51.        
  52.         local func = LuaY:parser(LuaState, zio, nil, name or "nil")
  53.         writer, buff = LuaU:make_setS()
  54.         LuaU:dump(LuaState, func, writer, buff)
  55.        
  56.         f = FiOne.wrap_lua(FiOne.stm_lua(buff.data), env)
  57.     end)
  58.    
  59.     if ran then
  60.         return f,buff.data
  61.     else
  62.         return nil,error
  63.     end
  64. end
  65. end
  66.  
  67. function FiOne()
  68.  
  69. local script = script.FiOne
  70. local bit = bit or bit32 or require('bit')
  71. local stm_lua_bytecode
  72. local wrap_lua_func
  73. local stm_lua_func
  74.  
  75. -- SETLIST config
  76. local FIELDS_PER_FLUSH = 50
  77.  
  78. -- opcode types for getting values
  79. local opcode_t = {
  80.     [0] = 'ABC',
  81.     'ABx',
  82.     'ABC',
  83.     'ABC',
  84.     'ABC',
  85.     'ABx',
  86.     'ABC',
  87.     'ABx',
  88.     'ABC',
  89.     'ABC',
  90.     'ABC',
  91.     'ABC',
  92.     'ABC',
  93.     'ABC',
  94.     'ABC',
  95.     'ABC',
  96.     'ABC',
  97.     'ABC',
  98.     'ABC',
  99.     'ABC',
  100.     'ABC',
  101.     'ABC',
  102.     'AsBx',
  103.     'ABC',
  104.     'ABC',
  105.     'ABC',
  106.     'ABC',
  107.     'ABC',
  108.     'ABC',
  109.     'ABC',
  110.     'ABC',
  111.     'AsBx',
  112.     'AsBx',
  113.     'ABC',
  114.     'ABC',
  115.     'ABC',
  116.     'ABx',
  117.     'ABC',
  118. }
  119.  
  120. local opcode_m = {
  121.     [0] = {b = 'OpArgR', c = 'OpArgN'},
  122.     {b = 'OpArgK', c = 'OpArgN'},
  123.     {b = 'OpArgU', c = 'OpArgU'},
  124.     {b = 'OpArgR', c = 'OpArgN'},
  125.     {b = 'OpArgU', c = 'OpArgN'},
  126.     {b = 'OpArgK', c = 'OpArgN'},
  127.     {b = 'OpArgR', c = 'OpArgK'},
  128.     {b = 'OpArgK', c = 'OpArgN'},
  129.     {b = 'OpArgU', c = 'OpArgN'},
  130.     {b = 'OpArgK', c = 'OpArgK'},
  131.     {b = 'OpArgU', c = 'OpArgU'},
  132.     {b = 'OpArgR', c = 'OpArgK'},
  133.     {b = 'OpArgK', c = 'OpArgK'},
  134.     {b = 'OpArgK', c = 'OpArgK'},
  135.     {b = 'OpArgK', c = 'OpArgK'},
  136.     {b = 'OpArgK', c = 'OpArgK'},
  137.     {b = 'OpArgK', c = 'OpArgK'},
  138.     {b = 'OpArgK', c = 'OpArgK'},
  139.     {b = 'OpArgR', c = 'OpArgN'},
  140.     {b = 'OpArgR', c = 'OpArgN'},
  141.     {b = 'OpArgR', c = 'OpArgN'},
  142.     {b = 'OpArgR', c = 'OpArgR'},
  143.     {b = 'OpArgR', c = 'OpArgN'},
  144.     {b = 'OpArgK', c = 'OpArgK'},
  145.     {b = 'OpArgK', c = 'OpArgK'},
  146.     {b = 'OpArgK', c = 'OpArgK'},
  147.     {b = 'OpArgR', c = 'OpArgU'},
  148.     {b = 'OpArgR', c = 'OpArgU'},
  149.     {b = 'OpArgU', c = 'OpArgU'},
  150.     {b = 'OpArgU', c = 'OpArgU'},
  151.     {b = 'OpArgU', c = 'OpArgN'},
  152.     {b = 'OpArgR', c = 'OpArgN'},
  153.     {b = 'OpArgR', c = 'OpArgN'},
  154.     {b = 'OpArgN', c = 'OpArgU'},
  155.     {b = 'OpArgU', c = 'OpArgU'},
  156.     {b = 'OpArgN', c = 'OpArgN'},
  157.     {b = 'OpArgU', c = 'OpArgN'},
  158.     {b = 'OpArgU', c = 'OpArgN'},
  159. }
  160.  
  161. -- int rd_int_basic(string src, int s, int e, int d)
  162. -- @src - Source binary string
  163. -- @s - Start index of a little endian integer
  164. -- @e - End index of the integer
  165. -- @d - Direction of the loop
  166. local function rd_int_basic(src, s, e, d)
  167.     local num = 0
  168.  
  169.     -- if bb[l] > 127 then -- signed negative
  170.     --  num = num - 256 ^ l
  171.     --  bb[l] = bb[l] - 128
  172.     -- end
  173.  
  174.     for i = s, e, d do num = num + src:byte(i, i) * 256 ^ (i - s) end
  175.  
  176.     return num
  177. end
  178.  
  179. -- float rd_flt_basic(byte f1..8)
  180. -- @f1..4 - The 4 bytes composing a little endian float
  181. local function rd_flt_basic(f1, f2, f3, f4)
  182.     local sign = bit.rshift(f4, 7)
  183.     local exp = bit.rshift(f3, 7) + bit.lshift(bit.band(f4, 0x7F), 1)
  184.     local frac = f1 + bit.lshift(f2, 8) + bit.lshift(bit.band(f3, 0x7F), 16)
  185.     local normal = 1
  186.  
  187.     if exp == 0 then
  188.         if frac == 0 then
  189.             return sign * 0
  190.         else
  191.             normal = 0
  192.             exp = 1
  193.         end
  194.     elseif exp == 0x7F then
  195.         if frac == 0 then
  196.             return sign * (1 / 0)
  197.         else
  198.             return sign * (0 / 0)
  199.         end
  200.     end
  201.  
  202.     return (-1) ^ sign * 2 ^ (exp - 127) * (1 + normal / 2 ^ 23)
  203. end
  204.  
  205. -- double rd_dbl_basic(byte f1..8)
  206. -- @f1..8 - The 8 bytes composing a little endian double
  207. local function rd_dbl_basic(f1, f2, f3, f4, f5, f6, f7, f8)
  208.     local sign = bit.rshift(f8, 7)
  209.     local exp = bit.lshift(bit.band(f8, 0x7F), 4) + bit.rshift(f7, 4)
  210.     local frac = bit.band(f7, 0x0F) * 2 ^ 48
  211.     local normal = 1
  212.  
  213.     frac = frac + (f6 * 2 ^ 40) + (f5 * 2 ^ 32) + (f4 * 2 ^ 24) + (f3 * 2 ^ 16) + (f2 * 2 ^ 8) + f1 -- help
  214.  
  215.     if exp == 0 then
  216.         if frac == 0 then
  217.             return sign * 0
  218.         else
  219.             normal = 0
  220.             exp = 1
  221.         end
  222.     elseif exp == 0x7FF then
  223.         if frac == 0 then
  224.             return sign * (1 / 0)
  225.         else
  226.             return sign * (0 / 0)
  227.         end
  228.     end
  229.  
  230.     return (-1) ^ sign * 2 ^ (exp - 1023) * (normal + frac / 2 ^ 52)
  231. end
  232.  
  233. -- int rd_int_le(string src, int s, int e)
  234. -- @src - Source binary string
  235. -- @s - Start index of a little endian integer
  236. -- @e - End index of the integer
  237. local function rd_int_le(src, s, e) return rd_int_basic(src, s, e - 1, 1) end
  238.  
  239. -- int rd_int_be(string src, int s, int e)
  240. -- @src - Source binary string
  241. -- @s - Start index of a big endian integer
  242. -- @e - End index of the integer
  243. local function rd_int_be(src, s, e) return rd_int_basic(src, e - 1, s, -1) end
  244.  
  245. -- float rd_flt_le(string src, int s)
  246. -- @src - Source binary string
  247. -- @s - Start index of little endian float
  248. local function rd_flt_le(src, s) return rd_flt_basic(src:byte(s, s + 3)) end
  249.  
  250. -- float rd_flt_be(string src, int s)
  251. -- @src - Source binary string
  252. -- @s - Start index of big endian float
  253. local function rd_flt_be(src, s)
  254.     local f1, f2, f3, f4 = src:byte(s, s + 3)
  255.     return rd_flt_basic(f4, f3, f2, f1)
  256. end
  257.  
  258. -- double rd_dbl_le(string src, int s)
  259. -- @src - Source binary string
  260. -- @s - Start index of little endian double
  261. local function rd_dbl_le(src, s) return rd_dbl_basic(src:byte(s, s + 7)) end
  262.  
  263. -- double rd_dbl_be(string src, int s)
  264. -- @src - Source binary string
  265. -- @s - Start index of big endian double
  266. local function rd_dbl_be(src, s)
  267.     local f1, f2, f3, f4, f5, f6, f7, f8 = src:byte(s, s + 7) -- same
  268.     return rd_dbl_basic(f8, f7, f6, f5, f4, f3, f2, f1)
  269. end
  270.  
  271. -- to avoid nested ifs in deserializing
  272. local float_types = {
  273.     [4] = {little = rd_flt_le, big = rd_flt_be},
  274.     [8] = {little = rd_dbl_le, big = rd_dbl_be},
  275. }
  276.  
  277. -- byte stm_byte(Stream S)
  278. -- @S - Stream object to read from
  279. local function stm_byte(S)
  280.     local idx = S.index
  281.     local bt = S.source:byte(idx, idx)
  282.  
  283.     S.index = idx + 1
  284.     return bt
  285. end
  286.  
  287. -- string stm_string(Stream S, int len)
  288. -- @S - Stream object to read from
  289. -- @len - Length of string being read
  290. local function stm_string(S, len)
  291.     local pos = S.index + len
  292.     local str = S.source:sub(S.index, pos - 1)
  293.  
  294.     S.index = pos
  295.     return str
  296. end
  297.  
  298. -- string stm_lstring(Stream S)
  299. -- @S - Stream object to read from
  300. local function stm_lstring(S)
  301.     local len = S:s_szt()
  302.     local str
  303.  
  304.     if len ~= 0 then str = stm_string(S, len):sub(1, -2) end
  305.  
  306.     return str
  307. end
  308.  
  309. -- fn cst_int_rdr(string src, int len, fn func)
  310. -- @len - Length of type for reader
  311. -- @func - Reader callback
  312. local function cst_int_rdr(len, func)
  313.     return function(S)
  314.         local pos = S.index + len
  315.         local int = func(S.source, S.index, pos)
  316.         S.index = pos
  317.  
  318.         return int
  319.     end
  320. end
  321.  
  322. -- fn cst_flt_rdr(string src, int len, fn func)
  323. -- @len - Length of type for reader
  324. -- @func - Reader callback
  325. local function cst_flt_rdr(len, func)
  326.     return function(S)
  327.         local flt = func(S.source, S.index)
  328.         S.index = S.index + len
  329.  
  330.         return flt
  331.     end
  332. end
  333.  
  334. local function stm_instructions(S)
  335.     local size = S:s_int()
  336.     local code = {}
  337.  
  338.     for i = 1, size do
  339.         local ins = S:s_ins()
  340.         local op = bit.band(ins, 0x3F)
  341.         local args = opcode_t[op]
  342.         local mode = opcode_m[op]
  343.         local data = {value = ins, op = op, A = bit.band(bit.rshift(ins, 6), 0xFF)}
  344.  
  345.         if args == 'ABC' then
  346.             data.B = bit.band(bit.rshift(ins, 23), 0x1FF)
  347.             data.C = bit.band(bit.rshift(ins, 14), 0x1FF)
  348.             data.is_KB = mode.b == 'OpArgK' and data.B > 0xFF -- post process optimization
  349.             data.is_KC = mode.c == 'OpArgK' and data.C > 0xFF
  350.         elseif args == 'ABx' then
  351.             data.Bx = bit.band(bit.rshift(ins, 14), 0x3FFFF)
  352.             data.is_K = mode.b == 'OpArgK'
  353.         elseif args == 'AsBx' then
  354.             data.sBx = bit.band(bit.rshift(ins, 14), 0x3FFFF) - 131071
  355.         end
  356.  
  357.         code[i] = data
  358.     end
  359.  
  360.     return code
  361. end
  362.  
  363. local function stm_constants(S)
  364.     local size = S:s_int()
  365.     local consts = {}
  366.  
  367.     for i = 1, size do
  368.         local tt = stm_byte(S)
  369.         local k
  370.  
  371.         if tt == 1 then
  372.             k = stm_byte(S) ~= 0
  373.         elseif tt == 3 then
  374.             k = S:s_num()
  375.         elseif tt == 4 then
  376.             k = stm_lstring(S)
  377.         end
  378.  
  379.         consts[i] = k -- offset +1 during instruction decode
  380.     end
  381.  
  382.     return consts
  383. end
  384.  
  385. local function stm_subfuncs(S, src)
  386.     local size = S:s_int()
  387.     local sub = {}
  388.  
  389.     for i = 1, size do
  390.         sub[i] = stm_lua_func(S, src) -- offset +1 in CLOSURE
  391.     end
  392.  
  393.     return sub
  394. end
  395.  
  396. local function stm_lineinfo(S)
  397.     local size = S:s_int()
  398.     local lines = {}
  399.  
  400.     for i = 1, size do lines[i] = S:s_int() end
  401.  
  402.     return lines
  403. end
  404.  
  405. local function stm_locvars(S)
  406.     local size = S:s_int()
  407.     local locvars = {}
  408.  
  409.     for i = 1, size do locvars[i] = {varname = stm_lstring(S), startpc = S:s_int(), endpc = S:s_int()} end
  410.  
  411.     return locvars
  412. end
  413.  
  414. local function stm_upvals(S)
  415.     local size = S:s_int()
  416.     local upvals = {}
  417.  
  418.     for i = 1, size do upvals[i] = stm_lstring(S) end
  419.  
  420.     return upvals
  421. end
  422.  
  423. function stm_lua_func(S, psrc)
  424.     local proto = {}
  425.     local src = stm_lstring(S) or psrc -- source is propagated
  426.  
  427.     proto.source = src -- source name
  428.  
  429.     S:s_int() -- line defined
  430.     S:s_int() -- last line defined
  431.  
  432.     proto.numupvals = stm_byte(S) -- num upvalues
  433.     proto.numparams = stm_byte(S) -- num params
  434.  
  435.     stm_byte(S) -- vararg flag
  436.     stm_byte(S) -- max stack size
  437.  
  438.     proto.code = stm_instructions(S)
  439.     proto.const = stm_constants(S)
  440.     proto.subs = stm_subfuncs(S, src)
  441.     proto.lines = stm_lineinfo(S)
  442.  
  443.     stm_locvars(S)
  444.     stm_upvals(S)
  445.  
  446.     -- post process optimization
  447.     for _, v in ipairs(proto.code) do
  448.         if v.is_K then
  449.             v.const = proto.const[v.Bx + 1] -- offset for 1 based index
  450.         else
  451.             if v.is_KB then v.const_B = proto.const[v.B - 0xFF] end
  452.  
  453.             if v.is_KC then v.const_C = proto.const[v.C - 0xFF] end
  454.         end
  455.     end
  456.  
  457.     return proto
  458. end
  459.  
  460. function stm_lua_bytecode(src)
  461.     -- func reader
  462.     local rdr_func
  463.  
  464.     -- header flags
  465.     local little
  466.     local size_int
  467.     local size_szt
  468.     local size_ins
  469.     local size_num
  470.     local flag_int
  471.  
  472.     -- stream object
  473.     local stream = {
  474.         -- data
  475.         index = 1,
  476.         source = src,
  477.     }
  478.  
  479.     assert(stm_string(stream, 4) == '\27Lua', 'invalid Lua signature')
  480.     assert(stm_byte(stream) == 0x51, 'invalid Lua version')
  481.     assert(stm_byte(stream) == 0, 'invalid Lua format')
  482.  
  483.     little = stm_byte(stream) ~= 0
  484.     size_int = stm_byte(stream)
  485.     size_szt = stm_byte(stream)
  486.     size_ins = stm_byte(stream)
  487.     size_num = stm_byte(stream)
  488.     flag_int = stm_byte(stream) ~= 0
  489.  
  490.     rdr_func = little and rd_int_le or rd_int_be
  491.     stream.s_int = cst_int_rdr(size_int, rdr_func)
  492.     stream.s_szt = cst_int_rdr(size_szt, rdr_func)
  493.     stream.s_ins = cst_int_rdr(size_ins, rdr_func)
  494.  
  495.     if flag_int then
  496.         stream.s_num = cst_int_rdr(size_num, rdr_func)
  497.     elseif float_types[size_num] then
  498.         stream.s_num = cst_flt_rdr(size_num, float_types[size_num][little and 'little' or 'big'])
  499.     else
  500.         error('unsupported float size')
  501.     end
  502.  
  503.     return stm_lua_func(stream, '@virtual')
  504. end
  505.  
  506. local function close_lua_upvalues(list, index)
  507.     for i, uv in pairs(list) do
  508.         if uv.index >= index then
  509.             uv.value = uv.store[uv.index] -- store value
  510.             uv.store = uv
  511.             uv.index = 'value' -- self reference
  512.             list[i] = nil
  513.         end
  514.     end
  515. end
  516.  
  517. local function open_lua_upvalue(list, index, stack)
  518.     local prev = list[index]
  519.  
  520.     if not prev then
  521.         prev = {index = index, store = stack}
  522.         list[index] = prev
  523.     end
  524.  
  525.     return prev
  526. end
  527.  
  528. local function wrap_lua_variadic(...) return select('#', ...), {...} end
  529.  
  530. local function on_lua_error(exst, err)
  531.     local src = exst.source
  532.     local line = exst.lines[exst.pc - 1]
  533.     local psrc, pline, pmsg = err:match('^(.-):(%d+):%s+(.+)')
  534.     local fmt = '%s:%i: [%s:%i] %s'
  535.  
  536.     line = line or '0'
  537.     psrc = psrc or '?'
  538.     pline = pline or '0'
  539.     pmsg = pmsg or err
  540.  
  541.     error(string.format(fmt, src, line, psrc, pline, pmsg), 0)
  542. end
  543.  
  544. local function exec_lua_func(exst)
  545.     -- localize for easy lookup
  546.     local code = exst.code
  547.     local subs = exst.subs
  548.     local env = exst.env
  549.     local upvs = exst.upvals
  550.     local vargs = exst.varargs
  551.  
  552.     -- state variables
  553.     local stktop = -1
  554.     local openupvs = {}
  555.     local stack = exst.stack
  556.     local pc = exst.pc
  557.  
  558.     while true do
  559.         local inst = code[pc]
  560.         local op = inst.op
  561.         pc = pc + 1
  562.  
  563.         if _G.stop then error("Script ended") end
  564.         if op < 19 then
  565.             if op < 9 then
  566.                 if op < 4 then
  567.                     if op < 2 then
  568.                         if op < 1 then
  569.                             --[[0 MOVE]]
  570.                             stack[inst.A] = stack[inst.B]
  571.                         else
  572.                             --[[1 LOADK]]
  573.                             stack[inst.A] = inst.const
  574.                         end
  575.                     elseif op > 2 then
  576.                         --[[3 LOADNIL]]
  577.                         for i = inst.A, inst.B do stack[i] = nil end
  578.                     else
  579.                         --[[2 LOADBOOL]]
  580.                         stack[inst.A] = inst.B ~= 0
  581.  
  582.                         if inst.C ~= 0 then pc = pc + 1 end
  583.                     end
  584.                 elseif op > 4 then
  585.                     if op < 7 then
  586.                         if op < 6 then
  587.                             --[[5 GETGLOBAL]]
  588.                             stack[inst.A] = env[inst.const]
  589.                         else
  590.                             --[[6 GETTABLE]]
  591.                             local index
  592.  
  593.                             if inst.is_KC then
  594.                                 index = inst.const_C
  595.                             else
  596.                                 index = stack[inst.C]
  597.                             end
  598.  
  599.                             stack[inst.A] = stack[inst.B][index]
  600.                         end
  601.                     elseif op > 7 then
  602.                         --[[8 SETUPVAL]]
  603.                         local uv = upvs[inst.B]
  604.  
  605.                         uv.store[uv.index] = stack[inst.A]
  606.                     else
  607.                         --[[7 SETGLOBAL]]
  608.                         env[inst.const] = stack[inst.A]
  609.                     end
  610.                 else
  611.                     --[[4 GETUPVAL]]
  612.                     local uv = upvs[inst.B]
  613.  
  614.                     stack[inst.A] = uv.store[uv.index]
  615.                 end
  616.             elseif op > 9 then
  617.                 if op < 14 then
  618.                     if op < 12 then
  619.                         if op < 11 then
  620.                             --[[10 NEWTABLE]]
  621.                             stack[inst.A] = {}
  622.                         else
  623.                             --[[11 SELF]]
  624.                             local A = inst.A
  625.                             local B = inst.B
  626.                             local index
  627.  
  628.                             if inst.is_KC then
  629.                                 index = inst.const_C
  630.                             else
  631.                                 index = stack[inst.C]
  632.                             end
  633.  
  634.                             stack[A + 1] = stack[B]
  635.                             stack[A] = stack[B][index]
  636.                         end
  637.                     elseif op > 12 then
  638.                         --[[13 SUB]]
  639.                         local lhs, rhs
  640.  
  641.                         if inst.is_KB then
  642.                             lhs = inst.const_B
  643.                         else
  644.                             lhs = stack[inst.B]
  645.                         end
  646.  
  647.                         if inst.is_KC then
  648.                             rhs = inst.const_C
  649.                         else
  650.                             rhs = stack[inst.C]
  651.                         end
  652.  
  653.                         stack[inst.A] = lhs - rhs
  654.                     else
  655.                         --[[12 ADD]]
  656.                         local lhs, rhs
  657.  
  658.                         if inst.is_KB then
  659.                             lhs = inst.const_B
  660.                         else
  661.                             lhs = stack[inst.B]
  662.                         end
  663.  
  664.                         if inst.is_KC then
  665.                             rhs = inst.const_C
  666.                         else
  667.                             rhs = stack[inst.C]
  668.                         end
  669.  
  670.                         stack[inst.A] = lhs + rhs
  671.                     end
  672.                 elseif op > 14 then
  673.                     if op < 17 then
  674.                         if op < 16 then
  675.                             --[[15 DIV]]
  676.                             local lhs, rhs
  677.  
  678.                             if inst.is_KB then
  679.                                 lhs = inst.const_B
  680.                             else
  681.                                 lhs = stack[inst.B]
  682.                             end
  683.  
  684.                             if inst.is_KC then
  685.                                 rhs = inst.const_C
  686.                             else
  687.                                 rhs = stack[inst.C]
  688.                             end
  689.  
  690.                             stack[inst.A] = lhs / rhs
  691.                         else
  692.                             --[[16 MOD]]
  693.                             local lhs, rhs
  694.  
  695.                             if inst.is_KB then
  696.                                 lhs = inst.const_B
  697.                             else
  698.                                 lhs = stack[inst.B]
  699.                             end
  700.  
  701.                             if inst.is_KC then
  702.                                 rhs = inst.const_C
  703.                             else
  704.                                 rhs = stack[inst.C]
  705.                             end
  706.  
  707.                             stack[inst.A] = lhs % rhs
  708.                         end
  709.                     elseif op > 17 then
  710.                         --[[18 UNM]]
  711.                         stack[inst.A] = -stack[inst.B]
  712.                     else
  713.                         --[[17 POW]]
  714.                         local lhs, rhs
  715.  
  716.                         if inst.is_KB then
  717.                             lhs = inst.const_B
  718.                         else
  719.                             lhs = stack[inst.B]
  720.                         end
  721.  
  722.                         if inst.is_KC then
  723.                             rhs = inst.const_C
  724.                         else
  725.                             rhs = stack[inst.C]
  726.                         end
  727.  
  728.                         stack[inst.A] = lhs ^ rhs
  729.                     end
  730.                 else
  731.                     --[[14 MUL]]
  732.                     local lhs, rhs
  733.  
  734.                     if inst.is_KB then
  735.                         lhs = inst.const_B
  736.                     else
  737.                         lhs = stack[inst.B]
  738.                     end
  739.  
  740.                     if inst.is_KC then
  741.                         rhs = inst.const_C
  742.                     else
  743.                         rhs = stack[inst.C]
  744.                     end
  745.  
  746.                     stack[inst.A] = lhs * rhs
  747.                 end
  748.             else
  749.                 --[[9 SETTABLE]]
  750.                 local index, value
  751.  
  752.                 if inst.is_KB then
  753.                     index = inst.const_B
  754.                 else
  755.                     index = stack[inst.B]
  756.                 end
  757.  
  758.                 if inst.is_KC then
  759.                     value = inst.const_C
  760.                 else
  761.                     value = stack[inst.C]
  762.                 end
  763.  
  764.                 stack[inst.A][index] = value
  765.             end
  766.         elseif op > 19 then
  767.             if op < 29 then
  768.                 if op < 24 then
  769.                     if op < 22 then
  770.                         if op < 21 then
  771.                             --[[20 LEN]]
  772.                             stack[inst.A] = #stack[inst.B]
  773.                         else
  774.                             --[[21 CONCAT]]
  775.                             local str = stack[inst.B]
  776.  
  777.                             for i = inst.B + 1, inst.C do str = str .. stack[i] end
  778.  
  779.                             stack[inst.A] = str
  780.                         end
  781.                     elseif op > 22 then
  782.                         --[[23 EQ]]
  783.                         local lhs, rhs
  784.  
  785.                         if inst.is_KB then
  786.                             lhs = inst.const_B
  787.                         else
  788.                             lhs = stack[inst.B]
  789.                         end
  790.  
  791.                         if inst.is_KC then
  792.                             rhs = inst.const_C
  793.                         else
  794.                             rhs = stack[inst.C]
  795.                         end
  796.  
  797.                         if (lhs == rhs) ~= (inst.A ~= 0) then pc = pc + 1 end
  798.                     else
  799.                         --[[22 JMP]]
  800.                         pc = pc + inst.sBx
  801.                     end
  802.                 elseif op > 24 then
  803.                     if op < 27 then
  804.                         if op < 26 then
  805.                             --[[25 LE]]
  806.                             local lhs, rhs
  807.  
  808.                             if inst.is_KB then
  809.                                 lhs = inst.const_B
  810.                             else
  811.                                 lhs = stack[inst.B]
  812.                             end
  813.  
  814.                             if inst.is_KC then
  815.                                 rhs = inst.const_C
  816.                             else
  817.                                 rhs = stack[inst.C]
  818.                             end
  819.  
  820.                             if (lhs <= rhs) ~= (inst.A ~= 0) then pc = pc + 1 end
  821.                         else
  822.                             --[[26 TEST]]
  823.                             if (not stack[inst.A]) == (inst.C ~= 0) then pc = pc + 1 end
  824.                         end
  825.                     elseif op > 27 then
  826.                         --[[28 CALL]]
  827.                         local A = inst.A
  828.                         local B = inst.B
  829.                         local C = inst.C
  830.                         local params
  831.                         local sz_vals, l_vals
  832.  
  833.                         if B == 0 then
  834.                             params = stktop - A
  835.                         else
  836.                             params = B - 1
  837.                         end
  838.  
  839.                         sz_vals, l_vals = wrap_lua_variadic(stack[A](unpack(stack, A + 1, A + params)))
  840.  
  841.                         if C == 0 then
  842.                             stktop = A + sz_vals - 1
  843.                         else
  844.                             sz_vals = C - 1
  845.                         end
  846.  
  847.                         for i = 1, sz_vals do stack[A + i - 1] = l_vals[i] end
  848.                     else
  849.                         --[[27 TESTSET]]
  850.                         local A = inst.A
  851.                         local B = inst.B
  852.  
  853.                         if (not stack[B]) == (inst.C ~= 0) then
  854.                             pc = pc + 1
  855.                         else
  856.                             stack[A] = stack[B]
  857.                         end
  858.                     end
  859.                 else
  860.                     --[[24 LT]]
  861.                     local lhs, rhs
  862.  
  863.                     if inst.is_KB then
  864.                         lhs = inst.const_B
  865.                     else
  866.                         lhs = stack[inst.B]
  867.                     end
  868.  
  869.                     if inst.is_KC then
  870.                         rhs = inst.const_C
  871.                     else
  872.                         rhs = stack[inst.C]
  873.                     end
  874.  
  875.                     if (lhs < rhs) ~= (inst.A ~= 0) then pc = pc + 1 end
  876.                 end
  877.             elseif op > 29 then
  878.                 if op < 34 then
  879.                     if op < 32 then
  880.                         if op < 31 then
  881.                             --[[30 RETURN]]
  882.                             local A = inst.A
  883.                             local B = inst.B
  884.                             local vals = {}
  885.                             local size
  886.  
  887.                             if B == 0 then
  888.                                 size = stktop - A + 1
  889.                             else
  890.                                 size = B - 1
  891.                             end
  892.  
  893.                             for i = 1, size do vals[i] = stack[A + i - 1] end
  894.  
  895.                             close_lua_upvalues(openupvs, math.huge)
  896.                             return size, vals
  897.                         else
  898.                             --[[31 FORLOOP]]
  899.                             local A = inst.A
  900.                             local step = stack[A + 2]
  901.                             local index = stack[A] + step
  902.                             local limit = stack[A + 1]
  903.                             local loops
  904.  
  905.                             if step == math.abs(step) then
  906.                                 loops = index <= limit
  907.                             else
  908.                                 loops = index >= limit
  909.                             end
  910.  
  911.                             if loops then
  912.                                 stack[inst.A] = index
  913.                                 stack[inst.A + 3] = index
  914.                                 pc = pc + inst.sBx
  915.                             end
  916.                         end
  917.                     elseif op > 32 then
  918.                         --[[33 TFORLOOP]]
  919.                         local A = inst.A
  920.                         local func = stack[A]
  921.                         local state = stack[A + 1]
  922.                         local index = stack[A + 2]
  923.                         local base = A + 3
  924.                         local vals
  925.  
  926.                         stack[base + 2] = index
  927.                         stack[base + 1] = state
  928.                         stack[base] = func
  929.  
  930.                         vals = {func(state, index)}
  931.  
  932.                         for i = 1, inst.C do stack[base + i - 1] = vals[i] end
  933.  
  934.                         if stack[base] ~= nil then
  935.                             stack[A + 2] = stack[base]
  936.                         else
  937.                             pc = pc + 1
  938.                         end
  939.                     else
  940.                         --[[32 FORPREP]]
  941.                         local A = inst.A
  942.                         local init, limit, step
  943.  
  944.                         init = assert(tonumber(stack[A]), '`for` initial value must be a number')
  945.                         limit = assert(tonumber(stack[A + 1]), '`for` limit must be a number')
  946.                         step = assert(tonumber(stack[A + 2]), '`for` step must be a number')
  947.  
  948.                         stack[A] = init - step
  949.                         stack[A + 1] = limit
  950.                         stack[A + 2] = step
  951.  
  952.                         pc = pc + inst.sBx
  953.                     end
  954.                 elseif op > 34 then
  955.                     if op < 36 then
  956.                         --[[35 CLOSE]]
  957.                         close_lua_upvalues(openupvs, inst.A)
  958.                     elseif op > 36 then
  959.                         --[[37 VARARG]]
  960.                         local A = inst.A
  961.                         local size = inst.B
  962.  
  963.                         if size == 0 then
  964.                             size = vargs.size
  965.                             stktop = A + size - 1
  966.                         end
  967.  
  968.                         for i = 1, size do stack[A + i - 1] = vargs.list[i] end
  969.                     else
  970.                         --[[36 CLOSURE]]
  971.                         local sub = subs[inst.Bx + 1] -- offset for 1 based index
  972.                         local nups = sub.numupvals
  973.                         local uvlist
  974.  
  975.                         if nups ~= 0 then
  976.                             uvlist = {}
  977.  
  978.                             for i = 1, nups do
  979.                                 local pseudo = code[pc + i - 1]
  980.  
  981.                                 if pseudo.op == 0 then -- @MOVE
  982.                                     uvlist[i - 1] = open_lua_upvalue(openupvs, pseudo.B, stack)
  983.                                 elseif pseudo.op == 4 then -- @GETUPVAL
  984.                                     uvlist[i - 1] = upvs[pseudo.B]
  985.                                 end
  986.                             end
  987.  
  988.                             pc = pc + nups
  989.                         end
  990.  
  991.                         stack[inst.A] = wrap_lua_func(sub, env, uvlist)
  992.                     end
  993.                 else
  994.                     --[[34 SETLIST]]
  995.                     local A = inst.A
  996.                     local C = inst.C
  997.                     local size = inst.B
  998.                     local tab = stack[A]
  999.                     local offset
  1000.  
  1001.                     if size == 0 then size = stktop - A end
  1002.  
  1003.                     if C == 0 then
  1004.                         C = inst[pc].value
  1005.                         pc = pc + 1
  1006.                     end
  1007.  
  1008.                     offset = (C - 1) * FIELDS_PER_FLUSH
  1009.  
  1010.                     for i = 1, size do tab[i + offset] = stack[A + i] end
  1011.                 end
  1012.             else
  1013.                 --[[29 TAILCALL]]
  1014.                 local A = inst.A
  1015.                 local B = inst.B
  1016.                 local params
  1017.  
  1018.                 if B == 0 then
  1019.                     params = stktop - A
  1020.                 else
  1021.                     params = B - 1
  1022.                 end
  1023.  
  1024.                 close_lua_upvalues(openupvs, math.huge)
  1025.                 return wrap_lua_variadic(stack[A](unpack(stack, A + 1, A + params)))
  1026.             end
  1027.         else
  1028.             --[[19 NOT]]
  1029.             stack[inst.A] = not stack[inst.B]
  1030.         end
  1031.  
  1032.         exst.pc = pc
  1033.     end
  1034. end
  1035.  
  1036. function wrap_lua_func(state, env, upvals)
  1037.     local st_code = state.code
  1038.     local st_subs = state.subs
  1039.     local st_lines = state.lines
  1040.     local st_source = state.source
  1041.     local st_numparams = state.numparams
  1042.  
  1043.     local function exec_wrap(...)
  1044.         local stack = {}
  1045.         local varargs = {}
  1046.         local sizevarg = 0
  1047.         local sz_args, l_args = wrap_lua_variadic(...)
  1048.  
  1049.         local exst
  1050.         local ok, err, vals
  1051.  
  1052.         for i = 1, st_numparams do stack[i - 1] = l_args[i] end
  1053.  
  1054.         if st_numparams < sz_args then
  1055.             sizevarg = sz_args - st_numparams
  1056.             for i = 1, sizevarg do varargs[i] = l_args[st_numparams + i] end
  1057.         end
  1058.  
  1059.         exst = {
  1060.             varargs = {list = varargs, size = sizevarg},
  1061.             code = st_code,
  1062.             subs = st_subs,
  1063.             lines = st_lines,
  1064.             source = st_source,
  1065.             env = env,
  1066.             upvals = upvals,
  1067.             stack = stack,
  1068.             pc = 1,
  1069.         }
  1070.  
  1071.         ok, err, vals = pcall(exec_lua_func, exst, ...)
  1072.         if ok then
  1073.             return unpack(vals, 1, err)
  1074.         else
  1075.             on_lua_error(exst, err)
  1076.         end
  1077.  
  1078.         return -- explicit "return nothing"
  1079.     end
  1080.  
  1081.     return exec_wrap
  1082. end
  1083.  
  1084. return {stm_lua = stm_lua_bytecode, wrap_lua = wrap_lua_func}
  1085. end
  1086.  
  1087. function LuaK()
  1088. local script = script.LuaK
  1089. --[[--------------------------------------------------------------------
  1090.  
  1091.   lcode.lua
  1092.   Lua 5 code generator in Lua
  1093.   This file is part of Yueliang.
  1094.  
  1095.   Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
  1096.   The COPYRIGHT file describes the conditions
  1097.   under which this software may be distributed.
  1098.  
  1099.   See the ChangeLog for more information.
  1100.  
  1101. ----------------------------------------------------------------------]]
  1102.  
  1103. --[[--------------------------------------------------------------------
  1104. -- Notes:
  1105. -- * one function manipulate a pointer argument with a simple data type
  1106. --   (can't be emulated by a table, ambiguous), now returns that value:
  1107. --   luaK:concat(fs, l1, l2)
  1108. -- * luaM_growvector uses the faux luaY:growvector, for limit checking
  1109. -- * some function parameters changed to boolean, additional code
  1110. --   translates boolean back to 1/0 for instruction fields
  1111. --
  1112. -- Not implemented:
  1113. -- * NOTE there is a failed assert in luaK:addk, a porting problem
  1114. --
  1115. -- Added:
  1116. -- * constant MAXSTACK from llimits.h
  1117. -- * luaK:ttisnumber(o) (from lobject.h)
  1118. -- * luaK:nvalue(o) (from lobject.h)
  1119. -- * luaK:setnilvalue(o) (from lobject.h)
  1120. -- * luaK:setnvalue(o, x) (from lobject.h)
  1121. -- * luaK:setbvalue(o, x) (from lobject.h)
  1122. -- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted
  1123. -- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted
  1124. -- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod,
  1125. --   luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h)
  1126. -- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct
  1127. --
  1128. -- Changed in 5.1.x:
  1129. -- * enum BinOpr has a new entry, OPR_MOD
  1130. -- * enum UnOpr has a new entry, OPR_LEN
  1131. -- * binopistest, unused in 5.0.x, has been deleted
  1132. -- * macro setmultret is new
  1133. -- * functions isnumeral, luaK_ret, boolK are new
  1134. -- * funcion nilK was named nil_constant in 5.0.x
  1135. -- * function interface changed: need_value, patchtestreg, concat
  1136. -- * TObject now a TValue
  1137. -- * functions luaK_setreturns, luaK_setoneret are new
  1138. -- * function luaK:setcallreturns deleted, to be replaced by:
  1139. --   luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret
  1140. -- * functions constfolding, codearith, codecomp are new
  1141. -- * luaK:codebinop has been deleted
  1142. -- * function luaK_setlist is new
  1143. -- * OPR_MULT renamed to OPR_MUL
  1144. ----------------------------------------------------------------------]]
  1145.  
  1146. -- requires luaP, luaX, luaY
  1147. local luaK = {}
  1148. local luaP = require(script.Parent.LuaP)
  1149. local luaX = require(script.Parent.LuaX)
  1150.  
  1151. ------------------------------------------------------------------------
  1152. -- constants used by code generator
  1153. ------------------------------------------------------------------------
  1154. -- maximum stack for a Lua function
  1155. luaK.MAXSTACK = 250  -- (from llimits.h)
  1156.  
  1157. --[[--------------------------------------------------------------------
  1158. -- other functions
  1159. ----------------------------------------------------------------------]]
  1160.  
  1161. ------------------------------------------------------------------------
  1162. -- emulation of TValue macros (these are from lobject.h)
  1163. -- * TValue is a table since lcode passes references around
  1164. -- * tt member field removed, using Lua's type() instead
  1165. -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
  1166. --   is used in an assert for testing, see checkliveness(g,obj)
  1167. ------------------------------------------------------------------------
  1168. function luaK:ttisnumber(o)
  1169.   if o then return type(o.value) == "number" else return false end
  1170. end
  1171. function luaK:nvalue(o) return o.value end
  1172. function luaK:setnilvalue(o) o.value = nil end
  1173. function luaK:setsvalue(o, x) o.value = x end
  1174. luaK.setnvalue = luaK.setsvalue
  1175. luaK.sethvalue = luaK.setsvalue
  1176. luaK.setbvalue = luaK.setsvalue
  1177.  
  1178. ------------------------------------------------------------------------
  1179. -- The luai_num* macros define the primitive operations over numbers.
  1180. -- * this is not the entire set of primitive operations from luaconf.h
  1181. -- * used in luaK:constfolding()
  1182. ------------------------------------------------------------------------
  1183. function luaK:numadd(a, b) return a + b end
  1184. function luaK:numsub(a, b) return a - b end
  1185. function luaK:nummul(a, b) return a * b end
  1186. function luaK:numdiv(a, b) return a / b end
  1187. function luaK:nummod(a, b) return a % b end
  1188.   -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
  1189. function luaK:numpow(a, b) return a ^ b end
  1190. function luaK:numunm(a) return -a end
  1191. function luaK:numisnan(a) return not a == a end
  1192.   -- a NaN cannot equal another NaN
  1193.  
  1194. --[[--------------------------------------------------------------------
  1195. -- code generator functions
  1196. ----------------------------------------------------------------------]]
  1197.  
  1198. ------------------------------------------------------------------------
  1199. -- Marks the end of a patch list. It is an invalid value both as an absolute
  1200. -- address, and as a list link (would link an element to itself).
  1201. ------------------------------------------------------------------------
  1202. luaK.NO_JUMP = -1
  1203.  
  1204. ------------------------------------------------------------------------
  1205. -- grep "ORDER OPR" if you change these enums
  1206. ------------------------------------------------------------------------
  1207. luaK.BinOpr = {
  1208.   OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5,
  1209.   OPR_CONCAT = 6,
  1210.   OPR_NE = 7, OPR_EQ = 8,
  1211.   OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12,
  1212.   OPR_AND = 13, OPR_OR = 14,
  1213.   OPR_NOBINOPR = 15,
  1214. }
  1215.  
  1216. -- * UnOpr is used by luaK:prefix's op argument, but not directly used
  1217. --   because the function receives the symbols as strings, e.g. "OPR_NOT"
  1218. luaK.UnOpr = {
  1219.   OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3
  1220. }
  1221.  
  1222. ------------------------------------------------------------------------
  1223. -- returns the instruction object for given e (expdesc), was a macro
  1224. ------------------------------------------------------------------------
  1225. function luaK:getcode(fs, e)
  1226.   return fs.f.code[e.info]
  1227. end
  1228.  
  1229. ------------------------------------------------------------------------
  1230. -- codes an instruction with a signed Bx (sBx) field, was a macro
  1231. -- * used in luaK:jump(), (lparser) luaY:forbody()
  1232. ------------------------------------------------------------------------
  1233. function luaK:codeAsBx(fs, o, A, sBx)
  1234.   return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
  1235. end
  1236.  
  1237. ------------------------------------------------------------------------
  1238. -- set the expdesc e instruction for multiple returns, was a macro
  1239. ------------------------------------------------------------------------
  1240. function luaK:setmultret(fs, e)
  1241.   self:setreturns(fs, e, luaY.LUA_MULTRET)
  1242. end
  1243.  
  1244. ------------------------------------------------------------------------
  1245. -- there is a jump if patch lists are not identical, was a macro
  1246. -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
  1247. ------------------------------------------------------------------------
  1248. function luaK:hasjumps(e)
  1249.   return e.t ~= e.f
  1250. end
  1251.  
  1252. ------------------------------------------------------------------------
  1253. -- true if the expression is a constant number (for constant folding)
  1254. -- * used in constfolding(), infix()
  1255. ------------------------------------------------------------------------
  1256. function luaK:isnumeral(e)
  1257.   return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
  1258. end
  1259.  
  1260. ------------------------------------------------------------------------
  1261. -- codes loading of nil, optimization done if consecutive locations
  1262. -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
  1263. ------------------------------------------------------------------------
  1264. function luaK:_nil(fs, from, n)
  1265.   if fs.pc > fs.lasttarget then  -- no jumps to current position?
  1266.     if fs.pc == 0 then  -- function start?
  1267.       if from >= fs.nactvar then
  1268.         return  -- positions are already clean
  1269.       end
  1270.     else
  1271.       local previous = fs.f.code[fs.pc - 1]
  1272.       if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
  1273.         local pfrom = luaP:GETARG_A(previous)
  1274.         local pto = luaP:GETARG_B(previous)
  1275.         if pfrom <= from and from <= pto + 1 then  -- can connect both?
  1276.           if from + n - 1 > pto then
  1277.             luaP:SETARG_B(previous, from + n - 1)
  1278.           end
  1279.           return
  1280.         end
  1281.       end
  1282.     end
  1283.   end
  1284.   self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0)  -- else no optimization
  1285. end
  1286.  
  1287. ------------------------------------------------------------------------
  1288. --
  1289. -- * used in multiple locations
  1290. ------------------------------------------------------------------------
  1291. function luaK:jump(fs)
  1292.   local jpc = fs.jpc  -- save list of jumps to here
  1293.   fs.jpc = self.NO_JUMP
  1294.   local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
  1295.   j = self:concat(fs, j, jpc)  -- keep them on hold
  1296.   return j
  1297. end
  1298.  
  1299. ------------------------------------------------------------------------
  1300. -- codes a RETURN instruction
  1301. -- * used in luaY:close_func(), luaY:retstat()
  1302. ------------------------------------------------------------------------
  1303. function luaK:ret(fs, first, nret)
  1304.   self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
  1305. end
  1306.  
  1307. ------------------------------------------------------------------------
  1308. --
  1309. -- * used in luaK:jumponcond(), luaK:codecomp()
  1310. ------------------------------------------------------------------------
  1311. function luaK:condjump(fs, op, A, B, C)
  1312.   self:codeABC(fs, op, A, B, C)
  1313.   return self:jump(fs)
  1314. end
  1315.  
  1316. ------------------------------------------------------------------------
  1317. --
  1318. -- * used in luaK:patchlistaux(), luaK:concat()
  1319. ------------------------------------------------------------------------
  1320. function luaK:fixjump(fs, pc, dest)
  1321.   local jmp = fs.f.code[pc]
  1322.   local offset = dest - (pc + 1)
  1323.   assert(dest ~= self.NO_JUMP)
  1324.   if math.abs(offset) > luaP.MAXARG_sBx then
  1325.     luaX:syntaxerror(fs.ls, "control structure too long")
  1326.   end
  1327.   luaP:SETARG_sBx(jmp, offset)
  1328. end
  1329.  
  1330. ------------------------------------------------------------------------
  1331. -- returns current 'pc' and marks it as a jump target (to avoid wrong
  1332. -- optimizations with consecutive instructions not in the same basic block).
  1333. -- * used in multiple locations
  1334. -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
  1335. ------------------------------------------------------------------------
  1336. function luaK:getlabel(fs)
  1337.   fs.lasttarget = fs.pc
  1338.   return fs.pc
  1339. end
  1340.  
  1341. ------------------------------------------------------------------------
  1342. --
  1343. -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
  1344. --   luaK:concat()
  1345. ------------------------------------------------------------------------
  1346. function luaK:getjump(fs, pc)
  1347.   local offset = luaP:GETARG_sBx(fs.f.code[pc])
  1348.   if offset == self.NO_JUMP then  -- point to itself represents end of list
  1349.     return self.NO_JUMP  -- end of list
  1350.   else
  1351.     return (pc + 1) + offset  -- turn offset into absolute position
  1352.   end
  1353. end
  1354.  
  1355. ------------------------------------------------------------------------
  1356. --
  1357. -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
  1358. ------------------------------------------------------------------------
  1359. function luaK:getjumpcontrol(fs, pc)
  1360.   local pi = fs.f.code[pc]
  1361.   local ppi = fs.f.code[pc - 1]
  1362.   if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
  1363.     return ppi
  1364.   else
  1365.     return pi
  1366.   end
  1367. end
  1368.  
  1369. ------------------------------------------------------------------------
  1370. -- check whether list has any jump that do not produce a value
  1371. -- (or produce an inverted value)
  1372. -- * return value changed to boolean
  1373. -- * used only in luaK:exp2reg()
  1374. ------------------------------------------------------------------------
  1375. function luaK:need_value(fs, list)
  1376.   while list ~= self.NO_JUMP do
  1377.     local i = self:getjumpcontrol(fs, list)
  1378.     if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end
  1379.     list = self:getjump(fs, list)
  1380.   end
  1381.   return false  -- not found
  1382. end
  1383.  
  1384. ------------------------------------------------------------------------
  1385. --
  1386. -- * used in luaK:removevalues(), luaK:patchlistaux()
  1387. ------------------------------------------------------------------------
  1388. function luaK:patchtestreg(fs, node, reg)
  1389.   local i = self:getjumpcontrol(fs, node)
  1390.   if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
  1391.     return false  -- cannot patch other instructions
  1392.   end
  1393.   if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
  1394.     luaP:SETARG_A(i, reg)
  1395.   else  -- no register to put value or register already has the value
  1396.     -- due to use of a table as i, i cannot be replaced by another table
  1397.     -- so the following is required; there is no change to ARG_C
  1398.     luaP:SET_OPCODE(i, "OP_TEST")
  1399.     local b = luaP:GETARG_B(i)
  1400.     luaP:SETARG_A(i, b)
  1401.     luaP:SETARG_B(i, 0)
  1402.     -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
  1403.   end
  1404.   return true
  1405. end
  1406.  
  1407. ------------------------------------------------------------------------
  1408. --
  1409. -- * used only in luaK:codenot()
  1410. ------------------------------------------------------------------------
  1411. function luaK:removevalues(fs, list)
  1412.   while list ~= self.NO_JUMP do
  1413.     self:patchtestreg(fs, list, luaP.NO_REG)
  1414.     list = self:getjump(fs, list)
  1415.   end
  1416. end
  1417.  
  1418. ------------------------------------------------------------------------
  1419. --
  1420. -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
  1421. ------------------------------------------------------------------------
  1422. function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
  1423.   while list ~= self.NO_JUMP do
  1424.     local _next = self:getjump(fs, list)
  1425.     if self:patchtestreg(fs, list, reg) then
  1426.       self:fixjump(fs, list, vtarget)
  1427.     else
  1428.       self:fixjump(fs, list, dtarget)  -- jump to default target
  1429.     end
  1430.     list = _next
  1431.   end
  1432. end
  1433.  
  1434. ------------------------------------------------------------------------
  1435. --
  1436. -- * used only in luaK:code()
  1437. ------------------------------------------------------------------------
  1438. function luaK:dischargejpc(fs)
  1439.   self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
  1440.   fs.jpc = self.NO_JUMP
  1441. end
  1442.  
  1443. ------------------------------------------------------------------------
  1444. --
  1445. -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
  1446. ------------------------------------------------------------------------
  1447. function luaK:patchlist(fs, list, target)
  1448.   if target == fs.pc then
  1449.     self:patchtohere(fs, list)
  1450.   else
  1451.     assert(target < fs.pc)
  1452.     self:patchlistaux(fs, list, target, luaP.NO_REG, target)
  1453.   end
  1454. end
  1455.  
  1456. ------------------------------------------------------------------------
  1457. --
  1458. -- * used in multiple locations
  1459. ------------------------------------------------------------------------
  1460. function luaK:patchtohere(fs, list)
  1461.   self:getlabel(fs)
  1462.   fs.jpc = self:concat(fs, fs.jpc, list)
  1463. end
  1464.  
  1465. ------------------------------------------------------------------------
  1466. -- * l1 was a pointer, now l1 is returned and callee assigns the value
  1467. -- * used in multiple locations
  1468. ------------------------------------------------------------------------
  1469. function luaK:concat(fs, l1, l2)
  1470.   if l2 == self.NO_JUMP then return l1
  1471.   elseif l1 == self.NO_JUMP then
  1472.     return l2
  1473.   else
  1474.     local list = l1
  1475.     local _next = self:getjump(fs, list)
  1476.     while _next ~= self.NO_JUMP do  -- find last element
  1477.       list = _next
  1478.       _next = self:getjump(fs, list)
  1479.     end
  1480.     self:fixjump(fs, list, l2)
  1481.   end
  1482.   return l1
  1483. end
  1484.  
  1485. ------------------------------------------------------------------------
  1486. --
  1487. -- * used in luaK:reserveregs(), (lparser) luaY:forlist()
  1488. ------------------------------------------------------------------------
  1489. function luaK:checkstack(fs, n)
  1490.   local newstack = fs.freereg + n
  1491.   if newstack > fs.f.maxstacksize then
  1492.     if newstack >= self.MAXSTACK then
  1493.       luaX:syntaxerror(fs.ls, "function or expression too complex")
  1494.     end
  1495.     fs.f.maxstacksize = newstack
  1496.   end
  1497. end
  1498.  
  1499. ------------------------------------------------------------------------
  1500. --
  1501. -- * used in multiple locations
  1502. ------------------------------------------------------------------------
  1503. function luaK:reserveregs(fs, n)
  1504.   self:checkstack(fs, n)
  1505.   fs.freereg = fs.freereg + n
  1506. end
  1507.  
  1508. ------------------------------------------------------------------------
  1509. --
  1510. -- * used in luaK:freeexp(), luaK:dischargevars()
  1511. ------------------------------------------------------------------------
  1512. function luaK:freereg(fs, reg)
  1513.   if not luaP:ISK(reg) and reg >= fs.nactvar then
  1514.     fs.freereg = fs.freereg - 1
  1515.     assert(reg == fs.freereg)
  1516.   end
  1517. end
  1518.  
  1519. ------------------------------------------------------------------------
  1520. --
  1521. -- * used in multiple locations
  1522. ------------------------------------------------------------------------
  1523. function luaK:freeexp(fs, e)
  1524.   if e.k == "VNONRELOC" then
  1525.     self:freereg(fs, e.info)
  1526.   end
  1527. end
  1528.  
  1529. ------------------------------------------------------------------------
  1530. -- * TODO NOTE implementation is not 100% correct, since the assert fails
  1531. -- * luaH_set, setobj deleted; direct table access used instead
  1532. -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
  1533. ------------------------------------------------------------------------
  1534. function luaK:addk(fs, k, v)
  1535.   local L = fs.L
  1536.   local idx = fs.h[k.value]
  1537.   --TValue *idx = luaH_set(L, fs->h, k); /* C */
  1538.   local f = fs.f
  1539.   if self:ttisnumber(idx) then
  1540.     --TODO this assert currently FAILS (last tested for 5.0.2)
  1541.     --assert(fs.f.k[self:nvalue(idx)] == v)
  1542.     --assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
  1543.     return self:nvalue(idx)
  1544.   else -- constant not found; create a new entry
  1545.     idx = {}
  1546.     self:setnvalue(idx, fs.nk)
  1547.     fs.h[k.value] = idx
  1548.     -- setnvalue(idx, cast_num(fs->nk)); /* C */
  1549.     luaY:growvector(L, f.k, fs.nk, f.sizek, nil,
  1550.                     luaP.MAXARG_Bx, "constant table overflow")
  1551.     -- loop to initialize empty f.k positions not required
  1552.     f.k[fs.nk] = v
  1553.     -- setobj(L, &f->k[fs->nk], v); /* C */
  1554.     -- luaC_barrier(L, f, v); /* GC */
  1555.     local nk = fs.nk
  1556.     fs.nk = fs.nk + 1
  1557.     return nk
  1558.   end
  1559.  
  1560. end
  1561.  
  1562. ------------------------------------------------------------------------
  1563. -- creates and sets a string object
  1564. -- * used in (lparser) luaY:codestring(), luaY:singlevar()
  1565. ------------------------------------------------------------------------
  1566. function luaK:stringK(fs, s)
  1567.   local o = {}  -- TValue
  1568.   self:setsvalue(o, s)
  1569.   return self:addk(fs, o, o)
  1570. end
  1571.  
  1572. ------------------------------------------------------------------------
  1573. -- creates and sets a number object
  1574. -- * used in luaK:prefix() for negative (or negation of) numbers
  1575. -- * used in (lparser) luaY:simpleexp(), luaY:fornum()
  1576. ------------------------------------------------------------------------
  1577. function luaK:numberK(fs, r)
  1578.   local o = {}  -- TValue
  1579.   self:setnvalue(o, r)
  1580.   return self:addk(fs, o, o)
  1581. end
  1582.  
  1583. ------------------------------------------------------------------------
  1584. -- creates and sets a boolean object
  1585. -- * used only in luaK:exp2RK()
  1586. ------------------------------------------------------------------------
  1587. function luaK:boolK(fs, b)
  1588.   local o = {}  -- TValue
  1589.   self:setbvalue(o, b)
  1590.   return self:addk(fs, o, o)
  1591. end
  1592.  
  1593. ------------------------------------------------------------------------
  1594. -- creates and sets a nil object
  1595. -- * used only in luaK:exp2RK()
  1596. ------------------------------------------------------------------------
  1597. function luaK:nilK(fs)
  1598.   local k, v = {}, {}  -- TValue
  1599.   self:setnilvalue(v)
  1600.   -- cannot use nil as key; instead use table itself to represent nil
  1601.   self:sethvalue(k, fs.h)
  1602.   return self:addk(fs, k, v)
  1603. end
  1604.  
  1605. ------------------------------------------------------------------------
  1606. --
  1607. -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
  1608. ------------------------------------------------------------------------
  1609. function luaK:setreturns(fs, e, nresults)
  1610.   if e.k == "VCALL" then  -- expression is an open function call?
  1611.     luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
  1612.   elseif e.k == "VVARARG" then
  1613.     luaP:SETARG_B(self:getcode(fs, e), nresults + 1);
  1614.     luaP:SETARG_A(self:getcode(fs, e), fs.freereg);
  1615.     luaK:reserveregs(fs, 1)
  1616.   end
  1617. end
  1618.  
  1619. ------------------------------------------------------------------------
  1620. --
  1621. -- * used in luaK:dischargevars(), (lparser) luaY:assignment()
  1622. ------------------------------------------------------------------------
  1623. function luaK:setoneret(fs, e)
  1624.   if e.k == "VCALL" then  -- expression is an open function call?
  1625.     e.k = "VNONRELOC"
  1626.     e.info = luaP:GETARG_A(self:getcode(fs, e))
  1627.   elseif e.k == "VVARARG" then
  1628.     luaP:SETARG_B(self:getcode(fs, e), 2)
  1629.     e.k = "VRELOCABLE"  -- can relocate its simple result
  1630.   end
  1631. end
  1632.  
  1633. ------------------------------------------------------------------------
  1634. --
  1635. -- * used in multiple locations
  1636. ------------------------------------------------------------------------
  1637. function luaK:dischargevars(fs, e)
  1638.   local k = e.k
  1639.   if k == "VLOCAL" then
  1640.     e.k = "VNONRELOC"
  1641.   elseif k == "VUPVAL" then
  1642.     e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
  1643.     e.k = "VRELOCABLE"
  1644.   elseif k == "VGLOBAL" then
  1645.     e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
  1646.     e.k = "VRELOCABLE"
  1647.   elseif k == "VINDEXED" then
  1648.     self:freereg(fs, e.aux)
  1649.     self:freereg(fs, e.info)
  1650.     e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
  1651.     e.k = "VRELOCABLE"
  1652.   elseif k == "VVARARG" or k == "VCALL" then
  1653.     self:setoneret(fs, e)
  1654.   else
  1655.     -- there is one value available (somewhere)
  1656.   end
  1657. end
  1658.  
  1659. ------------------------------------------------------------------------
  1660. --
  1661. -- * used only in luaK:exp2reg()
  1662. ------------------------------------------------------------------------
  1663. function luaK:code_label(fs, A, b, jump)
  1664.   self:getlabel(fs)  -- those instructions may be jump targets
  1665.   return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
  1666. end
  1667.  
  1668. ------------------------------------------------------------------------
  1669. --
  1670. -- * used in luaK:discharge2anyreg(), luaK:exp2reg()
  1671. ------------------------------------------------------------------------
  1672. function luaK:discharge2reg(fs, e, reg)
  1673.   self:dischargevars(fs, e)
  1674.   local k = e.k
  1675.   if k == "VNIL" then
  1676.     self:_nil(fs, reg, 1)
  1677.   elseif k == "VFALSE" or k == "VTRUE" then
  1678.     self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
  1679.   elseif k == "VK" then
  1680.     self:codeABx(fs, "OP_LOADK", reg, e.info)
  1681.   elseif k == "VKNUM" then
  1682.     self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
  1683.   elseif k == "VRELOCABLE" then
  1684.     local pc = self:getcode(fs, e)
  1685.     luaP:SETARG_A(pc, reg)
  1686.   elseif k == "VNONRELOC" then
  1687.     if reg ~= e.info then
  1688.       self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
  1689.     end
  1690.   else
  1691.     assert(e.k == "VVOID" or e.k == "VJMP")
  1692.     return  -- nothing to do...
  1693.   end
  1694.   e.info = reg
  1695.   e.k = "VNONRELOC"
  1696. end
  1697.  
  1698. ------------------------------------------------------------------------
  1699. --
  1700. -- * used in luaK:jumponcond(), luaK:codenot()
  1701. ------------------------------------------------------------------------
  1702. function luaK:discharge2anyreg(fs, e)
  1703.   if e.k ~= "VNONRELOC" then
  1704.     self:reserveregs(fs, 1)
  1705.     self:discharge2reg(fs, e, fs.freereg - 1)
  1706.   end
  1707. end
  1708.  
  1709. ------------------------------------------------------------------------
  1710. --
  1711. -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
  1712. ------------------------------------------------------------------------
  1713. function luaK:exp2reg(fs, e, reg)
  1714.   self:discharge2reg(fs, e, reg)
  1715.   if e.k == "VJMP" then
  1716.     e.t = self:concat(fs, e.t, e.info)  -- put this jump in 't' list
  1717.   end
  1718.   if self:hasjumps(e) then
  1719.     local final  -- position after whole expression
  1720.     local p_f = self.NO_JUMP  -- position of an eventual LOAD false
  1721.     local p_t = self.NO_JUMP  -- position of an eventual LOAD true
  1722.     if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
  1723.       local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
  1724.       p_f = self:code_label(fs, reg, 0, 1)
  1725.       p_t = self:code_label(fs, reg, 1, 0)
  1726.       self:patchtohere(fs, fj)
  1727.     end
  1728.     final = self:getlabel(fs)
  1729.     self:patchlistaux(fs, e.f, final, reg, p_f)
  1730.     self:patchlistaux(fs, e.t, final, reg, p_t)
  1731.   end
  1732.   e.f, e.t = self.NO_JUMP, self.NO_JUMP
  1733.   e.info = reg
  1734.   e.k = "VNONRELOC"
  1735. end
  1736.  
  1737. ------------------------------------------------------------------------
  1738. --
  1739. -- * used in multiple locations
  1740. ------------------------------------------------------------------------
  1741. function luaK:exp2nextreg(fs, e)
  1742.   self:dischargevars(fs, e)
  1743.   self:freeexp(fs, e)
  1744.   self:reserveregs(fs, 1)
  1745.   self:exp2reg(fs, e, fs.freereg - 1)
  1746. end
  1747.  
  1748. ------------------------------------------------------------------------
  1749. --
  1750. -- * used in multiple locations
  1751. ------------------------------------------------------------------------
  1752. function luaK:exp2anyreg(fs, e)
  1753.   self:dischargevars(fs, e)
  1754.   if e.k == "VNONRELOC" then
  1755.     if not self:hasjumps(e) then  -- exp is already in a register
  1756.       return e.info
  1757.     end
  1758.     if e.info >= fs.nactvar then  -- reg. is not a local?
  1759.       self:exp2reg(fs, e, e.info)  -- put value on it
  1760.       return e.info
  1761.     end
  1762.   end
  1763.   self:exp2nextreg(fs, e)  -- default
  1764.   return e.info
  1765. end
  1766.  
  1767. ------------------------------------------------------------------------
  1768. --
  1769. -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
  1770. -- * used in (lparser) luaY:yindex()
  1771. ------------------------------------------------------------------------
  1772. function luaK:exp2val(fs, e)
  1773.   if self:hasjumps(e) then
  1774.     self:exp2anyreg(fs, e)
  1775.   else
  1776.     self:dischargevars(fs, e)
  1777.   end
  1778. end
  1779.  
  1780. ------------------------------------------------------------------------
  1781. --
  1782. -- * used in multiple locations
  1783. ------------------------------------------------------------------------
  1784. function luaK:exp2RK(fs, e)
  1785.   self:exp2val(fs, e)
  1786.   local k = e.k
  1787.   if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
  1788.     if fs.nk <= luaP.MAXINDEXRK then  -- constant fit in RK operand?
  1789.       -- converted from a 2-deep ternary operator expression
  1790.       if e.k == "VNIL" then
  1791.         e.info = self:nilK(fs)
  1792.       else
  1793.         e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval)
  1794.                                   or self:boolK(fs, e.k == "VTRUE")
  1795.       end
  1796.       e.k = "VK"
  1797.       return luaP:RKASK(e.info)
  1798.     end
  1799.   elseif k == "VK" then
  1800.     if e.info <= luaP.MAXINDEXRK then  -- constant fit in argC?
  1801.       return luaP:RKASK(e.info)
  1802.     end
  1803.   else
  1804.     -- default
  1805.   end
  1806.   -- not a constant in the right range: put it in a register
  1807.   return self:exp2anyreg(fs, e)
  1808. end
  1809.  
  1810. ------------------------------------------------------------------------
  1811. --
  1812. -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
  1813. ------------------------------------------------------------------------
  1814. function luaK:storevar(fs, var, ex)
  1815.   local k = var.k
  1816.   if k == "VLOCAL" then
  1817.     self:freeexp(fs, ex)
  1818.     self:exp2reg(fs, ex, var.info)
  1819.     return
  1820.   elseif k == "VUPVAL" then
  1821.     local e = self:exp2anyreg(fs, ex)
  1822.     self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
  1823.   elseif k == "VGLOBAL" then
  1824.     local e = self:exp2anyreg(fs, ex)
  1825.     self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
  1826.   elseif k == "VINDEXED" then
  1827.     local e = self:exp2RK(fs, ex)
  1828.     self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
  1829.   else
  1830.     assert(0)  -- invalid var kind to store
  1831.   end
  1832.   self:freeexp(fs, ex)
  1833. end
  1834.  
  1835. ------------------------------------------------------------------------
  1836. --
  1837. -- * used only in (lparser) luaY:primaryexp()
  1838. ------------------------------------------------------------------------
  1839. function luaK:_self(fs, e, key)
  1840.   self:exp2anyreg(fs, e)
  1841.   self:freeexp(fs, e)
  1842.   local func = fs.freereg
  1843.   self:reserveregs(fs, 2)
  1844.   self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
  1845.   self:freeexp(fs, key)
  1846.   e.info = func
  1847.   e.k = "VNONRELOC"
  1848. end
  1849.  
  1850. ------------------------------------------------------------------------
  1851. --
  1852. -- * used in luaK:goiftrue(), luaK:codenot()
  1853. ------------------------------------------------------------------------
  1854. function luaK:invertjump(fs, e)
  1855.   local pc = self:getjumpcontrol(fs, e.info)
  1856.   assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and
  1857.              luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and
  1858.              luaP:GET_OPCODE(pc) ~= "OP_TEST")
  1859.   luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
  1860. end
  1861.  
  1862. ------------------------------------------------------------------------
  1863. --
  1864. -- * used in luaK:goiftrue(), luaK:goiffalse()
  1865. ------------------------------------------------------------------------
  1866. function luaK:jumponcond(fs, e, cond)
  1867.   if e.k == "VRELOCABLE" then
  1868.     local ie = self:getcode(fs, e)
  1869.     if luaP:GET_OPCODE(ie) == "OP_NOT" then
  1870.       fs.pc = fs.pc - 1  -- remove previous OP_NOT
  1871.       return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
  1872.     end
  1873.     -- else go through
  1874.   end
  1875.   self:discharge2anyreg(fs, e)
  1876.   self:freeexp(fs, e)
  1877.   return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
  1878. end
  1879.  
  1880. ------------------------------------------------------------------------
  1881. --
  1882. -- * used in luaK:infix(), (lparser) luaY:cond()
  1883. ------------------------------------------------------------------------
  1884. function luaK:goiftrue(fs, e)
  1885.   local pc  -- pc of last jump
  1886.   self:dischargevars(fs, e)
  1887.   local k = e.k
  1888.   if k == "VK" or k == "VKNUM" or k == "VTRUE" then
  1889.     pc = self.NO_JUMP  -- always true; do nothing
  1890.   elseif k == "VFALSE" then
  1891.     pc = self:jump(fs)  -- always jump
  1892.   elseif k == "VJMP" then
  1893.     self:invertjump(fs, e)
  1894.     pc = e.info
  1895.   else
  1896.     pc = self:jumponcond(fs, e, false)
  1897.   end
  1898.   e.f = self:concat(fs, e.f, pc)  -- insert last jump in `f' list
  1899.   self:patchtohere(fs, e.t)
  1900.   e.t = self.NO_JUMP
  1901. end
  1902.  
  1903. ------------------------------------------------------------------------
  1904. --
  1905. -- * used in luaK:infix()
  1906. ------------------------------------------------------------------------
  1907. function luaK:goiffalse(fs, e)
  1908.   local pc  -- pc of last jump
  1909.   self:dischargevars(fs, e)
  1910.   local k = e.k
  1911.   if k == "VNIL" or k == "VFALSE"then
  1912.     pc = self.NO_JUMP  -- always false; do nothing
  1913.   elseif k == "VTRUE" then
  1914.     pc = self:jump(fs)  -- always jump
  1915.   elseif k == "VJMP" then
  1916.     pc = e.info
  1917.   else
  1918.     pc = self:jumponcond(fs, e, true)
  1919.   end
  1920.   e.t = self:concat(fs, e.t, pc)  -- insert last jump in `t' list
  1921.   self:patchtohere(fs, e.f)
  1922.   e.f = self.NO_JUMP
  1923. end
  1924.  
  1925. ------------------------------------------------------------------------
  1926. --
  1927. -- * used only in luaK:prefix()
  1928. ------------------------------------------------------------------------
  1929. function luaK:codenot(fs, e)
  1930.   self:dischargevars(fs, e)
  1931.   local k = e.k
  1932.   if k == "VNIL" or k == "VFALSE" then
  1933.     e.k = "VTRUE"
  1934.   elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
  1935.     e.k = "VFALSE"
  1936.   elseif k == "VJMP" then
  1937.     self:invertjump(fs, e)
  1938.   elseif k == "VRELOCABLE" or k == "VNONRELOC" then
  1939.     self:discharge2anyreg(fs, e)
  1940.     self:freeexp(fs, e)
  1941.     e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
  1942.     e.k = "VRELOCABLE"
  1943.   else
  1944.     assert(0)  -- cannot happen
  1945.   end
  1946.   -- interchange true and false lists
  1947.   e.f, e.t = e.t, e.f
  1948.   self:removevalues(fs, e.f)
  1949.   self:removevalues(fs, e.t)
  1950. end
  1951.  
  1952. ------------------------------------------------------------------------
  1953. --
  1954. -- * used in (lparser) luaY:field(), luaY:primaryexp()
  1955. ------------------------------------------------------------------------
  1956. function luaK:indexed(fs, t, k)
  1957.   t.aux = self:exp2RK(fs, k)
  1958.   t.k = "VINDEXED"
  1959. end
  1960.  
  1961. ------------------------------------------------------------------------
  1962. --
  1963. -- * used only in luaK:codearith()
  1964. ------------------------------------------------------------------------
  1965. function luaK:constfolding(op, e1, e2)
  1966.   local r
  1967.   if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end
  1968.   local v1 = e1.nval
  1969.   local v2 = e2.nval
  1970.   if op == "OP_ADD" then
  1971.     r = self:numadd(v1, v2)
  1972.   elseif op == "OP_SUB" then
  1973.     r = self:numsub(v1, v2)
  1974.   elseif op == "OP_MUL" then
  1975.     r = self:nummul(v1, v2)
  1976.   elseif op == "OP_DIV" then
  1977.     if v2 == 0 then return false end  -- do not attempt to divide by 0
  1978.     r = self:numdiv(v1, v2)
  1979.   elseif op == "OP_MOD" then
  1980.     if v2 == 0 then return false end  -- do not attempt to divide by 0
  1981.     r = self:nummod(v1, v2)
  1982.   elseif op == "OP_POW" then
  1983.     r = self:numpow(v1, v2)
  1984.   elseif op == "OP_UNM" then
  1985.     r = self:numunm(v1)
  1986.   elseif op == "OP_LEN" then
  1987.     return false  -- no constant folding for 'len'
  1988.   else
  1989.     assert(0)
  1990.     r = 0
  1991.   end
  1992.   if self:numisnan(r) then return false end  -- do not attempt to produce NaN
  1993.   e1.nval = r
  1994.   return true
  1995. end
  1996.  
  1997. ------------------------------------------------------------------------
  1998. --
  1999. -- * used in luaK:prefix(), luaK:posfix()
  2000. ------------------------------------------------------------------------
  2001. function luaK:codearith(fs, op, e1, e2)
  2002.   if self:constfolding(op, e1, e2) then
  2003.     return
  2004.   else
  2005.     local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
  2006.     local o1 = self:exp2RK(fs, e1)
  2007.     if o1 > o2 then
  2008.       self:freeexp(fs, e1)
  2009.       self:freeexp(fs, e2)
  2010.     else
  2011.       self:freeexp(fs, e2)
  2012.       self:freeexp(fs, e1)
  2013.     end
  2014.     e1.info = self:codeABC(fs, op, 0, o1, o2)
  2015.     e1.k = "VRELOCABLE"
  2016.   end
  2017. end
  2018.  
  2019. ------------------------------------------------------------------------
  2020. --
  2021. -- * used only in luaK:posfix()
  2022. ------------------------------------------------------------------------
  2023. function luaK:codecomp(fs, op, cond, e1, e2)
  2024.   local o1 = self:exp2RK(fs, e1)
  2025.   local o2 = self:exp2RK(fs, e2)
  2026.   self:freeexp(fs, e2)
  2027.   self:freeexp(fs, e1)
  2028.   if cond == 0 and op ~= "OP_EQ" then
  2029.     -- exchange args to replace by `<' or `<='
  2030.     o1, o2 = o2, o1  -- o1 <==> o2
  2031.     cond = 1
  2032.   end
  2033.   e1.info = self:condjump(fs, op, cond, o1, o2)
  2034.   e1.k = "VJMP"
  2035. end
  2036.  
  2037. ------------------------------------------------------------------------
  2038. --
  2039. -- * used only in (lparser) luaY:subexpr()
  2040. ------------------------------------------------------------------------
  2041. function luaK:prefix(fs, op, e)
  2042.   local e2 = {}  -- expdesc
  2043.   e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
  2044.   e2.k = "VKNUM"
  2045.   e2.nval = 0
  2046.   if op == "OPR_MINUS" then
  2047.     if not self:isnumeral(e) then
  2048.       self:exp2anyreg(fs, e)  -- cannot operate on non-numeric constants
  2049.     end
  2050.     self:codearith(fs, "OP_UNM", e, e2)
  2051.   elseif op == "OPR_NOT" then
  2052.     self:codenot(fs, e)
  2053.   elseif op == "OPR_LEN" then
  2054.     self:exp2anyreg(fs, e)  -- cannot operate on constants
  2055.     self:codearith(fs, "OP_LEN", e, e2)
  2056.   else
  2057.     assert(0)
  2058.   end
  2059. end
  2060.  
  2061. ------------------------------------------------------------------------
  2062. --
  2063. -- * used only in (lparser) luaY:subexpr()
  2064. ------------------------------------------------------------------------
  2065. function luaK:infix(fs, op, v)
  2066.   if op == "OPR_AND" then
  2067.     self:goiftrue(fs, v)
  2068.   elseif op == "OPR_OR" then
  2069.     self:goiffalse(fs, v)
  2070.   elseif op == "OPR_CONCAT" then
  2071.     self:exp2nextreg(fs, v)  -- operand must be on the 'stack'
  2072.   elseif op == "OPR_ADD" or op == "OPR_SUB" or
  2073.          op == "OPR_MUL" or op == "OPR_DIV" or
  2074.          op == "OPR_MOD" or op == "OPR_POW" then
  2075.     if not self:isnumeral(v) then self:exp2RK(fs, v) end
  2076.   else
  2077.     self:exp2RK(fs, v)
  2078.   end
  2079. end
  2080.  
  2081. ------------------------------------------------------------------------
  2082. --
  2083. -- * used only in (lparser) luaY:subexpr()
  2084. ------------------------------------------------------------------------
  2085. -- table lookups to simplify testing
  2086. luaK.arith_op = {
  2087.   OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL",
  2088.   OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW",
  2089. }
  2090. luaK.comp_op = {
  2091.   OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT",
  2092.   OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE",
  2093. }
  2094. luaK.comp_cond = {
  2095.   OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1,
  2096.   OPR_LE = 1, OPR_GT = 0, OPR_GE = 0,
  2097. }
  2098. function luaK:posfix(fs, op, e1, e2)
  2099.   -- needed because e1 = e2 doesn't copy values...
  2100.   -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
  2101.   --   but here, all elements are copied for completeness' sake
  2102.   local function copyexp(e1, e2)
  2103.     e1.k = e2.k
  2104.     e1.info = e2.info; e1.aux = e2.aux
  2105.     e1.nval = e2.nval
  2106.     e1.t = e2.t; e1.f = e2.f
  2107.   end
  2108.   if op == "OPR_AND" then
  2109.     assert(e1.t == self.NO_JUMP)  -- list must be closed
  2110.     self:dischargevars(fs, e2)
  2111.     e2.f = self:concat(fs, e2.f, e1.f)
  2112.     copyexp(e1, e2)
  2113.   elseif op == "OPR_OR" then
  2114.     assert(e1.f == self.NO_JUMP)  -- list must be closed
  2115.     self:dischargevars(fs, e2)
  2116.     e2.t = self:concat(fs, e2.t, e1.t)
  2117.     copyexp(e1, e2)
  2118.   elseif op == "OPR_CONCAT" then
  2119.     self:exp2val(fs, e2)
  2120.     if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
  2121.       assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
  2122.       self:freeexp(fs, e1)
  2123.       luaP:SETARG_B(self:getcode(fs, e2), e1.info)
  2124.       e1.k = "VRELOCABLE"
  2125.       e1.info = e2.info
  2126.     else
  2127.       self:exp2nextreg(fs, e2)  -- operand must be on the 'stack'
  2128.       self:codearith(fs, "OP_CONCAT", e1, e2)
  2129.     end
  2130.   else
  2131.     -- the following uses a table lookup in place of conditionals
  2132.     local arith = self.arith_op[op]
  2133.     if arith then
  2134.       self:codearith(fs, arith, e1, e2)
  2135.     else
  2136.       local comp = self.comp_op[op]
  2137.       if comp then
  2138.         self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
  2139.       else
  2140.         assert(0)
  2141.       end
  2142.     end--if arith
  2143.   end--if op
  2144. end
  2145.  
  2146. ------------------------------------------------------------------------
  2147. -- adjusts debug information for last instruction written, in order to
  2148. -- change the line where item comes into existence
  2149. -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
  2150. ------------------------------------------------------------------------
  2151. function luaK:fixline(fs, line)
  2152.   fs.f.lineinfo[fs.pc - 1] = line
  2153. end
  2154.  
  2155. ------------------------------------------------------------------------
  2156. -- general function to write an instruction into the instruction buffer,
  2157. -- sets debug information too
  2158. -- * used in luaK:codeABC(), luaK:codeABx()
  2159. -- * called directly by (lparser) luaY:whilestat()
  2160. ------------------------------------------------------------------------
  2161. function luaK:code(fs, i, line)
  2162.   local f = fs.f
  2163.   self:dischargejpc(fs)  -- 'pc' will change
  2164.   -- put new instruction in code array
  2165.   luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
  2166.                   luaY.MAX_INT, "code size overflow")
  2167.   f.code[fs.pc] = i
  2168.   -- save corresponding line information
  2169.   luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
  2170.                   luaY.MAX_INT, "code size overflow")
  2171.   f.lineinfo[fs.pc] = line
  2172.   local pc = fs.pc
  2173.   fs.pc = fs.pc + 1
  2174.   return pc
  2175. end
  2176.  
  2177. ------------------------------------------------------------------------
  2178. -- writes an instruction of type ABC
  2179. -- * calls luaK:code()
  2180. ------------------------------------------------------------------------
  2181. function luaK:codeABC(fs, o, a, b, c)
  2182.   assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
  2183.   assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
  2184.   assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
  2185.   return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
  2186. end
  2187.  
  2188. ------------------------------------------------------------------------
  2189. -- writes an instruction of type ABx
  2190. -- * calls luaK:code(), called by luaK:codeAsBx()
  2191. ------------------------------------------------------------------------
  2192. function luaK:codeABx(fs, o, a, bc)
  2193.   assert(luaP:getOpMode(o) == luaP.OpMode.iABx or
  2194.              luaP:getOpMode(o) == luaP.OpMode.iAsBx)
  2195.   assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
  2196.   return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
  2197. end
  2198.  
  2199. ------------------------------------------------------------------------
  2200. --
  2201. -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
  2202. ------------------------------------------------------------------------
  2203. function luaK:setlist(fs, base, nelems, tostore)
  2204.   local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1
  2205.   local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
  2206.   assert(tostore ~= 0)
  2207.   if c <= luaP.MAXARG_C then
  2208.     self:codeABC(fs, "OP_SETLIST", base, b, c)
  2209.   else
  2210.     self:codeABC(fs, "OP_SETLIST", base, b, 0)
  2211.     self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
  2212.   end
  2213.   fs.freereg = base + 1  -- free registers with list values
  2214. end
  2215.  
  2216. return function(a) luaY = a return luaK end
  2217. end
  2218.  
  2219. function LuaP()
  2220. local script = script.LuaP
  2221. --[[--------------------------------------------------------------------
  2222.  
  2223.   lopcodes.lua
  2224.   Lua 5 virtual machine opcodes in Lua
  2225.   This file is part of Yueliang.
  2226.  
  2227.   Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
  2228.   The COPYRIGHT file describes the conditions
  2229.   under which this software may be distributed.
  2230.  
  2231.   See the ChangeLog for more information.
  2232.  
  2233. ----------------------------------------------------------------------]]
  2234.  
  2235. --[[--------------------------------------------------------------------
  2236. -- Notes:
  2237. -- * an Instruction is a table with OP, A, B, C, Bx elements; this
  2238. --   makes the code easy to follow and should allow instruction handling
  2239. --   to work with doubles and ints
  2240. -- * WARNING luaP:Instruction outputs instructions encoded in little-
  2241. --   endian form and field size and positions are hard-coded
  2242. --
  2243. -- Not implemented:
  2244. -- *
  2245. --
  2246. -- Added:
  2247. -- * luaP:CREATE_Inst(c): create an inst from a number (for OP_SETLIST)
  2248. -- * luaP:Instruction(i): convert field elements to a 4-char string
  2249. -- * luaP:DecodeInst(x): convert 4-char string into field elements
  2250. --
  2251. -- Changed in 5.1.x:
  2252. -- * POS_OP added, instruction field positions changed
  2253. -- * some symbol names may have changed, e.g. LUAI_BITSINT
  2254. -- * new operators for RK indices: BITRK, ISK(x), INDEXK(r), RKASK(x)
  2255. -- * OP_MOD, OP_LEN is new
  2256. -- * OP_TEST is now OP_TESTSET, OP_TEST is new
  2257. -- * OP_FORLOOP, OP_TFORLOOP adjusted, OP_FORPREP is new
  2258. -- * OP_TFORPREP deleted
  2259. -- * OP_SETLIST and OP_SETLISTO merged and extended
  2260. -- * OP_VARARG is new
  2261. -- * many changes to implementation of OpMode data
  2262. ----------------------------------------------------------------------]]
  2263.  
  2264. local luaP = {}
  2265.  
  2266. --[[
  2267. ===========================================================================
  2268.   We assume that instructions are unsigned numbers.
  2269.   All instructions have an opcode in the first 6 bits.
  2270.   Instructions can have the following fields:
  2271.         'A' : 8 bits
  2272.         'B' : 9 bits
  2273.         'C' : 9 bits
  2274.         'Bx' : 18 bits ('B' and 'C' together)
  2275.         'sBx' : signed Bx
  2276.  
  2277.   A signed argument is represented in excess K; that is, the number
  2278.   value is the unsigned value minus K. K is exactly the maximum value
  2279.   for that argument (so that -max is represented by 0, and +max is
  2280.   represented by 2*max), which is half the maximum for the corresponding
  2281.   unsigned argument.
  2282. ===========================================================================
  2283. --]]
  2284.  
  2285. luaP.OpMode = { iABC = 0, iABx = 1, iAsBx = 2 }  -- basic instruction format
  2286.  
  2287. ------------------------------------------------------------------------
  2288. -- size and position of opcode arguments.
  2289. -- * WARNING size and position is hard-coded elsewhere in this script
  2290. ------------------------------------------------------------------------
  2291. luaP.SIZE_C  = 9
  2292. luaP.SIZE_B  = 9
  2293. luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B
  2294. luaP.SIZE_A  = 8
  2295.  
  2296. luaP.SIZE_OP = 6
  2297.  
  2298. luaP.POS_OP = 0
  2299. luaP.POS_A  = luaP.POS_OP + luaP.SIZE_OP
  2300. luaP.POS_C  = luaP.POS_A + luaP.SIZE_A
  2301. luaP.POS_B  = luaP.POS_C + luaP.SIZE_C
  2302. luaP.POS_Bx = luaP.POS_C
  2303.  
  2304. ------------------------------------------------------------------------
  2305. -- limits for opcode arguments.
  2306. -- we use (signed) int to manipulate most arguments,
  2307. -- so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
  2308. ------------------------------------------------------------------------
  2309. -- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is
  2310. -- running on a Lua VM with double or int as LUA_NUMBER
  2311.  
  2312. luaP.MAXARG_Bx  = math.ldexp(1, luaP.SIZE_Bx) - 1
  2313. luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2)  -- 'sBx' is signed
  2314.  
  2315. luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1
  2316. luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1
  2317. luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1
  2318.  
  2319. -- creates a mask with 'n' 1 bits at position 'p'
  2320. -- MASK1(n,p) deleted, not required
  2321. -- creates a mask with 'n' 0 bits at position 'p'
  2322. -- MASK0(n,p) deleted, not required
  2323.  
  2324. --[[--------------------------------------------------------------------
  2325.   Visual representation for reference:
  2326.  
  2327.    31    |    |     |            0      bit position
  2328.     +-----+-----+-----+----------+
  2329.     |  B  |  C  |  A  |  Opcode  |      iABC format
  2330.     +-----+-----+-----+----------+
  2331.     -  9  -  9  -  8  -    6     -      field sizes
  2332.     +-----+-----+-----+----------+
  2333.     |   [s]Bx   |  A  |  Opcode  |      iABx | iAsBx format
  2334.     +-----+-----+-----+----------+
  2335.  
  2336. ----------------------------------------------------------------------]]
  2337.  
  2338. ------------------------------------------------------------------------
  2339. -- the following macros help to manipulate instructions
  2340. -- * changed to a table object representation, very clean compared to
  2341. --   the [nightmare] alternatives of using a number or a string
  2342. -- * Bx is a separate element from B and C, since there is never a need
  2343. --   to split Bx in the parser or code generator
  2344. ------------------------------------------------------------------------
  2345.  
  2346. -- these accept or return opcodes in the form of string names
  2347. function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end
  2348. function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end
  2349.  
  2350. function luaP:GETARG_A(i) return i.A end
  2351. function luaP:SETARG_A(i, u) i.A = u end
  2352.  
  2353. function luaP:GETARG_B(i) return i.B end
  2354. function luaP:SETARG_B(i, b) i.B = b end
  2355.  
  2356. function luaP:GETARG_C(i) return i.C end
  2357. function luaP:SETARG_C(i, b) i.C = b end
  2358.  
  2359. function luaP:GETARG_Bx(i) return i.Bx end
  2360. function luaP:SETARG_Bx(i, b) i.Bx = b end
  2361.  
  2362. function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end
  2363. function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end
  2364.  
  2365. function luaP:CREATE_ABC(o,a,b,c)
  2366.   return {OP = self.OpCode[o], A = a, B = b, C = c}
  2367. end
  2368.  
  2369. function luaP:CREATE_ABx(o,a,bc)
  2370.   return {OP = self.OpCode[o], A = a, Bx = bc}
  2371. end
  2372.  
  2373. ------------------------------------------------------------------------
  2374. -- create an instruction from a number (for OP_SETLIST)
  2375. ------------------------------------------------------------------------
  2376. function luaP:CREATE_Inst(c)
  2377.   local o = c % 64
  2378.   c = (c - o) / 64
  2379.   local a = c % 256
  2380.   c = (c - a) / 256
  2381.   return self:CREATE_ABx(o, a, c)
  2382. end
  2383.  
  2384. ------------------------------------------------------------------------
  2385. -- returns a 4-char string little-endian encoded form of an instruction
  2386. ------------------------------------------------------------------------
  2387. function luaP:Instruction(i)
  2388.   if i.Bx then
  2389.     -- change to OP/A/B/C format
  2390.     i.C = i.Bx % 512
  2391.     i.B = (i.Bx - i.C) / 512
  2392.   end
  2393.   local I = i.A * 64 + i.OP
  2394.   local c0 = I % 256
  2395.   I = i.C * 64 + (I - c0) / 256  -- 6 bits of A left
  2396.   local c1 = I % 256
  2397.   I = i.B * 128 + (I - c1) / 256  -- 7 bits of C left
  2398.   local c2 = I % 256
  2399.   local c3 = (I - c2) / 256
  2400.   return string.char(c0, c1, c2, c3)
  2401. end
  2402.  
  2403. ------------------------------------------------------------------------
  2404. -- decodes a 4-char little-endian string into an instruction struct
  2405. ------------------------------------------------------------------------
  2406. function luaP:DecodeInst(x)
  2407.   local byte = string.byte
  2408.   local i = {}
  2409.   local I = byte(x, 1)
  2410.   local op = I % 64
  2411.   i.OP = op
  2412.   I = byte(x, 2) * 4 + (I - op) / 64  -- 2 bits of c0 left
  2413.   local a = I % 256
  2414.   i.A = a
  2415.   I = byte(x, 3) * 4 + (I - a) / 256  -- 2 bits of c1 left
  2416.   local c = I % 512
  2417.   i.C = c
  2418.   i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left
  2419.   local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))]
  2420.   if opmode ~= "iABC" then
  2421.     i.Bx = i.B * 512 + i.C
  2422.   end
  2423.   return i
  2424. end
  2425.  
  2426. ------------------------------------------------------------------------
  2427. -- Macros to operate RK indices
  2428. -- * these use arithmetic instead of bit ops
  2429. ------------------------------------------------------------------------
  2430.  
  2431. -- this bit 1 means constant (0 means register)
  2432. luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1)
  2433.  
  2434. -- test whether value is a constant
  2435. function luaP:ISK(x) return x >= self.BITRK end
  2436.  
  2437. -- gets the index of the constant
  2438. function luaP:INDEXK(x) return x - self.BITRK end
  2439.  
  2440. luaP.MAXINDEXRK = luaP.BITRK - 1
  2441.  
  2442. -- code a constant index as a RK value
  2443. function luaP:RKASK(x) return x + self.BITRK end
  2444.  
  2445. ------------------------------------------------------------------------
  2446. -- invalid register that fits in 8 bits
  2447. ------------------------------------------------------------------------
  2448. luaP.NO_REG = luaP.MAXARG_A
  2449.  
  2450. ------------------------------------------------------------------------
  2451. -- R(x) - register
  2452. -- Kst(x) - constant (in constant table)
  2453. -- RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
  2454. ------------------------------------------------------------------------
  2455.  
  2456. ------------------------------------------------------------------------
  2457. -- grep "ORDER OP" if you change these enums
  2458. ------------------------------------------------------------------------
  2459.  
  2460. --[[--------------------------------------------------------------------
  2461. Lua virtual machine opcodes (enum OpCode):
  2462. ------------------------------------------------------------------------
  2463. name          args    description
  2464. ------------------------------------------------------------------------
  2465. OP_MOVE       A B     R(A) := R(B)
  2466. OP_LOADK      A Bx    R(A) := Kst(Bx)
  2467. OP_LOADBOOL   A B C   R(A) := (Bool)B; if (C) pc++
  2468. OP_LOADNIL    A B     R(A) := ... := R(B) := nil
  2469. OP_GETUPVAL   A B     R(A) := UpValue[B]
  2470. OP_GETGLOBAL  A Bx    R(A) := Gbl[Kst(Bx)]
  2471. OP_GETTABLE   A B C   R(A) := R(B)[RK(C)]
  2472. OP_SETGLOBAL  A Bx    Gbl[Kst(Bx)] := R(A)
  2473. OP_SETUPVAL   A B     UpValue[B] := R(A)
  2474. OP_SETTABLE   A B C   R(A)[RK(B)] := RK(C)
  2475. OP_NEWTABLE   A B C   R(A) := {} (size = B,C)
  2476. OP_SELF       A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]
  2477. OP_ADD        A B C   R(A) := RK(B) + RK(C)
  2478. OP_SUB        A B C   R(A) := RK(B) - RK(C)
  2479. OP_MUL        A B C   R(A) := RK(B) * RK(C)
  2480. OP_DIV        A B C   R(A) := RK(B) / RK(C)
  2481. OP_MOD        A B C   R(A) := RK(B) % RK(C)
  2482. OP_POW        A B C   R(A) := RK(B) ^ RK(C)
  2483. OP_UNM        A B     R(A) := -R(B)
  2484. OP_NOT        A B     R(A) := not R(B)
  2485. OP_LEN        A B     R(A) := length of R(B)
  2486. OP_CONCAT     A B C   R(A) := R(B).. ... ..R(C)
  2487. OP_JMP        sBx     pc+=sBx
  2488. OP_EQ         A B C   if ((RK(B) == RK(C)) ~= A) then pc++
  2489. OP_LT         A B C   if ((RK(B) <  RK(C)) ~= A) then pc++
  2490. OP_LE         A B C   if ((RK(B) <= RK(C)) ~= A) then pc++
  2491. OP_TEST       A C     if not (R(A) <=> C) then pc++
  2492. OP_TESTSET    A B C   if (R(B) <=> C) then R(A) := R(B) else pc++
  2493. OP_CALL       A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
  2494. OP_TAILCALL   A B C   return R(A)(R(A+1), ... ,R(A+B-1))
  2495. OP_RETURN     A B     return R(A), ... ,R(A+B-2)  (see note)
  2496. OP_FORLOOP    A sBx   R(A)+=R(A+2);
  2497.                       if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
  2498. OP_FORPREP    A sBx   R(A)-=R(A+2); pc+=sBx
  2499. OP_TFORLOOP   A C     R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
  2500.                       if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
  2501. OP_SETLIST    A B C   R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
  2502. OP_CLOSE      A       close all variables in the stack up to (>=) R(A)
  2503. OP_CLOSURE    A Bx    R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
  2504. OP_VARARG     A B     R(A), R(A+1), ..., R(A+B-1) = vararg
  2505. ----------------------------------------------------------------------]]
  2506.  
  2507. luaP.opnames = {}  -- opcode names
  2508. luaP.OpCode = {}   -- lookup name -> number
  2509. luaP.ROpCode = {}  -- lookup number -> name
  2510.  
  2511. ------------------------------------------------------------------------
  2512. -- ORDER OP
  2513. ------------------------------------------------------------------------
  2514. local i = 0
  2515. for v in string.gmatch([[
  2516. MOVE LOADK LOADBOOL LOADNIL GETUPVAL
  2517. GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE
  2518. NEWTABLE SELF ADD SUB MUL
  2519. DIV MOD POW UNM NOT
  2520. LEN CONCAT JMP EQ LT
  2521. LE TEST TESTSET CALL TAILCALL
  2522. RETURN FORLOOP FORPREP TFORLOOP SETLIST
  2523. CLOSE CLOSURE VARARG
  2524. ]], "%S+") do
  2525.   local n = "OP_"..v
  2526.   luaP.opnames[i] = v
  2527.   luaP.OpCode[n] = i
  2528.   luaP.ROpCode[i] = n
  2529.   i = i + 1
  2530. end
  2531. luaP.NUM_OPCODES = i
  2532.  
  2533. --[[
  2534. ===========================================================================
  2535.   Notes:
  2536.   (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
  2537.       and can be 0: OP_CALL then sets 'top' to last_result+1, so
  2538.       next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
  2539.   (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
  2540.       set top (like in OP_CALL with C == 0).
  2541.   (*) In OP_RETURN, if (B == 0) then return up to 'top'
  2542.   (*) In OP_SETLIST, if (B == 0) then B = 'top';
  2543.       if (C == 0) then next 'instruction' is real C
  2544.   (*) For comparisons, A specifies what condition the test should accept
  2545.       (true or false).
  2546.   (*) All 'skips' (pc++) assume that next instruction is a jump
  2547. ===========================================================================
  2548. --]]
  2549.  
  2550. --[[--------------------------------------------------------------------
  2551.   masks for instruction properties. The format is:
  2552.   bits 0-1: op mode
  2553.   bits 2-3: C arg mode
  2554.   bits 4-5: B arg mode
  2555.   bit 6: instruction set register A
  2556.   bit 7: operator is a test
  2557.  
  2558.   for OpArgMask:
  2559.   OpArgN - argument is not used
  2560.   OpArgU - argument is used
  2561.   OpArgR - argument is a register or a jump offset
  2562.   OpArgK - argument is a constant or register/constant
  2563. ----------------------------------------------------------------------]]
  2564.  
  2565. -- was enum OpArgMask
  2566. luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 }
  2567.  
  2568. ------------------------------------------------------------------------
  2569. -- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC
  2570. -- * accepts opcode parameter as strings, e.g. "OP_MOVE"
  2571. ------------------------------------------------------------------------
  2572.  
  2573. function luaP:getOpMode(m)
  2574.   return self.opmodes[self.OpCode[m]] % 4
  2575. end
  2576.  
  2577. function luaP:getBMode(m)
  2578.   return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4
  2579. end
  2580.  
  2581. function luaP:getCMode(m)
  2582.   return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4
  2583. end
  2584.  
  2585. function luaP:testAMode(m)
  2586.   return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2
  2587. end
  2588.  
  2589. function luaP:testTMode(m)
  2590.   return math.floor(self.opmodes[self.OpCode[m]] / 128)
  2591. end
  2592.  
  2593. -- luaP_opnames[] is set above, as the luaP.opnames table
  2594.  
  2595. -- number of list items to accumulate before a SETLIST instruction
  2596. luaP.LFIELDS_PER_FLUSH = 50
  2597.  
  2598. ------------------------------------------------------------------------
  2599. -- build instruction properties array
  2600. -- * deliberately coded to look like the C equivalent
  2601. ------------------------------------------------------------------------
  2602. local function opmode(t, a, b, c, m)
  2603.   local luaP = luaP
  2604.   return t * 128 + a * 64 +
  2605.          luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m]
  2606. end
  2607.  
  2608. -- ORDER OP
  2609. luaP.opmodes = {
  2610. -- T A B C mode opcode
  2611.   opmode(0, 1, "OpArgK", "OpArgN", "iABx"),     -- OP_LOADK
  2612.   opmode(0, 1, "OpArgU", "OpArgU", "iABC"),     -- OP_LOADBOOL
  2613.   opmode(0, 1, "OpArgR", "OpArgN", "iABC"),     -- OP_LOADNIL
  2614.   opmode(0, 1, "OpArgU", "OpArgN", "iABC"),     -- OP_GETUPVAL
  2615.   opmode(0, 1, "OpArgK", "OpArgN", "iABx"),     -- OP_GETGLOBAL
  2616.   opmode(0, 1, "OpArgR", "OpArgK", "iABC"),     -- OP_GETTABLE
  2617.   opmode(0, 0, "OpArgK", "OpArgN", "iABx"),     -- OP_SETGLOBAL
  2618.   opmode(0, 0, "OpArgU", "OpArgN", "iABC"),     -- OP_SETUPVAL
  2619.   opmode(0, 0, "OpArgK", "OpArgK", "iABC"),     -- OP_SETTABLE
  2620.   opmode(0, 1, "OpArgU", "OpArgU", "iABC"),     -- OP_NEWTABLE
  2621.   opmode(0, 1, "OpArgR", "OpArgK", "iABC"),     -- OP_SELF
  2622.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_ADD
  2623.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_SUB
  2624.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_MUL
  2625.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_DIV
  2626.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_MOD
  2627.   opmode(0, 1, "OpArgK", "OpArgK", "iABC"),     -- OP_POW
  2628.   opmode(0, 1, "OpArgR", "OpArgN", "iABC"),     -- OP_UNM
  2629.   opmode(0, 1, "OpArgR", "OpArgN", "iABC"),     -- OP_NOT
  2630.   opmode(0, 1, "OpArgR", "OpArgN", "iABC"),     -- OP_LEN
  2631.   opmode(0, 1, "OpArgR", "OpArgR", "iABC"),     -- OP_CONCAT
  2632.   opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"),    -- OP_JMP
  2633.   opmode(1, 0, "OpArgK", "OpArgK", "iABC"),     -- OP_EQ
  2634.   opmode(1, 0, "OpArgK", "OpArgK", "iABC"),     -- OP_LT
  2635.   opmode(1, 0, "OpArgK", "OpArgK", "iABC"),     -- OP_LE
  2636.   opmode(1, 1, "OpArgR", "OpArgU", "iABC"),     -- OP_TEST
  2637.   opmode(1, 1, "OpArgR", "OpArgU", "iABC"),     -- OP_TESTSET
  2638.   opmode(0, 1, "OpArgU", "OpArgU", "iABC"),     -- OP_CALL
  2639.   opmode(0, 1, "OpArgU", "OpArgU", "iABC"),     -- OP_TAILCALL
  2640.   opmode(0, 0, "OpArgU", "OpArgN", "iABC"),     -- OP_RETURN
  2641.   opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"),    -- OP_FORLOOP
  2642.   opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"),    -- OP_FORPREP
  2643.   opmode(1, 0, "OpArgN", "OpArgU", "iABC"),     -- OP_TFORLOOP
  2644.   opmode(0, 0, "OpArgU", "OpArgU", "iABC"),     -- OP_SETLIST
  2645.   opmode(0, 0, "OpArgN", "OpArgN", "iABC"),     -- OP_CLOSE
  2646.   opmode(0, 1, "OpArgU", "OpArgN", "iABx"),     -- OP_CLOSURE
  2647.   opmode(0, 1, "OpArgU", "OpArgN", "iABC"),     -- OP_VARARG
  2648. }
  2649. -- an awkward way to set a zero-indexed table...
  2650. luaP.opmodes[0] =
  2651.   opmode(0, 1, "OpArgR", "OpArgN", "iABC")      -- OP_MOVE
  2652.  
  2653. return luaP
  2654. end
  2655.  
  2656. function LuaU()
  2657. local script = script.LuaU
  2658. --[[--------------------------------------------------------------------
  2659.  
  2660.   ldump.lua
  2661.   Save precompiled Lua chunks
  2662.   This file is part of Yueliang.
  2663.  
  2664.   Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
  2665.   The COPYRIGHT file describes the conditions
  2666.   under which this software may be distributed.
  2667.  
  2668.   See the ChangeLog for more information.
  2669.  
  2670. ----------------------------------------------------------------------]]
  2671.  
  2672. --[[--------------------------------------------------------------------
  2673. -- Notes:
  2674. -- * WARNING! byte order (little endian) and data type sizes for header
  2675. --   signature values hard-coded; see luaU:header
  2676. -- * chunk writer generators are included, see below
  2677. -- * one significant difference is that instructions are still in table
  2678. --   form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to
  2679. --   convert them into 4-char strings
  2680. --
  2681. -- Not implemented:
  2682. -- * DumpVar, DumpMem has been removed
  2683. -- * DumpVector folded into folded into DumpDebug, DumpCode
  2684. --
  2685. -- Added:
  2686. -- * for convenience, the following two functions have been added:
  2687. --   luaU:make_setS: create a chunk writer that writes to a string
  2688. --   luaU:make_setF: create a chunk writer that writes to a file
  2689. --   (lua.h contains a typedef for lua_Writer/lua_Chunkwriter, and
  2690. --    a Lua-based implementation exists, writer() in lstrlib.c)
  2691. -- * luaU:ttype(o) (from lobject.h)
  2692. -- * for converting number types to its binary equivalent:
  2693. --   luaU:from_double(x): encode double value for writing
  2694. --   luaU:from_int(x): encode integer value for writing
  2695. --     (error checking is limited for these conversion functions)
  2696. --     (double conversion does not support denormals or NaNs)
  2697. --
  2698. -- Changed in 5.1.x:
  2699. -- * the dumper was mostly rewritten in Lua 5.1.x, so notes on the
  2700. --   differences between 5.0.x and 5.1.x is limited
  2701. -- * LUAC_VERSION bumped to 0x51, LUAC_FORMAT added
  2702. -- * developer is expected to adjust LUAC_FORMAT in order to identify
  2703. --   non-standard binary chunk formats
  2704. -- * header signature code is smaller, has been simplified, and is
  2705. --   tested as a single unit; its logic is shared with the undumper
  2706. -- * no more endian conversion, invalid endianness mean rejection
  2707. -- * opcode field sizes are no longer exposed in the header
  2708. -- * code moved to front of a prototype, followed by constants
  2709. -- * debug information moved to the end of the binary chunk, and the
  2710. --   relevant functions folded into a single function
  2711. -- * luaU:dump returns a writer status code
  2712. -- * chunk writer now implements status code because dumper uses it
  2713. -- * luaU:endianness removed
  2714. ----------------------------------------------------------------------]]
  2715.  
  2716. --requires luaP
  2717. local luaU = {}
  2718. local luaP = require(script.Parent.LuaP)
  2719.  
  2720. -- mark for precompiled code ('<esc>Lua') (from lua.h)
  2721. luaU.LUA_SIGNATURE = "\27Lua"
  2722.  
  2723. -- constants used by dumper (from lua.h)
  2724. luaU.LUA_TNUMBER  = 3
  2725. luaU.LUA_TSTRING  = 4
  2726. luaU.LUA_TNIL     = 0
  2727. luaU.LUA_TBOOLEAN = 1
  2728. luaU.LUA_TNONE    = -1
  2729.  
  2730. -- constants for header of binary files (from lundump.h)
  2731. luaU.LUAC_VERSION    = 0x51     -- this is Lua 5.1
  2732. luaU.LUAC_FORMAT     = 0        -- this is the official format
  2733. luaU.LUAC_HEADERSIZE = 12       -- size of header of binary files
  2734.  
  2735. --[[--------------------------------------------------------------------
  2736. -- Additional functions to handle chunk writing
  2737. -- * to use make_setS and make_setF, see test_ldump.lua elsewhere
  2738. ----------------------------------------------------------------------]]
  2739.  
  2740. ------------------------------------------------------------------------
  2741. -- create a chunk writer that writes to a string
  2742. -- * returns the writer function and a table containing the string
  2743. -- * to get the final result, look in buff.data
  2744. ------------------------------------------------------------------------
  2745. function luaU:make_setS()
  2746.   local buff = {}
  2747.         buff.data = ""
  2748.   local writer =
  2749.     function(s, buff)  -- chunk writer
  2750.       if not s then return 0 end
  2751.       buff.data = buff.data..s
  2752.       return 0
  2753.     end
  2754.   return writer, buff
  2755. end
  2756.  
  2757. ------------------------------------------------------------------------
  2758. -- create a chunk writer that writes to a file
  2759. -- * returns the writer function and a table containing the file handle
  2760. -- * if a nil is passed, then writer should close the open file
  2761. ------------------------------------------------------------------------
  2762.  
  2763. --[[
  2764. function luaU:make_setF(filename)
  2765.   local buff = {}
  2766.         buff.h = io.open(filename, "wb")
  2767.   if not buff.h then return nil end
  2768.   local writer =
  2769.     function(s, buff)  -- chunk writer
  2770.       if not buff.h then return 0 end
  2771.       if not s then
  2772.         if buff.h:close() then return 0 end
  2773.       else
  2774.         if buff.h:write(s) then return 0 end
  2775.       end
  2776.       return 1
  2777.     end
  2778.   return writer, buff
  2779. end--]]
  2780.  
  2781. ------------------------------------------------------------------------
  2782. -- works like the lobject.h version except that TObject used in these
  2783. -- scripts only has a 'value' field, no 'tt' field (native types used)
  2784. ------------------------------------------------------------------------
  2785. function luaU:ttype(o)
  2786.   local tt = type(o.value)
  2787.   if tt == "number" then return self.LUA_TNUMBER
  2788.   elseif tt == "string" then return self.LUA_TSTRING
  2789.   elseif tt == "nil" then return self.LUA_TNIL
  2790.   elseif tt == "boolean" then return self.LUA_TBOOLEAN
  2791.   else
  2792.     return self.LUA_TNONE  -- the rest should not appear
  2793.   end
  2794. end
  2795.  
  2796. -----------------------------------------------------------------------
  2797. -- converts a IEEE754 double number to an 8-byte little-endian string
  2798. -- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake
  2799. -- * supports +/- Infinity, but not denormals or NaNs
  2800. -----------------------------------------------------------------------
  2801. function luaU:from_double(x)
  2802.   local function grab_byte(v)
  2803.     local c = v % 256
  2804.     return (v - c) / 256, string.char(c)
  2805.   end
  2806.   local sign = 0
  2807.   if x < 0 then sign = 1; x = -x end
  2808.   local mantissa, exponent = math.frexp(x)
  2809.   if x == 0 then -- zero
  2810.     mantissa, exponent = 0, 0
  2811.   elseif x == 1/0 then
  2812.     mantissa, exponent = 0, 2047
  2813.   else
  2814.     mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53)
  2815.     exponent = exponent + 1022
  2816.   end
  2817.   local v, byte = "" -- convert to bytes
  2818.   x = math.floor(mantissa)
  2819.   for i = 1,6 do
  2820.     x, byte = grab_byte(x); v = v..byte -- 47:0
  2821.   end
  2822.   x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48
  2823.   x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56
  2824.   return v
  2825. end
  2826.  
  2827. -----------------------------------------------------------------------
  2828. -- converts a number to a little-endian 32-bit integer string
  2829. -- * input value assumed to not overflow, can be signed/unsigned
  2830. -----------------------------------------------------------------------
  2831. function luaU:from_int(x)
  2832.   local v = ""
  2833.   x = math.floor(x)
  2834.   if x < 0 then x = 4294967296 + x end  -- ULONG_MAX+1
  2835.   for i = 1, 4 do
  2836.     local c = x % 256
  2837.     v = v..string.char(c); x = math.floor(x / 256)
  2838.   end
  2839.   return v
  2840. end
  2841.  
  2842. --[[--------------------------------------------------------------------
  2843. -- Functions to make a binary chunk
  2844. -- * many functions have the size parameter removed, since output is
  2845. --   in the form of a string and some sizes are implicit or hard-coded
  2846. ----------------------------------------------------------------------]]
  2847.  
  2848. --[[--------------------------------------------------------------------
  2849. -- struct DumpState:
  2850. --   L  -- lua_State (not used in this script)
  2851. --   writer  -- lua_Writer (chunk writer function)
  2852. --   data  -- void* (chunk writer context or data already written)
  2853. --   strip  -- if true, don't write any debug information
  2854. --   status  -- if non-zero, an error has occured
  2855. ----------------------------------------------------------------------]]
  2856.  
  2857. ------------------------------------------------------------------------
  2858. -- dumps a block of bytes
  2859. -- * lua_unlock(D.L), lua_lock(D.L) unused
  2860. ------------------------------------------------------------------------
  2861. function luaU:DumpBlock(b, D)
  2862.   if D.status == 0 then
  2863.     -- lua_unlock(D->L);
  2864.     D.status = D.write(b, D.data)
  2865.     -- lua_lock(D->L);
  2866.   end
  2867. end
  2868.  
  2869. ------------------------------------------------------------------------
  2870. -- dumps a char
  2871. ------------------------------------------------------------------------
  2872. function luaU:DumpChar(y, D)
  2873.   self:DumpBlock(string.char(y), D)
  2874. end
  2875.  
  2876. ------------------------------------------------------------------------
  2877. -- dumps a 32-bit signed or unsigned integer (for int) (hard-coded)
  2878. ------------------------------------------------------------------------
  2879. function luaU:DumpInt(x, D)
  2880.   self:DumpBlock(self:from_int(x), D)
  2881. end
  2882.  
  2883. ------------------------------------------------------------------------
  2884. -- dumps a lua_Number (hard-coded as a double)
  2885. ------------------------------------------------------------------------
  2886. function luaU:DumpNumber(x, D)
  2887.   self:DumpBlock(self:from_double(x), D)
  2888. end
  2889.  
  2890. ------------------------------------------------------------------------
  2891. -- dumps a Lua string (size type is hard-coded)
  2892. ------------------------------------------------------------------------
  2893. function luaU:DumpString(s, D)
  2894.   if s == nil then
  2895.     self:DumpInt(0, D)
  2896.   else
  2897.     s = s.."\0"  -- include trailing '\0'
  2898.     self:DumpInt(#s, D)
  2899.     self:DumpBlock(s, D)
  2900.   end
  2901. end
  2902.  
  2903. ------------------------------------------------------------------------
  2904. -- dumps instruction block from function prototype
  2905. ------------------------------------------------------------------------
  2906. function luaU:DumpCode(f, D)
  2907.   local n = f.sizecode
  2908.   --was DumpVector
  2909.   self:DumpInt(n, D)
  2910.   for i = 0, n - 1 do
  2911.     self:DumpBlock(luaP:Instruction(f.code[i]), D)
  2912.   end
  2913. end
  2914.  
  2915. ------------------------------------------------------------------------
  2916. -- dump constant pool from function prototype
  2917. -- * bvalue(o), nvalue(o) and rawtsvalue(o) macros removed
  2918. ------------------------------------------------------------------------
  2919. function luaU:DumpConstants(f, D)
  2920.   local n = f.sizek
  2921.   self:DumpInt(n, D)
  2922.   for i = 0, n - 1 do
  2923.     local o = f.k[i]  -- TValue
  2924.     local tt = self:ttype(o)
  2925.     self:DumpChar(tt, D)
  2926.     if tt == self.LUA_TNIL then
  2927.     elseif tt == self.LUA_TBOOLEAN then
  2928.       self:DumpChar(o.value and 1 or 0, D)
  2929.     elseif tt == self.LUA_TNUMBER then
  2930.       self:DumpNumber(o.value, D)
  2931.     elseif tt == self.LUA_TSTRING then
  2932.       self:DumpString(o.value, D)
  2933.     else
  2934.       --lua_assert(0)  -- cannot happen
  2935.     end
  2936.   end
  2937.   n = f.sizep
  2938.   self:DumpInt(n, D)
  2939.   for i = 0, n - 1 do
  2940.     self:DumpFunction(f.p[i], f.source, D)
  2941.   end
  2942. end
  2943.  
  2944. ------------------------------------------------------------------------
  2945. -- dump debug information
  2946. ------------------------------------------------------------------------
  2947. function luaU:DumpDebug(f, D)
  2948.   local n
  2949.   n = D.strip and 0 or f.sizelineinfo           -- dump line information
  2950.   --was DumpVector
  2951.   self:DumpInt(n, D)
  2952.   for i = 0, n - 1 do
  2953.     self:DumpInt(f.lineinfo[i], D)
  2954.   end
  2955.   n = D.strip and 0 or f.sizelocvars            -- dump local information
  2956.   self:DumpInt(n, D)
  2957.   for i = 0, n - 1 do
  2958.     self:DumpString(f.locvars[i].varname, D)
  2959.     self:DumpInt(f.locvars[i].startpc, D)
  2960.     self:DumpInt(f.locvars[i].endpc, D)
  2961.   end
  2962.   n = D.strip and 0 or f.sizeupvalues           -- dump upvalue information
  2963.   self:DumpInt(n, D)
  2964.   for i = 0, n - 1 do
  2965.     self:DumpString(f.upvalues[i], D)
  2966.   end
  2967. end
  2968.  
  2969. ------------------------------------------------------------------------
  2970. -- dump child function prototypes from function prototype
  2971. ------------------------------------------------------------------------
  2972. function luaU:DumpFunction(f, p, D)
  2973.   local source = f.source
  2974.   if source == p or D.strip then source = nil end
  2975.   self:DumpString(source, D)
  2976.   self:DumpInt(f.lineDefined, D)
  2977.   self:DumpInt(f.lastlinedefined, D)
  2978.   self:DumpChar(f.nups, D)
  2979.   self:DumpChar(f.numparams, D)
  2980.   self:DumpChar(f.is_vararg, D)
  2981.   self:DumpChar(f.maxstacksize, D)
  2982.   self:DumpCode(f, D)
  2983.   self:DumpConstants(f, D)
  2984.   self:DumpDebug(f, D)
  2985. end
  2986.  
  2987. ------------------------------------------------------------------------
  2988. -- dump Lua header section (some sizes hard-coded)
  2989. ------------------------------------------------------------------------
  2990. function luaU:DumpHeader(D)
  2991.   local h = self:header()
  2992.   assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert
  2993.   self:DumpBlock(h, D)
  2994. end
  2995.  
  2996. ------------------------------------------------------------------------
  2997. -- make header (from lundump.c)
  2998. -- returns the header string
  2999. ------------------------------------------------------------------------
  3000. function luaU:header()
  3001.  local x = 1
  3002.  return self.LUA_SIGNATURE..
  3003.         string.char(
  3004.           self.LUAC_VERSION,
  3005.           self.LUAC_FORMAT,
  3006.           x,                    -- endianness (1=little)
  3007.           4,                    -- sizeof(int)
  3008.           4,                    -- sizeof(size_t)
  3009.           4,                    -- sizeof(Instruction)
  3010.           8,                    -- sizeof(lua_Number)
  3011.           0)                    -- is lua_Number integral?
  3012. end
  3013.  
  3014. ------------------------------------------------------------------------
  3015. -- dump Lua function as precompiled chunk
  3016. -- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
  3017. -- * w, data are created from make_setS, make_setF
  3018. ------------------------------------------------------------------------
  3019. function luaU:dump(L, f, w, data, strip)
  3020.   local D = {}  -- DumpState
  3021.   D.L = L
  3022.   D.write = w
  3023.   D.data = data
  3024.   D.strip = strip
  3025.   D.status = 0
  3026.   self:DumpHeader(D)
  3027.   self:DumpFunction(f, nil, D)
  3028.   -- added: for a chunk writer writing to a file, this final call with
  3029.   -- nil data is to indicate to the writer to close the file
  3030.   D.write(nil, D.data)
  3031.   return D.status
  3032. end
  3033.  
  3034. return luaU
  3035. end
  3036.  
  3037. function LuaX()
  3038. local script = script.LuaX
  3039. --[[--------------------------------------------------------------------
  3040.  
  3041.   llex.lua
  3042.   Lua lexical analyzer in Lua
  3043.   This file is part of Yueliang.
  3044.  
  3045.   Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
  3046.   The COPYRIGHT file describes the conditions
  3047.   under which this software may be distributed.
  3048.  
  3049.   See the ChangeLog for more information.
  3050.  
  3051. ----------------------------------------------------------------------]]
  3052.  
  3053. --[[--------------------------------------------------------------------
  3054. -- Notes:
  3055. -- * intended to 'imitate' llex.c code; performance is not a concern
  3056. -- * tokens are strings; code structure largely retained
  3057. -- * deleted stuff (compared to llex.c) are noted, comments retained
  3058. -- * nextc() returns the currently read character to simplify coding
  3059. --   here; next() in llex.c does not return anything
  3060. -- * compatibility code is marked with "--#" comments
  3061. --
  3062. -- Added:
  3063. -- * luaX:chunkid (function luaO_chunkid from lobject.c)
  3064. -- * luaX:str2d (function luaO_str2d from lobject.c)
  3065. -- * luaX.LUA_QS used in luaX:lexerror (from luaconf.h)
  3066. -- * luaX.LUA_COMPAT_LSTR in luaX:read_long_string (from luaconf.h)
  3067. -- * luaX.MAX_INT used in luaX:inclinenumber (from llimits.h)
  3068. --
  3069. -- To use the lexer:
  3070. -- (1) luaX:init() to initialize the lexer
  3071. -- (2) luaX:setinput() to set the input stream to lex
  3072. -- (3) call luaX:next() or luaX:luaX:lookahead() to get tokens,
  3073. --     until "TK_EOS": luaX:next()
  3074. -- * since EOZ is returned as a string, be careful when regexp testing
  3075. --
  3076. -- Not implemented:
  3077. -- * luaX_newstring: not required by this Lua implementation
  3078. -- * buffer MAX_SIZET size limit (from llimits.h) test not implemented
  3079. --   in the interest of performance
  3080. -- * locale-aware number handling is largely redundant as Lua's
  3081. --   tonumber() function is already capable of this
  3082. --
  3083. -- Changed in 5.1.x:
  3084. -- * TK_NAME token order moved down
  3085. -- * string representation for TK_NAME, TK_NUMBER, TK_STRING changed
  3086. -- * token struct renamed to lower case (LS -> ls)
  3087. -- * LexState struct: removed nestlevel, added decpoint
  3088. -- * error message functions have been greatly simplified
  3089. -- * token2string renamed to luaX_tokens, exposed in llex.h
  3090. -- * lexer now handles all kinds of newlines, including CRLF
  3091. -- * shbang first line handling removed from luaX:setinput;
  3092. --   it is now done in lauxlib.c (luaL_loadfile)
  3093. -- * next(ls) macro renamed to nextc(ls) due to new luaX_next function
  3094. -- * EXTRABUFF and MAXNOCHECK removed due to lexer changes
  3095. -- * checkbuffer(ls, len) macro deleted
  3096. -- * luaX:read_numeral now has 3 support functions: luaX:trydecpoint,
  3097. --   luaX:buffreplace and (luaO_str2d from lobject.c) luaX:str2d
  3098. -- * luaX:read_numeral is now more promiscuous in slurping characters;
  3099. --   hexadecimal numbers was added, locale-aware decimal points too
  3100. -- * luaX:skip_sep is new; used by luaX:read_long_string
  3101. -- * luaX:read_long_string handles new-style long blocks, with some
  3102. --   optional compatibility code
  3103. -- * luaX:llex: parts changed to support new-style long blocks
  3104. -- * luaX:llex: readname functionality has been folded in
  3105. -- * luaX:llex: removed test for control characters
  3106. --
  3107. --------------------------------------------------------------------]]
  3108.  
  3109. local luaZ = require(script.Parent.LuaZ)
  3110.  
  3111. local luaX = {}
  3112.  
  3113. -- FIRST_RESERVED is not required as tokens are manipulated as strings
  3114. -- TOKEN_LEN deleted; maximum length of a reserved word not needed
  3115.  
  3116. ------------------------------------------------------------------------
  3117. -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
  3118. ------------------------------------------------------------------------
  3119.  
  3120. -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
  3121. -- other terminal symbols: TK_NAME to TK_EOS
  3122. luaX.RESERVED = [[
  3123. TK_AND and
  3124. TK_BREAK break
  3125. TK_DO do
  3126. TK_ELSE else
  3127. TK_ELSEIF elseif
  3128. TK_END end
  3129. TK_FALSE false
  3130. TK_FOR for
  3131. TK_FUNCTION function
  3132. TK_IF if
  3133. TK_IN in
  3134. TK_LOCAL local
  3135. TK_NIL nil
  3136. TK_NOT not
  3137. TK_OR or
  3138. TK_REPEAT repeat
  3139. TK_RETURN return
  3140. TK_THEN then
  3141. TK_TRUE true
  3142. TK_UNTIL until
  3143. TK_WHILE while
  3144. TK_CONCAT ..
  3145. TK_DOTS ...
  3146. TK_EQ ==
  3147. TK_GE >=
  3148. TK_LE <=
  3149. TK_NE ~=
  3150. TK_NAME <name>
  3151. TK_NUMBER <number>
  3152. TK_STRING <string>
  3153. TK_EOS <eof>]]
  3154.  
  3155. -- NUM_RESERVED is not required; number of reserved words
  3156.  
  3157. --[[--------------------------------------------------------------------
  3158. -- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed
  3159. -- so that lexer functions can use its table element, ls.t.seminfo
  3160. --
  3161. -- SemInfo (struct no longer needed, a mixed-type value is used)
  3162. --
  3163. -- Token (struct of ls.t and ls.lookahead):
  3164. --   token  -- token symbol
  3165. --   seminfo  -- semantics information
  3166. --
  3167. -- LexState (struct of ls; ls is initialized by luaX:setinput):
  3168. --   current  -- current character (charint)
  3169. --   linenumber  -- input line counter
  3170. --   lastline  -- line of last token 'consumed'
  3171. --   t  -- current token (table: struct Token)
  3172. --   lookahead  -- look ahead token (table: struct Token)
  3173. --   fs  -- 'FuncState' is private to the parser
  3174. --   L -- LuaState
  3175. --   z  -- input stream
  3176. --   buff  -- buffer for tokens
  3177. --   source  -- current source name
  3178. --   decpoint -- locale decimal point
  3179. --   nestlevel  -- level of nested non-terminals
  3180. ----------------------------------------------------------------------]]
  3181.  
  3182. -- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init
  3183.  
  3184. luaX.MAXSRC = 80
  3185. luaX.MAX_INT = 2147483645       -- constants from elsewhere (see above)
  3186. luaX.LUA_QS = "'%s'"
  3187. luaX.LUA_COMPAT_LSTR = 1
  3188. --luaX.MAX_SIZET = 4294967293
  3189.  
  3190. ------------------------------------------------------------------------
  3191. -- initialize lexer
  3192. -- * original luaX_init has code to create and register token strings
  3193. -- * luaX.tokens: TK_* -> token
  3194. -- * luaX.enums:  token -> TK_* (used in luaX:llex)
  3195. ------------------------------------------------------------------------
  3196. function luaX:init()
  3197.   local tokens, enums = {}, {}
  3198.   for v in string.gmatch(self.RESERVED, "[^\n]+") do
  3199.     local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
  3200.     tokens[tok] = str
  3201.     enums[str] = tok
  3202.   end
  3203.   self.tokens = tokens
  3204.   self.enums = enums
  3205. end
  3206.  
  3207. ------------------------------------------------------------------------
  3208. -- returns a suitably-formatted chunk name or id
  3209. -- * from lobject.c, used in llex.c and ldebug.c
  3210. -- * the result, out, is returned (was first argument)
  3211. ------------------------------------------------------------------------
  3212. function luaX:chunkid(source, bufflen)
  3213.   local out
  3214.   local first = string.sub(source, 1, 1)
  3215.   if first == "=" then
  3216.     out = string.sub(source, 2, bufflen)  -- remove first char
  3217.   else  -- out = "source", or "...source"
  3218.     if first == "@" then
  3219.       source = string.sub(source, 2)  -- skip the '@'
  3220.       bufflen = bufflen - #" '...' "
  3221.       local l = #source
  3222.       out = ""
  3223.       if l > bufflen then
  3224.         source = string.sub(source, 1 + l - bufflen)  -- get last part of file name
  3225.         out = out.."..."
  3226.       end
  3227.       out = out..source
  3228.     else  -- out = [string "string"]
  3229.       local len = string.find(source, "[\n\r]")  -- stop at first newline
  3230.       len = len and (len - 1) or #source
  3231.       bufflen = bufflen - #(" [string \"...\"] ")
  3232.       if len > bufflen then len = bufflen end
  3233.       out = "[string \""
  3234.       if len < #source then  -- must truncate?
  3235.         out = out..string.sub(source, 1, len).."..."
  3236.       else
  3237.         out = out..source
  3238.       end
  3239.       out = out.."\"]"
  3240.     end
  3241.   end
  3242.   return out
  3243. end
  3244.  
  3245. --[[--------------------------------------------------------------------
  3246. -- Support functions for lexer
  3247. -- * all lexer errors eventually reaches lexerror:
  3248.      syntaxerror -> lexerror
  3249. ----------------------------------------------------------------------]]
  3250.  
  3251. ------------------------------------------------------------------------
  3252. -- look up token and return keyword if found (also called by parser)
  3253. ------------------------------------------------------------------------
  3254. function luaX:token2str(ls, token)
  3255.   if string.sub(token, 1, 3) ~= "TK_" then
  3256.     if string.find(token, "%c") then
  3257.       return string.format("char(%d)", string.byte(token))
  3258.     end
  3259.     return token
  3260.   else
  3261.   end
  3262.     return self.tokens[token]
  3263. end
  3264.  
  3265. ------------------------------------------------------------------------
  3266. -- throws a lexer error
  3267. -- * txtToken has been made local to luaX:lexerror
  3268. -- * can't communicate LUA_ERRSYNTAX, so it is unimplemented
  3269. ------------------------------------------------------------------------
  3270. function luaX:lexerror(ls, msg, token)
  3271.   local function txtToken(ls, token)
  3272.     if token == "TK_NAME" or
  3273.        token == "TK_STRING" or
  3274.        token == "TK_NUMBER" then
  3275.       return ls.buff
  3276.     else
  3277.       return self:token2str(ls, token)
  3278.     end
  3279.   end
  3280.   local buff = self:chunkid(ls.source, self.MAXSRC)
  3281.   local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg)
  3282.   if token then
  3283.     msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token))
  3284.   end
  3285.   -- luaD_throw(ls->L, LUA_ERRSYNTAX)
  3286.   error(msg)
  3287. end
  3288.  
  3289. ------------------------------------------------------------------------
  3290. -- throws a syntax error (mainly called by parser)
  3291. -- * ls.t.token has to be set by the function calling luaX:llex
  3292. --   (see luaX:next and luaX:lookahead elsewhere in this file)
  3293. ------------------------------------------------------------------------
  3294. function luaX:syntaxerror(ls, msg)
  3295.   self:lexerror(ls, msg, ls.t.token)
  3296. end
  3297.  
  3298. ------------------------------------------------------------------------
  3299. -- move on to next line
  3300. ------------------------------------------------------------------------
  3301. function luaX:currIsNewline(ls)
  3302.   return ls.current == "\n" or ls.current == "\r"
  3303. end
  3304.  
  3305. function luaX:inclinenumber(ls)
  3306.   local old = ls.current
  3307.   -- lua_assert(currIsNewline(ls))
  3308.   self:nextc(ls)  -- skip '\n' or '\r'
  3309.   if self:currIsNewline(ls) and ls.current ~= old then
  3310.     self:nextc(ls)  -- skip '\n\r' or '\r\n'
  3311.   end
  3312.   ls.linenumber = ls.linenumber + 1
  3313.   if ls.linenumber >= self.MAX_INT then
  3314.     self:syntaxerror(ls, "chunk has too many lines")
  3315.   end
  3316. end
  3317.  
  3318. ------------------------------------------------------------------------
  3319. -- initializes an input stream for lexing
  3320. -- * if ls (the lexer state) is passed as a table, then it is filled in,
  3321. --   otherwise it has to be retrieved as a return value
  3322. -- * LUA_MINBUFFER not used; buffer handling not required any more
  3323. ------------------------------------------------------------------------
  3324. function luaX:setinput(L, ls, z, source)
  3325.   if not ls then ls = {} end  -- create struct
  3326.   if not ls.lookahead then ls.lookahead = {} end
  3327.   if not ls.t then ls.t = {} end
  3328.   ls.decpoint = "."
  3329.   ls.L = L
  3330.   ls.lookahead.token = "TK_EOS"  -- no look-ahead token
  3331.   ls.z = z
  3332.   ls.fs = nil
  3333.   ls.linenumber = 1
  3334.   ls.lastline = 1
  3335.   ls.source = source
  3336.   self:nextc(ls)  -- read first char
  3337. end
  3338.  
  3339. --[[--------------------------------------------------------------------
  3340. -- LEXICAL ANALYZER
  3341. ----------------------------------------------------------------------]]
  3342.  
  3343. ------------------------------------------------------------------------
  3344. -- checks if current character read is found in the set 'set'
  3345. ------------------------------------------------------------------------
  3346. function luaX:check_next(ls, set)
  3347.   if not string.find(set, ls.current, 1, 1) then
  3348.     return false
  3349.   end
  3350.   self:save_and_next(ls)
  3351.   return true
  3352. end
  3353.  
  3354. ------------------------------------------------------------------------
  3355. -- retrieve next token, checking the lookahead buffer if necessary
  3356. -- * note that the macro next(ls) in llex.c is now luaX:nextc
  3357. -- * utilized used in lparser.c (various places)
  3358. ------------------------------------------------------------------------
  3359. function luaX:next(ls)
  3360.   ls.lastline = ls.linenumber
  3361.   if ls.lookahead.token ~= "TK_EOS" then  -- is there a look-ahead token?
  3362.     -- this must be copy-by-value
  3363.     ls.t.seminfo = ls.lookahead.seminfo  -- use this one
  3364.     ls.t.token = ls.lookahead.token
  3365.     ls.lookahead.token = "TK_EOS"  -- and discharge it
  3366.   else
  3367.     ls.t.token = self:llex(ls, ls.t)  -- read next token
  3368.   end
  3369. end
  3370.  
  3371. ------------------------------------------------------------------------
  3372. -- fill in the lookahead buffer
  3373. -- * utilized used in lparser.c:constructor
  3374. ------------------------------------------------------------------------
  3375. function luaX:lookahead(ls)
  3376.   -- lua_assert(ls.lookahead.token == "TK_EOS")
  3377.   ls.lookahead.token = self:llex(ls, ls.lookahead)
  3378. end
  3379.  
  3380. ------------------------------------------------------------------------
  3381. -- gets the next character and returns it
  3382. -- * this is the next() macro in llex.c; see notes at the beginning
  3383. ------------------------------------------------------------------------
  3384. function luaX:nextc(ls)
  3385.   local c = luaZ:zgetc(ls.z)
  3386.   ls.current = c
  3387.   return c
  3388. end
  3389.  
  3390. ------------------------------------------------------------------------
  3391. -- saves the given character into the token buffer
  3392. -- * buffer handling code removed, not used in this implementation
  3393. -- * test for maximum token buffer length not used, makes things faster
  3394. ------------------------------------------------------------------------
  3395.  
  3396. function luaX:save(ls, c)
  3397.   local buff = ls.buff
  3398.   -- if you want to use this, please uncomment luaX.MAX_SIZET further up
  3399.   --if #buff > self.MAX_SIZET then
  3400.   --  self:lexerror(ls, "lexical element too long")
  3401.   --end
  3402.   ls.buff = buff..c
  3403. end
  3404.  
  3405. ------------------------------------------------------------------------
  3406. -- save current character into token buffer, grabs next character
  3407. -- * like luaX:nextc, returns the character read for convenience
  3408. ------------------------------------------------------------------------
  3409. function luaX:save_and_next(ls)
  3410.   self:save(ls, ls.current)
  3411.   return self:nextc(ls)
  3412. end
  3413.  
  3414. ------------------------------------------------------------------------
  3415. -- LUA_NUMBER
  3416. -- * luaX:read_numeral is the main lexer function to read a number
  3417. -- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions
  3418. ------------------------------------------------------------------------
  3419.  
  3420. ------------------------------------------------------------------------
  3421. -- string to number converter (was luaO_str2d from lobject.c)
  3422. -- * returns the number, nil if fails (originally returns a boolean)
  3423. -- * conversion function originally lua_str2number(s,p), a macro which
  3424. --   maps to the strtod() function by default (from luaconf.h)
  3425. ------------------------------------------------------------------------
  3426. function luaX:str2d(s)
  3427.   local result = tonumber(s)
  3428.   if result then return result end
  3429.   -- conversion failed
  3430.   if string.lower(string.sub(s, 1, 2)) == "0x" then  -- maybe an hexadecimal constant?
  3431.     result = tonumber(s, 16)
  3432.     if result then return result end  -- most common case
  3433.     -- Was: invalid trailing characters?
  3434.     -- In C, this function then skips over trailing spaces.
  3435.     -- true is returned if nothing else is found except for spaces.
  3436.     -- If there is still something else, then it returns a false.
  3437.     -- All this is not necessary using Lua's tonumber.
  3438.   end
  3439.   return nil
  3440. end
  3441.  
  3442. ------------------------------------------------------------------------
  3443. -- single-character replacement, for locale-aware decimal points
  3444. ------------------------------------------------------------------------
  3445. function luaX:buffreplace(ls, from, to)
  3446.   local result, buff = "", ls.buff
  3447.   for p = 1, #buff do
  3448.     local c = string.sub(buff, p, p)
  3449.     if c == from then c = to end
  3450.     result = result..c
  3451.   end
  3452.   ls.buff = result
  3453. end
  3454.  
  3455. ------------------------------------------------------------------------
  3456. -- Attempt to convert a number by translating '.' decimal points to
  3457. -- the decimal point character used by the current locale. This is not
  3458. -- needed in Yueliang as Lua's tonumber() is already locale-aware.
  3459. -- Instead, the code is here in case the user implements localeconv().
  3460. ------------------------------------------------------------------------
  3461. function luaX:trydecpoint(ls, Token)
  3462.   -- format error: try to update decimal point separator
  3463.   local old = ls.decpoint
  3464.   -- translate the following to Lua if you implement localeconv():
  3465.   -- struct lconv *cv = localeconv();
  3466.   -- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
  3467.   self:buffreplace(ls, old, ls.decpoint)  -- try updated decimal separator
  3468.   local seminfo = self:str2d(ls.buff)
  3469.   Token.seminfo = seminfo
  3470.   if not seminfo then
  3471.     -- format error with correct decimal point: no more options
  3472.     self:buffreplace(ls, ls.decpoint, ".")  -- undo change (for error message)
  3473.     self:lexerror(ls, "malformed number", "TK_NUMBER")
  3474.   end
  3475. end
  3476.  
  3477. ------------------------------------------------------------------------
  3478. -- main number conversion function
  3479. -- * "^%w$" needed in the scan in order to detect "EOZ"
  3480. ------------------------------------------------------------------------
  3481. function luaX:read_numeral(ls, Token)
  3482.   -- lua_assert(string.find(ls.current, "%d"))
  3483.   repeat
  3484.     self:save_and_next(ls)
  3485.   until string.find(ls.current, "%D") and ls.current ~= "."
  3486.   if self:check_next(ls, "Ee") then  -- 'E'?
  3487.     self:check_next(ls, "+-")  -- optional exponent sign
  3488.   end
  3489.   while string.find(ls.current, "^%w$") or ls.current == "_" do
  3490.     self:save_and_next(ls)
  3491.   end
  3492.   self:buffreplace(ls, ".", ls.decpoint)  -- follow locale for decimal point
  3493.   local seminfo = self:str2d(ls.buff)
  3494.   Token.seminfo = seminfo
  3495.   if not seminfo then  -- format error?
  3496.     self:trydecpoint(ls, Token) -- try to update decimal point separator
  3497.   end
  3498. end
  3499.  
  3500. ------------------------------------------------------------------------
  3501. -- count separators ("=") in a long string delimiter
  3502. -- * used by luaX:read_long_string
  3503. ------------------------------------------------------------------------
  3504. function luaX:skip_sep(ls)
  3505.   local count = 0
  3506.   local s = ls.current
  3507.   -- lua_assert(s == "[" or s == "]")
  3508.   self:save_and_next(ls)
  3509.   while ls.current == "=" do
  3510.     self:save_and_next(ls)
  3511.     count = count + 1
  3512.   end
  3513.   return (ls.current == s) and count or (-count) - 1
  3514. end
  3515.  
  3516. ------------------------------------------------------------------------
  3517. -- reads a long string or long comment
  3518. ------------------------------------------------------------------------
  3519. function luaX:read_long_string(ls, Token, sep)
  3520.   local cont = 0
  3521.   self:save_and_next(ls)  -- skip 2nd '['
  3522.   if self:currIsNewline(ls) then  -- string starts with a newline?
  3523.     self:inclinenumber(ls)  -- skip it
  3524.   end
  3525.   while true do
  3526.     local c = ls.current
  3527.     if c == "EOZ" then
  3528.       self:lexerror(ls, Token and "unfinished long string" or
  3529.                     "unfinished long comment", "TK_EOS")
  3530.     elseif c == "[" then
  3531.       --# compatibility code start
  3532.       if self.LUA_COMPAT_LSTR then
  3533.         if self:skip_sep(ls) == sep then
  3534.           self:save_and_next(ls)  -- skip 2nd '['
  3535.           cont = cont + 1
  3536.           --# compatibility code start
  3537.           if self.LUA_COMPAT_LSTR == 1 then
  3538.             if sep == 0 then
  3539.               self:lexerror(ls, "nesting of [[...]] is deprecated", "[")
  3540.             end
  3541.           end
  3542.           --# compatibility code end
  3543.         end
  3544.       end
  3545.       --# compatibility code end
  3546.     elseif c == "]" then
  3547.       if self:skip_sep(ls) == sep then
  3548.         self:save_and_next(ls)  -- skip 2nd ']'
  3549.         --# compatibility code start
  3550.         if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then
  3551.           cont = cont - 1
  3552.           if sep == 0 and cont >= 0 then break end
  3553.         end
  3554.         --# compatibility code end
  3555.         break
  3556.       end
  3557.     elseif self:currIsNewline(ls) then
  3558.       self:save(ls, "\n")
  3559.       self:inclinenumber(ls)
  3560.       if not Token then ls.buff = "" end -- avoid wasting space
  3561.     else  -- default
  3562.       if Token then
  3563.         self:save_and_next(ls)
  3564.       else
  3565.         self:nextc(ls)
  3566.       end
  3567.     end--if c
  3568.   end--while
  3569.   if Token then
  3570.     local p = 3 + sep
  3571.     Token.seminfo = string.sub(ls.buff, p, -p)
  3572.   end
  3573. end
  3574.  
  3575. ------------------------------------------------------------------------
  3576. -- reads a string
  3577. -- * has been restructured significantly compared to the original C code
  3578. ------------------------------------------------------------------------
  3579.  
  3580. function luaX:read_string(ls, del, Token)
  3581.   self:save_and_next(ls)
  3582.   while ls.current ~= del do
  3583.     local c = ls.current
  3584.     if c == "EOZ" then
  3585.       self:lexerror(ls, "unfinished string", "TK_EOS")
  3586.     elseif self:currIsNewline(ls) then
  3587.       self:lexerror(ls, "unfinished string", "TK_STRING")
  3588.     elseif c == "\\" then
  3589.       c = self:nextc(ls)  -- do not save the '\'
  3590.       if self:currIsNewline(ls) then  -- go through
  3591.         self:save(ls, "\n")
  3592.         self:inclinenumber(ls)
  3593.       elseif c ~= "EOZ" then -- will raise an error next loop
  3594.         -- escapes handling greatly simplified here:
  3595.         local i = string.find("abfnrtv", c, 1, 1)
  3596.         if i then
  3597.           self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i))
  3598.           self:nextc(ls)
  3599.         elseif not string.find(c, "%d") then
  3600.           self:save_and_next(ls)  -- handles \\, \", \', and \?
  3601.         else  -- \xxx
  3602.           c, i = 0, 0
  3603.           repeat
  3604.             c = 10 * c + ls.current
  3605.             self:nextc(ls)
  3606.             i = i + 1
  3607.           until i >= 3 or not string.find(ls.current, "%d")
  3608.           if c > 255 then  -- UCHAR_MAX
  3609.             self:lexerror(ls, "escape sequence too large", "TK_STRING")
  3610.           end
  3611.           self:save(ls, string.char(c))
  3612.         end
  3613.       end
  3614.     else
  3615.       self:save_and_next(ls)
  3616.     end--if c
  3617.   end--while
  3618.   self:save_and_next(ls)  -- skip delimiter
  3619.   Token.seminfo = string.sub(ls.buff, 2, -2)
  3620. end
  3621.  
  3622. ------------------------------------------------------------------------
  3623. -- main lexer function
  3624. ------------------------------------------------------------------------
  3625. function luaX:llex(ls, Token)
  3626.   ls.buff = ""
  3627.   while true do
  3628.     local c = ls.current
  3629.     ----------------------------------------------------------------
  3630.     if self:currIsNewline(ls) then
  3631.       self:inclinenumber(ls)
  3632.     ----------------------------------------------------------------
  3633.     elseif c == "-" then
  3634.       c = self:nextc(ls)
  3635.       if c ~= "-" then return "-" end
  3636.       -- else is a comment
  3637.       local sep = -1
  3638.       if self:nextc(ls) == '[' then
  3639.         sep = self:skip_sep(ls)
  3640.         ls.buff = ""  -- 'skip_sep' may dirty the buffer
  3641.       end
  3642.       if sep >= 0 then
  3643.         self:read_long_string(ls, nil, sep)  -- long comment
  3644.         ls.buff = ""
  3645.       else  -- else short comment
  3646.         while not self:currIsNewline(ls) and ls.current ~= "EOZ" do
  3647.           self:nextc(ls)
  3648.         end
  3649.       end
  3650.     ----------------------------------------------------------------
  3651.     elseif c == "[" then
  3652.       local sep = self:skip_sep(ls)
  3653.       if sep >= 0 then
  3654.         self:read_long_string(ls, Token, sep)
  3655.         return "TK_STRING"
  3656.       elseif sep == -1 then
  3657.         return "["
  3658.       else
  3659.         self:lexerror(ls, "invalid long string delimiter", "TK_STRING")
  3660.       end
  3661.     ----------------------------------------------------------------
  3662.     elseif c == "=" then
  3663.       c = self:nextc(ls)
  3664.       if c ~= "=" then return "="
  3665.       else self:nextc(ls); return "TK_EQ" end
  3666.     ----------------------------------------------------------------
  3667.     elseif c == "<" then
  3668.       c = self:nextc(ls)
  3669.       if c ~= "=" then return "<"
  3670.       else self:nextc(ls); return "TK_LE" end
  3671.     ----------------------------------------------------------------
  3672.     elseif c == ">" then
  3673.       c = self:nextc(ls)
  3674.       if c ~= "=" then return ">"
  3675.       else self:nextc(ls); return "TK_GE" end
  3676.     ----------------------------------------------------------------
  3677.     elseif c == "~" then
  3678.       c = self:nextc(ls)
  3679.       if c ~= "=" then return "~"
  3680.       else self:nextc(ls); return "TK_NE" end
  3681.     ----------------------------------------------------------------
  3682.     elseif c == "\"" or c == "'" then
  3683.       self:read_string(ls, c, Token)
  3684.       return "TK_STRING"
  3685.     ----------------------------------------------------------------
  3686.     elseif c == "." then
  3687.       c = self:save_and_next(ls)
  3688.       if self:check_next(ls, ".") then
  3689.         if self:check_next(ls, ".") then
  3690.           return "TK_DOTS"   -- ...
  3691.         else return "TK_CONCAT"   -- ..
  3692.         end
  3693.       elseif not string.find(c, "%d") then
  3694.         return "."
  3695.       else
  3696.         self:read_numeral(ls, Token)
  3697.         return "TK_NUMBER"
  3698.       end
  3699.     ----------------------------------------------------------------
  3700.     elseif c == "EOZ" then
  3701.       return "TK_EOS"
  3702.     ----------------------------------------------------------------
  3703.     else  -- default
  3704.       if string.find(c, "%s") then
  3705.         -- lua_assert(self:currIsNewline(ls))
  3706.         self:nextc(ls)
  3707.       elseif string.find(c, "%d") then
  3708.         self:read_numeral(ls, Token)
  3709.         return "TK_NUMBER"
  3710.       elseif string.find(c, "[_%a]") then
  3711.         -- identifier or reserved word
  3712.         repeat
  3713.           c = self:save_and_next(ls)
  3714.         until c == "EOZ" or not string.find(c, "[_%w]")
  3715.         local ts = ls.buff
  3716.         local tok = self.enums[ts]
  3717.         if tok then return tok end  -- reserved word?
  3718.         Token.seminfo = ts
  3719.         return "TK_NAME"
  3720.       else
  3721.         self:nextc(ls)
  3722.         return c  -- single-char tokens (+ - / ...)
  3723.       end
  3724.     ----------------------------------------------------------------
  3725.     end--if c
  3726.   end--while
  3727. end
  3728.  
  3729. return luaX
  3730. end
  3731.  
  3732. function LuaY()
  3733. local script = script.LuaY
  3734. --[[--------------------------------------------------------------------
  3735.  
  3736.   lparser.lua
  3737.   Lua 5 parser in Lua
  3738.   This file is part of Yueliang.
  3739.  
  3740.   Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
  3741.   The COPYRIGHT file describes the conditions
  3742.   under which this software may be distributed.
  3743.  
  3744.   See the ChangeLog for more information.
  3745.  
  3746. ----------------------------------------------------------------------]]
  3747.  
  3748. --[[--------------------------------------------------------------------
  3749. -- Notes:
  3750. -- * some unused C code that were not converted are kept as comments
  3751. -- * LUA_COMPAT_VARARG option changed into a comment block
  3752. -- * for value/size specific code added, look for 'NOTE: '
  3753. --
  3754. -- Not implemented:
  3755. -- * luaX_newstring not needed by this Lua implementation
  3756. -- * luaG_checkcode() in assert is not currently implemented
  3757. --
  3758. -- Added:
  3759. -- * some constants added from various header files
  3760. -- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h)
  3761. -- * luaY:LUA_QL needed for error messages (from luaconf.h)
  3762. -- * luaY:growvector (from lmem.h) -- skeleton only, limit checking
  3763. -- * luaY.SHRT_MAX (from <limits.h>) for registerlocalvar
  3764. -- * luaY:newproto (from lfunc.c)
  3765. -- * luaY:int2fb (from lobject.c)
  3766. -- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation
  3767. -- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop
  3768. --
  3769. -- Changed in 5.1.x:
  3770. -- * various code changes are not detailed...
  3771. -- * names of constants may have changed, e.g. added a LUAI_ prefix
  3772. -- * struct expkind: added VKNUM, VVARARG; VCALL's info changed?
  3773. -- * struct expdesc: added nval
  3774. -- * struct FuncState: upvalues data type changed to upvaldesc
  3775. -- * macro hasmultret is new
  3776. -- * function checklimit moved to parser from lexer
  3777. -- * functions anchor_token, errorlimit, checknext are new
  3778. -- * checknext is new, equivalent to 5.0.x's check, see check too
  3779. -- * luaY:next and luaY:lookahead moved to lexer
  3780. -- * break keyword no longer skipped in luaY:breakstat
  3781. -- * function new_localvarstr replaced by new_localvarliteral
  3782. -- * registerlocalvar limits local variables to SHRT_MAX
  3783. -- * create_local deleted, new_localvarliteral used instead
  3784. -- * constant LUAI_MAXUPVALUES increased to 60
  3785. -- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed
  3786. -- * function interface changed: singlevaraux, singlevar
  3787. -- * enterlevel and leavelevel uses nCcalls to track call depth
  3788. -- * added a name argument to main entry function, luaY:parser
  3789. -- * function luaY_index changed to yindex
  3790. -- * luaY:int2fb()'s table size encoding format has been changed
  3791. -- * luaY:log2() no longer needed for table constructors
  3792. -- * function code_params deleted, functionality folded in parlist
  3793. -- * vararg flags handling (is_vararg) changes; also see VARARG_*
  3794. -- * LUA_COMPATUPSYNTAX section for old-style upvalues removed
  3795. -- * repeatstat() calls chunk() instead of block()
  3796. -- * function interface changed: cond, test_then_block
  3797. -- * while statement implementation considerably simplified; MAXEXPWHILE
  3798. --   and EXTRAEXP no longer required, no limits to the complexity of a
  3799. --   while condition
  3800. -- * repeat, forbody statement implementation has major changes,
  3801. --   mostly due to new scoping behaviour of local variables
  3802. -- * OPR_MULT renamed to OPR_MUL
  3803. ----------------------------------------------------------------------]]
  3804.  
  3805. --requires luaP, luaX, luaK
  3806. local luaY = {}
  3807. local luaX = require(script.Parent.LuaX)
  3808. local luaK = require(script.Parent.LuaK)(luaY)
  3809. local luaP = require(script.Parent.LuaP)
  3810.  
  3811. --[[--------------------------------------------------------------------
  3812. -- Expression descriptor
  3813. -- * expkind changed to string constants; luaY:assignment was the only
  3814. --   function to use a relational operator with this enumeration
  3815. -- VVOID       -- no value
  3816. -- VNIL        -- no value
  3817. -- VTRUE       -- no value
  3818. -- VFALSE      -- no value
  3819. -- VK          -- info = index of constant in 'k'
  3820. -- VKNUM       -- nval = numerical value
  3821. -- VLOCAL      -- info = local register
  3822. -- VUPVAL,     -- info = index of upvalue in 'upvalues'
  3823. -- VGLOBAL     -- info = index of table; aux = index of global name in 'k'
  3824. -- VINDEXED    -- info = table register; aux = index register (or 'k')
  3825. -- VJMP        -- info = instruction pc
  3826. -- VRELOCABLE  -- info = instruction pc
  3827. -- VNONRELOC   -- info = result register
  3828. -- VCALL       -- info = instruction pc
  3829. -- VVARARG     -- info = instruction pc
  3830. } ----------------------------------------------------------------------]]
  3831.  
  3832. --[[--------------------------------------------------------------------
  3833. -- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
  3834. --   implementation ignores all instances of u and s usage
  3835. -- struct expdesc:
  3836. --   k  -- (enum: expkind)
  3837. --   info, aux -- (int, int)
  3838. --   nval -- (lua_Number)
  3839. --   t  -- patch list of 'exit when true'
  3840. --   f  -- patch list of 'exit when false'
  3841. ----------------------------------------------------------------------]]
  3842.  
  3843. --[[--------------------------------------------------------------------
  3844. -- struct upvaldesc:
  3845. --   k  -- (lu_byte)
  3846. --   info -- (lu_byte)
  3847. ----------------------------------------------------------------------]]
  3848.  
  3849. --[[--------------------------------------------------------------------
  3850. -- state needed to generate code for a given function
  3851. -- struct FuncState:
  3852. --   f  -- current function header (table: Proto)
  3853. --   h  -- table to find (and reuse) elements in 'k' (table: Table)
  3854. --   prev  -- enclosing function (table: FuncState)
  3855. --   ls  -- lexical state (table: LexState)
  3856. --   L  -- copy of the Lua state (table: lua_State)
  3857. --   bl  -- chain of current blocks (table: BlockCnt)
  3858. --   pc  -- next position to code (equivalent to 'ncode')
  3859. --   lasttarget   -- 'pc' of last 'jump target'
  3860. --   jpc  -- list of pending jumps to 'pc'
  3861. --   freereg  -- first free register
  3862. --   nk  -- number of elements in 'k'
  3863. --   np  -- number of elements in 'p'
  3864. --   nlocvars  -- number of elements in 'locvars'
  3865. --   nactvar  -- number of active local variables
  3866. --   upvalues[LUAI_MAXUPVALUES]  -- upvalues (table: upvaldesc)
  3867. --   actvar[LUAI_MAXVARS]  -- declared-variable stack
  3868. ----------------------------------------------------------------------]]
  3869.  
  3870. ------------------------------------------------------------------------
  3871. -- constants used by parser
  3872. -- * picks up duplicate values from luaX if required
  3873. ------------------------------------------------------------------------
  3874.  
  3875. luaY.LUA_QS = luaX.LUA_QS or "'%s'"  -- (from luaconf.h)
  3876.  
  3877. luaY.SHRT_MAX = 32767 -- (from <limits.h>)
  3878. luaY.LUAI_MAXVARS = 200  -- (luaconf.h)
  3879. luaY.LUAI_MAXUPVALUES = 60  -- (luaconf.h)
  3880. luaY.MAX_INT = luaX.MAX_INT or 2147483645  -- (from llimits.h)
  3881.   -- * INT_MAX-2 for 32-bit systems
  3882. luaY.LUAI_MAXCCALLS = 200  -- (from luaconf.h)
  3883.  
  3884. luaY.VARARG_HASARG = 1  -- (from lobject.h)
  3885. -- NOTE: HASARG_MASK is value-specific
  3886. luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
  3887. luaY.VARARG_ISVARARG = 2
  3888. -- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
  3889. luaY.VARARG_NEEDSARG = 4
  3890.  
  3891. luaY.LUA_MULTRET = -1  -- (lua.h)
  3892.  
  3893. --[[--------------------------------------------------------------------
  3894. -- other functions
  3895. ----------------------------------------------------------------------]]
  3896.  
  3897. ------------------------------------------------------------------------
  3898. -- LUA_QL describes how error messages quote program elements.
  3899. -- CHANGE it if you want a different appearance. (from luaconf.h)
  3900. ------------------------------------------------------------------------
  3901. function luaY:LUA_QL(x)
  3902.   return "'"..x.."'"
  3903. end
  3904.  
  3905. ------------------------------------------------------------------------
  3906. -- this is a stripped-down luaM_growvector (from lmem.h) which is a
  3907. -- macro based on luaM_growaux (in lmem.c); all the following does is
  3908. -- reproduce the size limit checking logic of the original function
  3909. -- so that error behaviour is identical; all arguments preserved for
  3910. -- convenience, even those which are unused
  3911. -- * set the t field to nil, since this originally does a sizeof(t)
  3912. -- * size (originally a pointer) is never updated, their final values
  3913. --   are set by luaY:close_func(), so overall things should still work
  3914. ------------------------------------------------------------------------
  3915. function luaY:growvector(L, v, nelems, size, t, limit, e)
  3916.   if nelems >= limit then
  3917.     error(e)  -- was luaG_runerror
  3918.   end
  3919. end
  3920.  
  3921. ------------------------------------------------------------------------
  3922. -- initialize a new function prototype structure (from lfunc.c)
  3923. -- * used only in open_func()
  3924. ------------------------------------------------------------------------
  3925. function luaY:newproto(L)
  3926.   local f = {} -- Proto
  3927.   -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
  3928.   f.k = {}
  3929.   f.sizek = 0
  3930.   f.p = {}
  3931.   f.sizep = 0
  3932.   f.code = {}
  3933.   f.sizecode = 0
  3934.   f.sizelineinfo = 0
  3935.   f.sizeupvalues = 0
  3936.   f.nups = 0
  3937.   f.upvalues = {}
  3938.   f.numparams = 0
  3939.   f.is_vararg = 0
  3940.   f.maxstacksize = 0
  3941.   f.lineinfo = {}
  3942.   f.sizelocvars = 0
  3943.   f.locvars = {}
  3944.   f.lineDefined = 0
  3945.   f.lastlinedefined = 0
  3946.   f.source = nil
  3947.   return f
  3948. end
  3949.  
  3950. ------------------------------------------------------------------------
  3951. -- converts an integer to a "floating point byte", represented as
  3952. -- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
  3953. -- eeeee != 0 and (xxx) otherwise.
  3954. ------------------------------------------------------------------------
  3955. function luaY:int2fb(x)
  3956.   local e = 0  -- exponent
  3957.   while x >= 16 do
  3958.     x = math.floor((x + 1) / 2)
  3959.     e = e + 1
  3960.   end
  3961.   if x < 8 then
  3962.     return x
  3963.   else
  3964.     return ((e + 1) * 8) + (x - 8)
  3965.   end
  3966. end
  3967.  
  3968. --[[--------------------------------------------------------------------
  3969. -- parser functions
  3970. ----------------------------------------------------------------------]]
  3971.  
  3972. ------------------------------------------------------------------------
  3973. -- true of the kind of expression produces multiple return values
  3974. ------------------------------------------------------------------------
  3975. function luaY:hasmultret(k)
  3976.   return k == "VCALL" or k == "VVARARG"
  3977. end
  3978.  
  3979. ------------------------------------------------------------------------
  3980. -- convenience function to access active local i, returns entry
  3981. ------------------------------------------------------------------------
  3982. function luaY:getlocvar(fs, i)
  3983.   return fs.f.locvars[ fs.actvar[i] ]
  3984. end
  3985.  
  3986. ------------------------------------------------------------------------
  3987. -- check a limit, string m provided as an error message
  3988. ------------------------------------------------------------------------
  3989. function luaY:checklimit(fs, v, l, m)
  3990.   if v > l then self:errorlimit(fs, l, m) end
  3991. end
  3992.  
  3993. --[[--------------------------------------------------------------------
  3994. -- nodes for block list (list of active blocks)
  3995. -- struct BlockCnt:
  3996. --   previous  -- chain (table: BlockCnt)
  3997. --   breaklist  -- list of jumps out of this loop
  3998. --   nactvar  -- # active local variables outside the breakable structure
  3999. --   upval  -- true if some variable in the block is an upvalue (boolean)
  4000. --   isbreakable  -- true if 'block' is a loop (boolean)
  4001. ----------------------------------------------------------------------]]
  4002.  
  4003. ------------------------------------------------------------------------
  4004. -- prototypes for recursive non-terminal functions
  4005. ------------------------------------------------------------------------
  4006. -- prototypes deleted; not required in Lua
  4007.  
  4008. ------------------------------------------------------------------------
  4009. -- reanchor if last token is has a constant string, see close_func()
  4010. -- * used only in close_func()
  4011. ------------------------------------------------------------------------
  4012. function luaY:anchor_token(ls)
  4013.   if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
  4014.     -- not relevant to Lua implementation of parser
  4015.     -- local ts = ls.t.seminfo
  4016.     -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
  4017.   end
  4018. end
  4019.  
  4020. ------------------------------------------------------------------------
  4021. -- throws a syntax error if token expected is not there
  4022. ------------------------------------------------------------------------
  4023. function luaY:error_expected(ls, token)
  4024.   luaX:syntaxerror(ls,
  4025.     string.format(self.LUA_QS.." expected", luaX:token2str(ls, token)))
  4026. end
  4027.  
  4028. ------------------------------------------------------------------------
  4029. -- prepares error message for display, for limits exceeded
  4030. -- * used only in checklimit()
  4031. ------------------------------------------------------------------------
  4032. function luaY:errorlimit(fs, limit, what)
  4033.   local msg = (fs.f.linedefined == 0) and
  4034.     string.format("main function has more than %d %s", limit, what) or
  4035.     string.format("function at line %d has more than %d %s",
  4036.                   fs.f.linedefined, limit, what)
  4037.   luaX:lexerror(fs.ls, msg, 0)
  4038. end
  4039.  
  4040. ------------------------------------------------------------------------
  4041. -- tests for a token, returns outcome
  4042. -- * return value changed to boolean
  4043. ------------------------------------------------------------------------
  4044. function luaY:testnext(ls, c)
  4045.   if ls.t.token == c then
  4046.     luaX:next(ls)
  4047.     return true
  4048.   else
  4049.     return false
  4050.   end
  4051. end
  4052.  
  4053. ------------------------------------------------------------------------
  4054. -- check for existence of a token, throws error if not found
  4055. ------------------------------------------------------------------------
  4056. function luaY:check(ls, c)
  4057.   if ls.t.token ~= c then
  4058.     self:error_expected(ls, c)
  4059.   end
  4060. end
  4061.  
  4062. ------------------------------------------------------------------------
  4063. -- verify existence of a token, then skip it
  4064. ------------------------------------------------------------------------
  4065. function luaY:checknext(ls, c)
  4066.   self:check(ls, c)
  4067.   luaX:next(ls)
  4068. end
  4069.  
  4070. ------------------------------------------------------------------------
  4071. -- throws error if condition not matched
  4072. ------------------------------------------------------------------------
  4073. function luaY:check_condition(ls, c, msg)
  4074.   if not c then luaX:syntaxerror(ls, msg) end
  4075. end
  4076.  
  4077. ------------------------------------------------------------------------
  4078. -- verifies token conditions are met or else throw error
  4079. ------------------------------------------------------------------------
  4080. function luaY:check_match(ls, what, who, where)
  4081.   if not self:testnext(ls, what) then
  4082.     if where == ls.linenumber then
  4083.       self:error_expected(ls, what)
  4084.     else
  4085.       luaX:syntaxerror(ls, string.format(
  4086.         self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)",
  4087.         luaX:token2str(ls, what), luaX:token2str(ls, who), where))
  4088.     end
  4089.   end
  4090. end
  4091.  
  4092. ------------------------------------------------------------------------
  4093. -- expect that token is a name, return the name
  4094. ------------------------------------------------------------------------
  4095. function luaY:str_checkname(ls)
  4096.   self:check(ls, "TK_NAME")
  4097.   local ts = ls.t.seminfo
  4098.   luaX:next(ls)
  4099.   return ts
  4100. end
  4101.  
  4102. ------------------------------------------------------------------------
  4103. -- initialize a struct expdesc, expression description data structure
  4104. ------------------------------------------------------------------------
  4105. function luaY:init_exp(e, k, i)
  4106.   e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
  4107.   e.k = k
  4108.   e.info = i
  4109. end
  4110.  
  4111. ------------------------------------------------------------------------
  4112. -- adds given string s in string pool, sets e as VK
  4113. ------------------------------------------------------------------------
  4114. function luaY:codestring(ls, e, s)
  4115.   self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
  4116. end
  4117.  
  4118. ------------------------------------------------------------------------
  4119. -- consume a name token, adds it to string pool, sets e as VK
  4120. ------------------------------------------------------------------------
  4121. function luaY:checkname(ls, e)
  4122.   self:codestring(ls, e, self:str_checkname(ls))
  4123. end
  4124.  
  4125. ------------------------------------------------------------------------
  4126. -- creates struct entry for a local variable
  4127. -- * used only in new_localvar()
  4128. ------------------------------------------------------------------------
  4129. function luaY:registerlocalvar(ls, varname)
  4130.   local fs = ls.fs
  4131.   local f = fs.f
  4132.   self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
  4133.                   nil, self.SHRT_MAX, "too many local variables")
  4134.   -- loop to initialize empty f.locvar positions not required
  4135.   f.locvars[fs.nlocvars] = {} -- LocVar
  4136.   f.locvars[fs.nlocvars].varname = varname
  4137.   -- luaC_objbarrier(ls.L, f, varname) /* GC */
  4138.   local nlocvars = fs.nlocvars
  4139.   fs.nlocvars = fs.nlocvars + 1
  4140.   return nlocvars
  4141. end
  4142.  
  4143. ------------------------------------------------------------------------
  4144. -- creates a new local variable given a name and an offset from nactvar
  4145. -- * used in fornum(), forlist(), parlist(), body()
  4146. ------------------------------------------------------------------------
  4147. function luaY:new_localvarliteral(ls, v, n)
  4148.   self:new_localvar(ls, v, n)
  4149. end
  4150.  
  4151. ------------------------------------------------------------------------
  4152. -- register a local variable, set in active variable list
  4153. ------------------------------------------------------------------------
  4154. function luaY:new_localvar(ls, name, n)
  4155.   local fs = ls.fs
  4156.   self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
  4157.   fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
  4158. end
  4159.  
  4160. ------------------------------------------------------------------------
  4161. -- adds nvars number of new local variables, set debug information
  4162. ------------------------------------------------------------------------
  4163. function luaY:adjustlocalvars(ls, nvars)
  4164.   local fs = ls.fs
  4165.   fs.nactvar = fs.nactvar + nvars
  4166.   for i = nvars, 1, -1 do
  4167.     self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
  4168.   end
  4169. end
  4170.  
  4171. ------------------------------------------------------------------------
  4172. -- removes a number of locals, set debug information
  4173. ------------------------------------------------------------------------
  4174. function luaY:removevars(ls, tolevel)
  4175.   local fs = ls.fs
  4176.   while fs.nactvar > tolevel do
  4177.     fs.nactvar = fs.nactvar - 1
  4178.     self:getlocvar(fs, fs.nactvar).endpc = fs.pc
  4179.   end
  4180. end
  4181.  
  4182. ------------------------------------------------------------------------
  4183. -- returns an existing upvalue index based on the given name, or
  4184. -- creates a new upvalue struct entry and returns the new index
  4185. -- * used only in singlevaraux()
  4186. ------------------------------------------------------------------------
  4187. function luaY:indexupvalue(fs, name, v)
  4188.   local f = fs.f
  4189.   for i = 0, f.nups - 1 do
  4190.     if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
  4191.       assert(f.upvalues[i] == name)
  4192.       return i
  4193.     end
  4194.   end
  4195.   -- new one
  4196.   self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
  4197.   self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues,
  4198.                   nil, self.MAX_INT, "")
  4199.   -- loop to initialize empty f.upvalues positions not required
  4200.   f.upvalues[f.nups] = name
  4201.   -- luaC_objbarrier(fs->L, f, name); /* GC */
  4202.   assert(v.k == "VLOCAL" or v.k == "VUPVAL")
  4203.   -- this is a partial copy; only k & info fields used
  4204.   fs.upvalues[f.nups] = { k = v.k, info = v.info }
  4205.   local nups = f.nups
  4206.   f.nups = f.nups + 1
  4207.   return nups
  4208. end
  4209.  
  4210. ------------------------------------------------------------------------
  4211. -- search the local variable namespace of the given fs for a match
  4212. -- * used only in singlevaraux()
  4213. ------------------------------------------------------------------------
  4214. function luaY:searchvar(fs, n)
  4215.   for i = fs.nactvar - 1, 0, -1 do
  4216.     if n == self:getlocvar(fs, i).varname then
  4217.       return i
  4218.     end
  4219.   end
  4220.   return -1  -- not found
  4221. end
  4222.  
  4223. ------------------------------------------------------------------------
  4224. -- * mark upvalue flags in function states up to a given level
  4225. -- * used only in singlevaraux()
  4226. ------------------------------------------------------------------------
  4227. function luaY:markupval(fs, level)
  4228.   local bl = fs.bl
  4229.   while bl and bl.nactvar > level do bl = bl.previous end
  4230.   if bl then bl.upval = true end
  4231. end
  4232.  
  4233. ------------------------------------------------------------------------
  4234. -- handle locals, globals and upvalues and related processing
  4235. -- * search mechanism is recursive, calls itself to search parents
  4236. -- * used only in singlevar()
  4237. ------------------------------------------------------------------------
  4238. function luaY:singlevaraux(fs, n, var, base)
  4239.   if fs == nil then  -- no more levels?
  4240.     self:init_exp(var, "VGLOBAL", luaP.NO_REG)  -- default is global variable
  4241.     return "VGLOBAL"
  4242.   else
  4243.     local v = self:searchvar(fs, n)  -- look up at current level
  4244.     if v >= 0 then
  4245.       self:init_exp(var, "VLOCAL", v)
  4246.       if base == 0 then
  4247.         self:markupval(fs, v)  -- local will be used as an upval
  4248.       end
  4249.       return "VLOCAL"
  4250.     else  -- not found at current level; try upper one
  4251.       if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
  4252.         return "VGLOBAL"
  4253.       end
  4254.       var.info = self:indexupvalue(fs, n, var)  -- else was LOCAL or UPVAL
  4255.       var.k = "VUPVAL"  -- upvalue in this level
  4256.       return "VUPVAL"
  4257.     end--if v
  4258.   end--if fs
  4259. end
  4260.  
  4261. ------------------------------------------------------------------------
  4262. -- consume a name token, creates a variable (global|local|upvalue)
  4263. -- * used in prefixexp(), funcname()
  4264. ------------------------------------------------------------------------
  4265. function luaY:singlevar(ls, var)
  4266.   local varname = self:str_checkname(ls)
  4267.   local fs = ls.fs
  4268.   if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
  4269.     var.info = luaK:stringK(fs, varname)  -- info points to global name
  4270.   end
  4271. end
  4272.  
  4273. ------------------------------------------------------------------------
  4274. -- adjust RHS to match LHS in an assignment
  4275. -- * used in assignment(), forlist(), localstat()
  4276. ------------------------------------------------------------------------
  4277. function luaY:adjust_assign(ls, nvars, nexps, e)
  4278.   local fs = ls.fs
  4279.   local extra = nvars - nexps
  4280.   if self:hasmultret(e.k) then
  4281.     extra = extra + 1  -- includes call itself
  4282.     if extra <= 0 then extra = 0 end
  4283.     luaK:setreturns(fs, e, extra)  -- last exp. provides the difference
  4284.     if extra > 1 then luaK:reserveregs(fs, extra - 1) end
  4285.   else
  4286.     if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end  -- close last expression
  4287.     if extra > 0 then
  4288.       local reg = fs.freereg
  4289.       luaK:reserveregs(fs, extra)
  4290.       luaK:_nil(fs, reg, extra)
  4291.     end
  4292.   end
  4293. end
  4294.  
  4295. ------------------------------------------------------------------------
  4296. -- tracks and limits parsing depth, assert check at end of parsing
  4297. ------------------------------------------------------------------------
  4298. function luaY:enterlevel(ls)
  4299.   ls.L.nCcalls = ls.L.nCcalls + 1
  4300.   if ls.L.nCcalls > self.LUAI_MAXCCALLS then
  4301.     luaX:lexerror(ls, "chunk has too many syntax levels", 0)
  4302.   end
  4303. end
  4304.  
  4305. ------------------------------------------------------------------------
  4306. -- tracks parsing depth, a pair with luaY:enterlevel()
  4307. ------------------------------------------------------------------------
  4308. function luaY:leavelevel(ls)
  4309.   ls.L.nCcalls = ls.L.nCcalls - 1
  4310. end
  4311.  
  4312. ------------------------------------------------------------------------
  4313. -- enters a code unit, initializes elements
  4314. ------------------------------------------------------------------------
  4315. function luaY:enterblock(fs, bl, isbreakable)
  4316.   bl.breaklist = luaK.NO_JUMP
  4317.   bl.isbreakable = isbreakable
  4318.   bl.nactvar = fs.nactvar
  4319.   bl.upval = false
  4320.   bl.previous = fs.bl
  4321.   fs.bl = bl
  4322.   assert(fs.freereg == fs.nactvar)
  4323. end
  4324.  
  4325. ------------------------------------------------------------------------
  4326. -- leaves a code unit, close any upvalues
  4327. ------------------------------------------------------------------------
  4328. function luaY:leaveblock(fs)
  4329.   local bl = fs.bl
  4330.   fs.bl = bl.previous
  4331.   self:removevars(fs.ls, bl.nactvar)
  4332.   if bl.upval then
  4333.     luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  4334.   end
  4335.   -- a block either controls scope or breaks (never both)
  4336.   assert(not bl.isbreakable or not bl.upval)
  4337.   assert(bl.nactvar == fs.nactvar)
  4338.   fs.freereg = fs.nactvar  -- free registers
  4339.   luaK:patchtohere(fs, bl.breaklist)
  4340. end
  4341.  
  4342. ------------------------------------------------------------------------
  4343. -- implement the instantiation of a function prototype, append list of
  4344. -- upvalues after the instantiation instruction
  4345. -- * used only in body()
  4346. ------------------------------------------------------------------------
  4347. function luaY:pushclosure(ls, func, v)
  4348.   local fs = ls.fs
  4349.   local f = fs.f
  4350.   self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
  4351.                   luaP.MAXARG_Bx, "constant table overflow")
  4352.   -- loop to initialize empty f.p positions not required
  4353.   f.p[fs.np] = func.f
  4354.   fs.np = fs.np + 1
  4355.   -- luaC_objbarrier(ls->L, f, func->f); /* C */
  4356.   self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
  4357.   for i = 0, func.f.nups - 1 do
  4358.     local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
  4359.     luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
  4360.   end
  4361. end
  4362.  
  4363. ------------------------------------------------------------------------
  4364. -- opening of a function
  4365. ------------------------------------------------------------------------
  4366. function luaY:open_func(ls, fs)
  4367.   local L = ls.L
  4368.   local f = self:newproto(ls.L)
  4369.   fs.f = f
  4370.   fs.prev = ls.fs  -- linked list of funcstates
  4371.   fs.ls = ls
  4372.   fs.L = L
  4373.   ls.fs = fs
  4374.   fs.pc = 0
  4375.   fs.lasttarget = -1
  4376.   fs.jpc = luaK.NO_JUMP
  4377.   fs.freereg = 0
  4378.   fs.nk = 0
  4379.   fs.np = 0
  4380.   fs.nlocvars = 0
  4381.   fs.nactvar = 0
  4382.   fs.bl = nil
  4383.   f.source = ls.source
  4384.   f.maxstacksize = 2  -- registers 0/1 are always valid
  4385.   fs.h = {}  -- constant table; was luaH_new call
  4386.   -- anchor table of constants and prototype (to avoid being collected)
  4387.   -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
  4388.   -- setptvalue2s(L, L->top, f); incr_top(L);
  4389. end
  4390.  
  4391. ------------------------------------------------------------------------
  4392. -- closing of a function
  4393. ------------------------------------------------------------------------
  4394. function luaY:close_func(ls)
  4395.   local L = ls.L
  4396.   local fs = ls.fs
  4397.   local f = fs.f
  4398.   self:removevars(ls, 0)
  4399.   luaK:ret(fs, 0, 0)  -- final return
  4400.   -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
  4401.   -- f->locvars, f->upvalues; not required for Lua table arrays
  4402.   f.sizecode = fs.pc
  4403.   f.sizelineinfo = fs.pc
  4404.   f.sizek = fs.nk
  4405.   f.sizep = fs.np
  4406.   f.sizelocvars = fs.nlocvars
  4407.   f.sizeupvalues = f.nups
  4408.   --assert(luaG_checkcode(f))  -- currently not implemented
  4409.   assert(fs.bl == nil)
  4410.   ls.fs = fs.prev
  4411.   -- the following is not required for this implementation; kept here
  4412.   -- for completeness
  4413.   -- L->top -= 2;  /* remove table and prototype from the stack */
  4414.   -- last token read was anchored in defunct function; must reanchor it
  4415.   if fs then self:anchor_token(ls) end
  4416. end
  4417.  
  4418. ------------------------------------------------------------------------
  4419. -- parser initialization function
  4420. -- * note additional sub-tables needed for LexState, FuncState
  4421. ------------------------------------------------------------------------
  4422. function luaY:parser(L, z, buff, name)
  4423.   local lexstate = {}  -- LexState
  4424.         lexstate.t = {}
  4425.         lexstate.lookahead = {}
  4426.   local funcstate = {}  -- FuncState
  4427.         funcstate.upvalues = {}
  4428.         funcstate.actvar = {}
  4429.   -- the following nCcalls initialization added for convenience
  4430.   L.nCcalls = 0
  4431.   lexstate.buff = buff
  4432.   luaX:setinput(L, lexstate, z, name)
  4433.   self:open_func(lexstate, funcstate)
  4434.   funcstate.f.is_vararg = self.VARARG_ISVARARG  -- main func. is always vararg
  4435.   luaX:next(lexstate)  -- read first token
  4436.   self:chunk(lexstate)
  4437.   self:check(lexstate, "TK_EOS")
  4438.   self:close_func(lexstate)
  4439.   assert(funcstate.prev == nil)
  4440.   assert(funcstate.f.nups == 0)
  4441.   assert(lexstate.fs == nil)
  4442.   return funcstate.f
  4443. end
  4444.  
  4445. --[[--------------------------------------------------------------------
  4446. -- GRAMMAR RULES
  4447. ----------------------------------------------------------------------]]
  4448.  
  4449. ------------------------------------------------------------------------
  4450. -- parse a function name suffix, for function call specifications
  4451. -- * used in primaryexp(), funcname()
  4452. ------------------------------------------------------------------------
  4453. function luaY:field(ls, v)
  4454.   -- field -> ['.' | ':'] NAME
  4455.   local fs = ls.fs
  4456.   local key = {}  -- expdesc
  4457.   luaK:exp2anyreg(fs, v)
  4458.   luaX:next(ls)  -- skip the dot or colon
  4459.   self:checkname(ls, key)
  4460.   luaK:indexed(fs, v, key)
  4461. end
  4462.  
  4463. ------------------------------------------------------------------------
  4464. -- parse a table indexing suffix, for constructors, expressions
  4465. -- * used in recfield(), primaryexp()
  4466. ------------------------------------------------------------------------
  4467. function luaY:yindex(ls, v)
  4468.   -- index -> '[' expr ']'
  4469.   luaX:next(ls)  -- skip the '['
  4470.   self:expr(ls, v)
  4471.   luaK:exp2val(ls.fs, v)
  4472.   self:checknext(ls, "]")
  4473. end
  4474.  
  4475. --[[--------------------------------------------------------------------
  4476. -- Rules for Constructors
  4477. ----------------------------------------------------------------------]]
  4478.  
  4479. --[[--------------------------------------------------------------------
  4480. -- struct ConsControl:
  4481. --   v  -- last list item read (table: struct expdesc)
  4482. --   t  -- table descriptor (table: struct expdesc)
  4483. --   nh  -- total number of 'record' elements
  4484. --   na  -- total number of array elements
  4485. --   tostore  -- number of array elements pending to be stored
  4486. ----------------------------------------------------------------------]]
  4487.  
  4488. ------------------------------------------------------------------------
  4489. -- parse a table record (hash) field
  4490. -- * used in constructor()
  4491. ------------------------------------------------------------------------
  4492. function luaY:recfield(ls, cc)
  4493.   -- recfield -> (NAME | '['exp1']') = exp1
  4494.   local fs = ls.fs
  4495.   local reg = ls.fs.freereg
  4496.   local key, val = {}, {}  -- expdesc
  4497.   if ls.t.token == "TK_NAME" then
  4498.     self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
  4499.     self:checkname(ls, key)
  4500.   else  -- ls->t.token == '['
  4501.     self:yindex(ls, key)
  4502.   end
  4503.   cc.nh = cc.nh + 1
  4504.   self:checknext(ls, "=")
  4505.   local rkkey = luaK:exp2RK(fs, key)
  4506.   self:expr(ls, val)
  4507.   luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
  4508.   fs.freereg = reg  -- free registers
  4509. end
  4510.  
  4511. ------------------------------------------------------------------------
  4512. -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
  4513. -- * used in constructor()
  4514. ------------------------------------------------------------------------
  4515. function luaY:closelistfield(fs, cc)
  4516.   if cc.v.k == "VVOID" then return end  -- there is no list item
  4517.   luaK:exp2nextreg(fs, cc.v)
  4518.   cc.v.k = "VVOID"
  4519.   if cc.tostore == luaP.LFIELDS_PER_FLUSH then
  4520.     luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)  -- flush
  4521.     cc.tostore = 0  -- no more items pending
  4522.   end
  4523. end
  4524.  
  4525. ------------------------------------------------------------------------
  4526. -- emit a set list instruction at the end of parsing list constructor
  4527. -- * used in constructor()
  4528. ------------------------------------------------------------------------
  4529. function luaY:lastlistfield(fs, cc)
  4530.   if cc.tostore == 0 then return end
  4531.   if self:hasmultret(cc.v.k) then
  4532.     luaK:setmultret(fs, cc.v)
  4533.     luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
  4534.     cc.na = cc.na - 1  -- do not count last expression (unknown number of elements)
  4535.   else
  4536.     if cc.v.k ~= "VVOID" then
  4537.       luaK:exp2nextreg(fs, cc.v)
  4538.     end
  4539.     luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
  4540.   end
  4541. end
  4542.  
  4543. ------------------------------------------------------------------------
  4544. -- parse a table list (array) field
  4545. -- * used in constructor()
  4546. ------------------------------------------------------------------------
  4547. function luaY:listfield(ls, cc)
  4548.   self:expr(ls, cc.v)
  4549.   self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
  4550.   cc.na = cc.na + 1
  4551.   cc.tostore = cc.tostore + 1
  4552. end
  4553.  
  4554. ------------------------------------------------------------------------
  4555. -- parse a table constructor
  4556. -- * used in funcargs(), simpleexp()
  4557. ------------------------------------------------------------------------
  4558. function luaY:constructor(ls, t)
  4559.   -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
  4560.   -- field -> recfield | listfield
  4561.   -- fieldsep -> ',' | ';'
  4562.   local fs = ls.fs
  4563.   local line = ls.linenumber
  4564.   local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
  4565.   local cc = {}  -- ConsControl
  4566.         cc.v = {}
  4567.   cc.na, cc.nh, cc.tostore = 0, 0, 0
  4568.   cc.t = t
  4569.   self:init_exp(t, "VRELOCABLE", pc)
  4570.   self:init_exp(cc.v, "VVOID", 0)  -- no value (yet)
  4571.   luaK:exp2nextreg(ls.fs, t)  -- fix it at stack top (for gc)
  4572.   self:checknext(ls, "{")
  4573.   repeat
  4574.     assert(cc.v.k == "VVOID" or cc.tostore > 0)
  4575.     if ls.t.token == "}" then break end
  4576.     self:closelistfield(fs, cc)
  4577.     local c = ls.t.token
  4578.  
  4579.     if c == "TK_NAME" then  -- may be listfields or recfields
  4580.       luaX:lookahead(ls)
  4581.       if ls.lookahead.token ~= "=" then  -- expression?
  4582.         self:listfield(ls, cc)
  4583.       else
  4584.         self:recfield(ls, cc)
  4585.       end
  4586.     elseif c == "[" then  -- constructor_item -> recfield
  4587.       self:recfield(ls, cc)
  4588.     else  -- constructor_part -> listfield
  4589.       self:listfield(ls, cc)
  4590.     end
  4591.   until not self:testnext(ls, ",") and not self:testnext(ls, ";")
  4592.   self:check_match(ls, "}", "{", line)
  4593.   self:lastlistfield(fs, cc)
  4594.   luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
  4595.   luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
  4596. end
  4597.  
  4598. -- }======================================================================
  4599.  
  4600. ------------------------------------------------------------------------
  4601. -- parse the arguments (parameters) of a function declaration
  4602. -- * used in body()
  4603. ------------------------------------------------------------------------
  4604. function luaY:parlist(ls)
  4605.   -- parlist -> [ param { ',' param } ]
  4606.   local fs = ls.fs
  4607.   local f = fs.f
  4608.   local nparams = 0
  4609.   f.is_vararg = 0
  4610.   if ls.t.token ~= ")" then  -- is 'parlist' not empty?
  4611.     repeat
  4612.       local c = ls.t.token
  4613.       if c == "TK_NAME" then  -- param -> NAME
  4614.         self:new_localvar(ls, self:str_checkname(ls), nparams)
  4615.         nparams = nparams + 1
  4616.       elseif c == "TK_DOTS" then  -- param -> `...'
  4617.         luaX:next(ls)
  4618. -- [[
  4619. -- #if defined(LUA_COMPAT_VARARG)
  4620.         -- use `arg' as default name
  4621.         self:new_localvarliteral(ls, "arg", nparams)
  4622.         nparams = nparams + 1
  4623.         f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
  4624. -- #endif
  4625. --]]
  4626.         f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
  4627.       else
  4628.         luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected")
  4629.       end
  4630.     until f.is_vararg ~= 0 or not self:testnext(ls, ",")
  4631.   end--if
  4632.   self:adjustlocalvars(ls, nparams)
  4633.   -- NOTE: the following works only when HASARG_MASK is 2!
  4634.   f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
  4635.   luaK:reserveregs(fs, fs.nactvar)  -- reserve register for parameters
  4636. end
  4637.  
  4638. ------------------------------------------------------------------------
  4639. -- parse function declaration body
  4640. -- * used in simpleexp(), localfunc(), funcstat()
  4641. ------------------------------------------------------------------------
  4642. function luaY:body(ls, e, needself, line)
  4643.   -- body ->  '(' parlist ')' chunk END
  4644.   local new_fs = {}  -- FuncState
  4645.         new_fs.upvalues = {}
  4646.         new_fs.actvar = {}
  4647.   self:open_func(ls, new_fs)
  4648.   new_fs.f.lineDefined = line
  4649.   self:checknext(ls, "(")
  4650.   if needself then
  4651.     self:new_localvarliteral(ls, "self", 0)
  4652.     self:adjustlocalvars(ls, 1)
  4653.   end
  4654.   self:parlist(ls)
  4655.   self:checknext(ls, ")")
  4656.   self:chunk(ls)
  4657.   new_fs.f.lastlinedefined = ls.linenumber
  4658.   self:check_match(ls, "TK_END", "TK_FUNCTION", line)
  4659.   self:close_func(ls)
  4660.   self:pushclosure(ls, new_fs, e)
  4661. end
  4662.  
  4663. ------------------------------------------------------------------------
  4664. -- parse a list of comma-separated expressions
  4665. -- * used is multiple locations
  4666. ------------------------------------------------------------------------
  4667. function luaY:explist1(ls, v)
  4668.   -- explist1 -> expr { ',' expr }
  4669.   local n = 1  -- at least one expression
  4670.   self:expr(ls, v)
  4671.   while self:testnext(ls, ",") do
  4672.     luaK:exp2nextreg(ls.fs, v)
  4673.     self:expr(ls, v)
  4674.     n = n + 1
  4675.   end
  4676.   return n
  4677. end
  4678.  
  4679. ------------------------------------------------------------------------
  4680. -- parse the parameters of a function call
  4681. -- * contrast with parlist(), used in function declarations
  4682. -- * used in primaryexp()
  4683. ------------------------------------------------------------------------
  4684. function luaY:funcargs(ls, f)
  4685.   local fs = ls.fs
  4686.   local args = {}  -- expdesc
  4687.   local nparams
  4688.   local line = ls.linenumber
  4689.   local c = ls.t.token
  4690.   if c == "(" then  -- funcargs -> '(' [ explist1 ] ')'
  4691.     if line ~= ls.lastline then
  4692.       luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
  4693.     end
  4694.     luaX:next(ls)
  4695.     if ls.t.token == ")" then  -- arg list is empty?
  4696.       args.k = "VVOID"
  4697.     else
  4698.       self:explist1(ls, args)
  4699.       luaK:setmultret(fs, args)
  4700.     end
  4701.     self:check_match(ls, ")", "(", line)
  4702.   elseif c == "{" then  -- funcargs -> constructor
  4703.     self:constructor(ls, args)
  4704.   elseif c == "TK_STRING" then  -- funcargs -> STRING
  4705.     self:codestring(ls, args, ls.t.seminfo)
  4706.     luaX:next(ls)  -- must use 'seminfo' before 'next'
  4707.   else
  4708.     luaX:syntaxerror(ls, "function arguments expected")
  4709.     return
  4710.   end
  4711.   assert(f.k == "VNONRELOC")
  4712.   local base = f.info  -- base register for call
  4713.   if self:hasmultret(args.k) then
  4714.     nparams = self.LUA_MULTRET  -- open call
  4715.   else
  4716.     if args.k ~= "VVOID" then
  4717.       luaK:exp2nextreg(fs, args)  -- close last argument
  4718.     end
  4719.     nparams = fs.freereg - (base + 1)
  4720.   end
  4721.   self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
  4722.   luaK:fixline(fs, line)
  4723.   fs.freereg = base + 1  -- call remove function and arguments and leaves
  4724.                          -- (unless changed) one result
  4725. end
  4726.  
  4727. --[[--------------------------------------------------------------------
  4728. -- Expression parsing
  4729. ----------------------------------------------------------------------]]
  4730.  
  4731. ------------------------------------------------------------------------
  4732. -- parses an expression in parentheses or a single variable
  4733. -- * used in primaryexp()
  4734. ------------------------------------------------------------------------
  4735. function luaY:prefixexp(ls, v)
  4736.   -- prefixexp -> NAME | '(' expr ')'
  4737.   local c = ls.t.token
  4738.   if c == "(" then
  4739.     local line = ls.linenumber
  4740.     luaX:next(ls)
  4741.     self:expr(ls, v)
  4742.     self:check_match(ls, ")", "(", line)
  4743.     luaK:dischargevars(ls.fs, v)
  4744.   elseif c == "TK_NAME" then
  4745.     self:singlevar(ls, v)
  4746.   else
  4747.     luaX:syntaxerror(ls, "unexpected symbol")
  4748.   end--if c
  4749.   return
  4750. end
  4751.  
  4752. ------------------------------------------------------------------------
  4753. -- parses a prefixexp (an expression in parentheses or a single variable)
  4754. -- or a function call specification
  4755. -- * used in simpleexp(), assignment(), exprstat()
  4756. ------------------------------------------------------------------------
  4757. function luaY:primaryexp(ls, v)
  4758.   -- primaryexp ->
  4759.   --    prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
  4760.   local fs = ls.fs
  4761.   self:prefixexp(ls, v)
  4762.   while true do
  4763.     local c = ls.t.token
  4764.     if c == "." then  -- field
  4765.       self:field(ls, v)
  4766.     elseif c == "[" then  -- '[' exp1 ']'
  4767.       local key = {}  -- expdesc
  4768.       luaK:exp2anyreg(fs, v)
  4769.       self:yindex(ls, key)
  4770.       luaK:indexed(fs, v, key)
  4771.     elseif c == ":" then  -- ':' NAME funcargs
  4772.       local key = {}  -- expdesc
  4773.       luaX:next(ls)
  4774.       self:checkname(ls, key)
  4775.       luaK:_self(fs, v, key)
  4776.       self:funcargs(ls, v)
  4777.     elseif c == "(" or c == "TK_STRING" or c == "{" then  -- funcargs
  4778.       luaK:exp2nextreg(fs, v)
  4779.       self:funcargs(ls, v)
  4780.     else
  4781.       return
  4782.     end--if c
  4783.   end--while
  4784. end
  4785.  
  4786. ------------------------------------------------------------------------
  4787. -- parses general expression types, constants handled here
  4788. -- * used in subexpr()
  4789. ------------------------------------------------------------------------
  4790. function luaY:simpleexp(ls, v)
  4791.   -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
  4792.   --              constructor | FUNCTION body | primaryexp
  4793.   local c = ls.t.token
  4794.   if c == "TK_NUMBER" then
  4795.     self:init_exp(v, "VKNUM", 0)
  4796.     v.nval = ls.t.seminfo
  4797.   elseif c == "TK_STRING" then
  4798.     self:codestring(ls, v, ls.t.seminfo)
  4799.   elseif c == "TK_NIL" then
  4800.     self:init_exp(v, "VNIL", 0)
  4801.   elseif c == "TK_TRUE" then
  4802.     self:init_exp(v, "VTRUE", 0)
  4803.   elseif c == "TK_FALSE" then
  4804.     self:init_exp(v, "VFALSE", 0)
  4805.   elseif c == "TK_DOTS" then  -- vararg
  4806.     local fs = ls.fs
  4807.     self:check_condition(ls, fs.f.is_vararg ~= 0,
  4808.                     "cannot use "..self:LUA_QL("...").." outside a vararg function");
  4809.     -- NOTE: the following substitutes for a bitop, but is value-specific
  4810.     local is_vararg = fs.f.is_vararg
  4811.     if is_vararg >= self.VARARG_NEEDSARG then
  4812.       fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG  -- don't need 'arg'
  4813.     end
  4814.     self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
  4815.   elseif c == "{" then  -- constructor
  4816.     self:constructor(ls, v)
  4817.     return
  4818.   elseif c == "TK_FUNCTION" then
  4819.     luaX:next(ls)
  4820.     self:body(ls, v, false, ls.linenumber)
  4821.     return
  4822.   else
  4823.     self:primaryexp(ls, v)
  4824.     return
  4825.   end--if c
  4826.   luaX:next(ls)
  4827. end
  4828.  
  4829. ------------------------------------------------------------------------
  4830. -- Translates unary operators tokens if found, otherwise returns
  4831. -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
  4832. -- * used in subexpr()
  4833. ------------------------------------------------------------------------
  4834. function luaY:getunopr(op)
  4835.   if op == "TK_NOT" then
  4836.     return "OPR_NOT"
  4837.   elseif op == "-" then
  4838.     return "OPR_MINUS"
  4839.   elseif op == "#" then
  4840.     return "OPR_LEN"
  4841.   else
  4842.     return "OPR_NOUNOPR"
  4843.   end
  4844. end
  4845.  
  4846. ------------------------------------------------------------------------
  4847. -- Translates binary operator tokens if found, otherwise returns
  4848. -- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
  4849. -- * used in subexpr()
  4850. ------------------------------------------------------------------------
  4851. luaY.getbinopr_table = {
  4852.   ["+"] = "OPR_ADD",
  4853.   ["-"] = "OPR_SUB",
  4854.   ["*"] = "OPR_MUL",
  4855.   ["/"] = "OPR_DIV",
  4856.   ["%"] = "OPR_MOD",
  4857.   ["^"] = "OPR_POW",
  4858.   ["TK_CONCAT"] = "OPR_CONCAT",
  4859.   ["TK_NE"] = "OPR_NE",
  4860.   ["TK_EQ"] = "OPR_EQ",
  4861.   ["<"] = "OPR_LT",
  4862.   ["TK_LE"] = "OPR_LE",
  4863.   [">"] = "OPR_GT",
  4864.   ["TK_GE"] = "OPR_GE",
  4865.   ["TK_AND"] = "OPR_AND",
  4866.   ["TK_OR"] = "OPR_OR",
  4867. }
  4868. function luaY:getbinopr(op)
  4869.   local opr = self.getbinopr_table[op]
  4870.   if opr then return opr else return "OPR_NOBINOPR" end
  4871. end
  4872.  
  4873. ------------------------------------------------------------------------
  4874. -- the following priority table consists of pairs of left/right values
  4875. -- for binary operators (was a static const struct); grep for ORDER OPR
  4876. -- * the following struct is replaced:
  4877. --   static const struct {
  4878. --     lu_byte left;  /* left priority for each binary operator */
  4879. --     lu_byte right; /* right priority */
  4880. --   } priority[] = {  /* ORDER OPR */
  4881. ------------------------------------------------------------------------
  4882. luaY.priority = {
  4883.   {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%'
  4884.   {10, 9}, {5, 4},                 -- power and concat (right associative)
  4885.   {3, 3}, {3, 3},                  -- equality
  4886.   {3, 3}, {3, 3}, {3, 3}, {3, 3},  -- order
  4887.   {2, 2}, {1, 1}                   -- logical (and/or)
  4888. }
  4889.  
  4890. luaY.UNARY_PRIORITY = 8  -- priority for unary operators
  4891.  
  4892. ------------------------------------------------------------------------
  4893. -- Parse subexpressions. Includes handling of unary operators and binary
  4894. -- operators. A subexpr is given the rhs priority level of the operator
  4895. -- immediately left of it, if any (limit is -1 if none,) and if a binop
  4896. -- is found, limit is compared with the lhs priority level of the binop
  4897. -- in order to determine which executes first.
  4898. ------------------------------------------------------------------------
  4899.  
  4900. ------------------------------------------------------------------------
  4901. -- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
  4902. -- where 'binop' is any binary operator with a priority higher than 'limit'
  4903. -- * for priority lookups with self.priority[], 1=left and 2=right
  4904. -- * recursively called
  4905. -- * used in expr()
  4906. ------------------------------------------------------------------------
  4907. function luaY:subexpr(ls, v, limit)
  4908.   self:enterlevel(ls)
  4909.   local uop = self:getunopr(ls.t.token)
  4910.   if uop ~= "OPR_NOUNOPR" then
  4911.     luaX:next(ls)
  4912.     self:subexpr(ls, v, self.UNARY_PRIORITY)
  4913.     luaK:prefix(ls.fs, uop, v)
  4914.   else
  4915.     self:simpleexp(ls, v)
  4916.   end
  4917.   -- expand while operators have priorities higher than 'limit'
  4918.   local op = self:getbinopr(ls.t.token)
  4919.   while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
  4920.     local v2 = {}  -- expdesc
  4921.     luaX:next(ls)
  4922.     luaK:infix(ls.fs, op, v)
  4923.     -- read sub-expression with higher priority
  4924.     local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
  4925.     luaK:posfix(ls.fs, op, v, v2)
  4926.     op = nextop
  4927.   end
  4928.   self:leavelevel(ls)
  4929.   return op  -- return first untreated operator
  4930. end
  4931.  
  4932. ------------------------------------------------------------------------
  4933. -- Expression parsing starts here. Function subexpr is entered with the
  4934. -- left operator (which is non-existent) priority of -1, which is lower
  4935. -- than all actual operators. Expr information is returned in parm v.
  4936. -- * used in multiple locations
  4937. ------------------------------------------------------------------------
  4938. function luaY:expr(ls, v)
  4939.   self:subexpr(ls, v, 0)
  4940. end
  4941.  
  4942. -- }====================================================================
  4943.  
  4944. --[[--------------------------------------------------------------------
  4945. -- Rules for Statements
  4946. ----------------------------------------------------------------------]]
  4947.  
  4948. ------------------------------------------------------------------------
  4949. -- checks next token, used as a look-ahead
  4950. -- * returns boolean instead of 0|1
  4951. -- * used in retstat(), chunk()
  4952. ------------------------------------------------------------------------
  4953. function luaY:block_follow(token)
  4954.   if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
  4955.      or token == "TK_UNTIL" or token == "TK_EOS" then
  4956.     return true
  4957.   else
  4958.     return false
  4959.   end
  4960. end
  4961.  
  4962. ------------------------------------------------------------------------
  4963. -- parse a code block or unit
  4964. -- * used in multiple functions
  4965. ------------------------------------------------------------------------
  4966. function luaY:block(ls)
  4967.   -- block -> chunk
  4968.   local fs = ls.fs
  4969.   local bl = {}  -- BlockCnt
  4970.   self:enterblock(fs, bl, false)
  4971.   self:chunk(ls)
  4972.   assert(bl.breaklist == luaK.NO_JUMP)
  4973.   self:leaveblock(fs)
  4974. end
  4975.  
  4976. ------------------------------------------------------------------------
  4977. -- structure to chain all variables in the left-hand side of an
  4978. -- assignment
  4979. -- struct LHS_assign:
  4980. --   prev  -- (table: struct LHS_assign)
  4981. --   v  -- variable (global, local, upvalue, or indexed) (table: expdesc)
  4982. ------------------------------------------------------------------------
  4983.  
  4984. ------------------------------------------------------------------------
  4985. -- check whether, in an assignment to a local variable, the local variable
  4986. -- is needed in a previous assignment (to a table). If so, save original
  4987. -- local value in a safe place and use this safe copy in the previous
  4988. -- assignment.
  4989. -- * used in assignment()
  4990. ------------------------------------------------------------------------
  4991. function luaY:check_conflict(ls, lh, v)
  4992.   local fs = ls.fs
  4993.   local extra = fs.freereg  -- eventual position to save local variable
  4994.   local conflict = false
  4995.   while lh do
  4996.     if lh.v.k == "VINDEXED" then
  4997.       if lh.v.info == v.info then  -- conflict?
  4998.         conflict = true
  4999.         lh.v.info = extra  -- previous assignment will use safe copy
  5000.       end
  5001.       if lh.v.aux == v.info then  -- conflict?
  5002.         conflict = true
  5003.         lh.v.aux = extra  -- previous assignment will use safe copy
  5004.       end
  5005.     end
  5006.     lh = lh.prev
  5007.   end
  5008.   if conflict then
  5009.     luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0)  -- make copy
  5010.     luaK:reserveregs(fs, 1)
  5011.   end
  5012. end
  5013.  
  5014. ------------------------------------------------------------------------
  5015. -- parse a variable assignment sequence
  5016. -- * recursively called
  5017. -- * used in exprstat()
  5018. ------------------------------------------------------------------------
  5019. function luaY:assignment(ls, lh, nvars)
  5020.   local e = {}  -- expdesc
  5021.   -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
  5022.   local c = lh.v.k
  5023.   self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
  5024.                        or c == "VINDEXED", "syntax error")
  5025.   if self:testnext(ls, ",") then  -- assignment -> ',' primaryexp assignment
  5026.     local nv = {}  -- LHS_assign
  5027.           nv.v = {}
  5028.     nv.prev = lh
  5029.     self:primaryexp(ls, nv.v)
  5030.     if nv.v.k == "VLOCAL" then
  5031.       self:check_conflict(ls, lh, nv.v)
  5032.     end
  5033.     self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls,
  5034.                     "variables in assignment")
  5035.     self:assignment(ls, nv, nvars + 1)
  5036.   else  -- assignment -> '=' explist1
  5037.     self:checknext(ls, "=")
  5038.     local nexps = self:explist1(ls, e)
  5039.     if nexps ~= nvars then
  5040.       self:adjust_assign(ls, nvars, nexps, e)
  5041.       if nexps > nvars then
  5042.         ls.fs.freereg = ls.fs.freereg - (nexps - nvars)  -- remove extra values
  5043.       end
  5044.     else
  5045.       luaK:setoneret(ls.fs, e)  -- close last expression
  5046.       luaK:storevar(ls.fs, lh.v, e)
  5047.       return  -- avoid default
  5048.     end
  5049.   end
  5050.   self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1)  -- default assignment
  5051.   luaK:storevar(ls.fs, lh.v, e)
  5052. end
  5053.  
  5054. ------------------------------------------------------------------------
  5055. -- parse condition in a repeat statement or an if control structure
  5056. -- * used in repeatstat(), test_then_block()
  5057. ------------------------------------------------------------------------
  5058. function luaY:cond(ls)
  5059.   -- cond -> exp
  5060.   local v = {}  -- expdesc
  5061.   self:expr(ls, v)  -- read condition
  5062.   if v.k == "VNIL" then v.k = "VFALSE" end  -- 'falses' are all equal here
  5063.   luaK:goiftrue(ls.fs, v)
  5064.   return v.f
  5065. end
  5066.  
  5067. ------------------------------------------------------------------------
  5068. -- parse a break statement
  5069. -- * used in statements()
  5070. ------------------------------------------------------------------------
  5071. function luaY:breakstat(ls)
  5072.   -- stat -> BREAK
  5073.   local fs = ls.fs
  5074.   local bl = fs.bl
  5075.   local upval = false
  5076.   while bl and not bl.isbreakable do
  5077.     if bl.upval then upval = true end
  5078.     bl = bl.previous
  5079.   end
  5080.   if not bl then
  5081.     luaX:syntaxerror(ls, "no loop to break")
  5082.   end
  5083.   if upval then
  5084.     luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  5085.   end
  5086.   bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
  5087. end
  5088.  
  5089. ------------------------------------------------------------------------
  5090. -- parse a while-do control structure, body processed by block()
  5091. -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
  5092. --   the function's implementation can be removed
  5093. -- * used in statements()
  5094. ------------------------------------------------------------------------
  5095. function luaY:whilestat(ls, line)
  5096.   -- whilestat -> WHILE cond DO block END
  5097.   local fs = ls.fs
  5098.   local bl = {}  -- BlockCnt
  5099.   luaX:next(ls)  -- skip WHILE
  5100.   local whileinit = luaK:getlabel(fs)
  5101.   local condexit = self:cond(ls)
  5102.   self:enterblock(fs, bl, true)
  5103.   self:checknext(ls, "TK_DO")
  5104.   self:block(ls)
  5105.   luaK:patchlist(fs, luaK:jump(fs), whileinit)
  5106.   self:check_match(ls, "TK_END", "TK_WHILE", line)
  5107.   self:leaveblock(fs)
  5108.   luaK:patchtohere(fs, condexit)  -- false conditions finish the loop
  5109. end
  5110.  
  5111. ------------------------------------------------------------------------
  5112. -- parse a repeat-until control structure, body parsed by chunk()
  5113. -- * used in statements()
  5114. ------------------------------------------------------------------------
  5115. function luaY:repeatstat(ls, line)
  5116.   -- repeatstat -> REPEAT block UNTIL cond
  5117.   local fs = ls.fs
  5118.   local repeat_init = luaK:getlabel(fs)
  5119.   local bl1, bl2 = {}, {}  -- BlockCnt
  5120.   self:enterblock(fs, bl1, true)  -- loop block
  5121.   self:enterblock(fs, bl2, false)  -- scope block
  5122.   luaX:next(ls)  -- skip REPEAT
  5123.   self:chunk(ls)
  5124.   self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
  5125.   local condexit = self:cond(ls)  -- read condition (inside scope block)
  5126.   if not bl2.upval then  -- no upvalues?
  5127.     self:leaveblock(fs)  -- finish scope
  5128.     luaK:patchlist(ls.fs, condexit, repeat_init)  -- close the loop
  5129.   else  -- complete semantics when there are upvalues
  5130.     self:breakstat(ls)  -- if condition then break
  5131.     luaK:patchtohere(ls.fs, condexit)  -- else...
  5132.     self:leaveblock(fs)  -- finish scope...
  5133.     luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init)  -- and repeat
  5134.   end
  5135.   self:leaveblock(fs)  -- finish loop
  5136. end
  5137.  
  5138. ------------------------------------------------------------------------
  5139. -- parse the single expressions needed in numerical for loops
  5140. -- * used in fornum()
  5141. ------------------------------------------------------------------------
  5142. function luaY:exp1(ls)
  5143.   local e = {}  -- expdesc
  5144.   self:expr(ls, e)
  5145.   local k = e.k
  5146.   luaK:exp2nextreg(ls.fs, e)
  5147.   return k
  5148. end
  5149.  
  5150. ------------------------------------------------------------------------
  5151. -- parse a for loop body for both versions of the for loop
  5152. -- * used in fornum(), forlist()
  5153. ------------------------------------------------------------------------
  5154. function luaY:forbody(ls, base, line, nvars, isnum)
  5155.   -- forbody -> DO block
  5156.   local bl = {}  -- BlockCnt
  5157.   local fs = ls.fs
  5158.   self:adjustlocalvars(ls, 3)  -- control variables
  5159.   self:checknext(ls, "TK_DO")
  5160.   local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP)
  5161.                      or luaK:jump(fs)
  5162.   self:enterblock(fs, bl, false)  -- scope for declared variables
  5163.   self:adjustlocalvars(ls, nvars)
  5164.   luaK:reserveregs(fs, nvars)
  5165.   self:block(ls)
  5166.   self:leaveblock(fs)  -- end of scope for declared variables
  5167.   luaK:patchtohere(fs, prep)
  5168.   local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
  5169.                        or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
  5170.   luaK:fixline(fs, line)  -- pretend that `OP_FOR' starts the loop
  5171.   luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
  5172. end
  5173.  
  5174. ------------------------------------------------------------------------
  5175. -- parse a numerical for loop, calls forbody()
  5176. -- * used in forstat()
  5177. ------------------------------------------------------------------------
  5178. function luaY:fornum(ls, varname, line)
  5179.   -- fornum -> NAME = exp1,exp1[,exp1] forbody
  5180.   local fs = ls.fs
  5181.   local base = fs.freereg
  5182.   self:new_localvarliteral(ls, "(for index)", 0)
  5183.   self:new_localvarliteral(ls, "(for limit)", 1)
  5184.   self:new_localvarliteral(ls, "(for step)", 2)
  5185.   self:new_localvar(ls, varname, 3)
  5186.   self:checknext(ls, '=')
  5187.   self:exp1(ls)  -- initial value
  5188.   self:checknext(ls, ",")
  5189.   self:exp1(ls)  -- limit
  5190.   if self:testnext(ls, ",") then
  5191.     self:exp1(ls)  -- optional step
  5192.   else  -- default step = 1
  5193.     luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
  5194.     luaK:reserveregs(fs, 1)
  5195.   end
  5196.   self:forbody(ls, base, line, 1, true)
  5197. end
  5198.  
  5199. ------------------------------------------------------------------------
  5200. -- parse a generic for loop, calls forbody()
  5201. -- * used in forstat()
  5202. ------------------------------------------------------------------------
  5203. function luaY:forlist(ls, indexname)
  5204.   -- forlist -> NAME {,NAME} IN explist1 forbody
  5205.   local fs = ls.fs
  5206.   local e = {}  -- expdesc
  5207.   local nvars = 0
  5208.   local base = fs.freereg
  5209.   -- create control variables
  5210.   self:new_localvarliteral(ls, "(for generator)", nvars)
  5211.   nvars = nvars + 1
  5212.   self:new_localvarliteral(ls, "(for state)", nvars)
  5213.   nvars = nvars + 1
  5214.   self:new_localvarliteral(ls, "(for control)", nvars)
  5215.   nvars = nvars + 1
  5216.   -- create declared variables
  5217.   self:new_localvar(ls, indexname, nvars)
  5218.   nvars = nvars + 1
  5219.   while self:testnext(ls, ",") do
  5220.     self:new_localvar(ls, self:str_checkname(ls), nvars)
  5221.     nvars = nvars + 1
  5222.   end
  5223.   self:checknext(ls, "TK_IN")
  5224.   local line = ls.linenumber
  5225.   self:adjust_assign(ls, 3, self:explist1(ls, e), e)
  5226.   luaK:checkstack(fs, 3)  -- extra space to call generator
  5227.   self:forbody(ls, base, line, nvars - 3, false)
  5228. end
  5229.  
  5230. ------------------------------------------------------------------------
  5231. -- initial parsing for a for loop, calls fornum() or forlist()
  5232. -- * used in statements()
  5233. ------------------------------------------------------------------------
  5234. function luaY:forstat(ls, line)
  5235.   -- forstat -> FOR (fornum | forlist) END
  5236.   local fs = ls.fs
  5237.   local bl = {}  -- BlockCnt
  5238.   self:enterblock(fs, bl, true)  -- scope for loop and control variables
  5239.   luaX:next(ls)  -- skip `for'
  5240.   local varname = self:str_checkname(ls)  -- first variable name
  5241.   local c = ls.t.token
  5242.   if c == "=" then
  5243.     self:fornum(ls, varname, line)
  5244.   elseif c == "," or c == "TK_IN" then
  5245.     self:forlist(ls, varname)
  5246.   else
  5247.     luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected")
  5248.   end
  5249.   self:check_match(ls, "TK_END", "TK_FOR", line)
  5250.   self:leaveblock(fs)  -- loop scope (`break' jumps to this point)
  5251. end
  5252.  
  5253. ------------------------------------------------------------------------
  5254. -- parse part of an if control structure, including the condition
  5255. -- * used in ifstat()
  5256. ------------------------------------------------------------------------
  5257. function luaY:test_then_block(ls)
  5258.   -- test_then_block -> [IF | ELSEIF] cond THEN block
  5259.   luaX:next(ls)  -- skip IF or ELSEIF
  5260.   local condexit = self:cond(ls)
  5261.   self:checknext(ls, "TK_THEN")
  5262.   self:block(ls)  -- `then' part
  5263.   return condexit
  5264. end
  5265.  
  5266. ------------------------------------------------------------------------
  5267. -- parse an if control structure
  5268. -- * used in statements()
  5269. ------------------------------------------------------------------------
  5270. function luaY:ifstat(ls, line)
  5271.   -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
  5272.   local fs = ls.fs
  5273.   local escapelist = luaK.NO_JUMP
  5274.   local flist = self:test_then_block(ls)  -- IF cond THEN block
  5275.   while ls.t.token == "TK_ELSEIF" do
  5276.     escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  5277.     luaK:patchtohere(fs, flist)
  5278.     flist = self:test_then_block(ls)  -- ELSEIF cond THEN block
  5279.   end
  5280.   if ls.t.token == "TK_ELSE" then
  5281.     escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  5282.     luaK:patchtohere(fs, flist)
  5283.     luaX:next(ls)  -- skip ELSE (after patch, for correct line info)
  5284.     self:block(ls)  -- 'else' part
  5285.   else
  5286.     escapelist = luaK:concat(fs, escapelist, flist)
  5287.   end
  5288.   luaK:patchtohere(fs, escapelist)
  5289.   self:check_match(ls, "TK_END", "TK_IF", line)
  5290. end
  5291.  
  5292. ------------------------------------------------------------------------
  5293. -- parse a local function statement
  5294. -- * used in statements()
  5295. ------------------------------------------------------------------------
  5296. function luaY:localfunc(ls)
  5297.   local v, b = {}, {}  -- expdesc
  5298.   local fs = ls.fs
  5299.   self:new_localvar(ls, self:str_checkname(ls), 0)
  5300.   self:init_exp(v, "VLOCAL", fs.freereg)
  5301.   luaK:reserveregs(fs, 1)
  5302.   self:adjustlocalvars(ls, 1)
  5303.   self:body(ls, b, false, ls.linenumber)
  5304.   luaK:storevar(fs, v, b)
  5305.   -- debug information will only see the variable after this point!
  5306.   self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
  5307. end
  5308.  
  5309. ------------------------------------------------------------------------
  5310. -- parse a local variable declaration statement
  5311. -- * used in statements()
  5312. ------------------------------------------------------------------------
  5313. function luaY:localstat(ls)
  5314.   -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
  5315.   local nvars = 0
  5316.   local nexps
  5317.   local e = {}  -- expdesc
  5318.   repeat
  5319.     self:new_localvar(ls, self:str_checkname(ls), nvars)
  5320.     nvars = nvars + 1
  5321.   until not self:testnext(ls, ",")
  5322.   if self:testnext(ls, "=") then
  5323.     nexps = self:explist1(ls, e)
  5324.   else
  5325.     e.k = "VVOID"
  5326.     nexps = 0
  5327.   end
  5328.   self:adjust_assign(ls, nvars, nexps, e)
  5329.   self:adjustlocalvars(ls, nvars)
  5330. end
  5331.  
  5332. ------------------------------------------------------------------------
  5333. -- parse a function name specification
  5334. -- * used in funcstat()
  5335. ------------------------------------------------------------------------
  5336. function luaY:funcname(ls, v)
  5337.   -- funcname -> NAME {field} [':' NAME]
  5338.   local needself = false
  5339.   self:singlevar(ls, v)
  5340.   while ls.t.token == "." do
  5341.     self:field(ls, v)
  5342.   end
  5343.   if ls.t.token == ":" then
  5344.     needself = true
  5345.     self:field(ls, v)
  5346.   end
  5347.   return needself
  5348. end
  5349.  
  5350. ------------------------------------------------------------------------
  5351. -- parse a function statement
  5352. -- * used in statements()
  5353. ------------------------------------------------------------------------
  5354. function luaY:funcstat(ls, line)
  5355.   -- funcstat -> FUNCTION funcname body
  5356.   local v, b = {}, {}  -- expdesc
  5357.   luaX:next(ls)  -- skip FUNCTION
  5358.   local needself = self:funcname(ls, v)
  5359.   self:body(ls, b, needself, line)
  5360.   luaK:storevar(ls.fs, v, b)
  5361.   luaK:fixline(ls.fs, line)  -- definition 'happens' in the first line
  5362. end
  5363.  
  5364. ------------------------------------------------------------------------
  5365. -- parse a function call with no returns or an assignment statement
  5366. -- * used in statements()
  5367. ------------------------------------------------------------------------
  5368. function luaY:exprstat(ls)
  5369.   -- stat -> func | assignment
  5370.   local fs = ls.fs
  5371.   local v = {}  -- LHS_assign
  5372.         v.v = {}
  5373.   self:primaryexp(ls, v.v)
  5374.   if v.v.k == "VCALL" then  -- stat -> func
  5375.     luaP:SETARG_C(luaK:getcode(fs, v.v), 1)  -- call statement uses no results
  5376.   else  -- stat -> assignment
  5377.     v.prev = nil
  5378.     self:assignment(ls, v, 1)
  5379.   end
  5380. end
  5381.  
  5382. ------------------------------------------------------------------------
  5383. -- parse a return statement
  5384. -- * used in statements()
  5385. ------------------------------------------------------------------------
  5386. function luaY:retstat(ls)
  5387.   -- stat -> RETURN explist
  5388.   local fs = ls.fs
  5389.   local e = {}  -- expdesc
  5390.   local first, nret  -- registers with returned values
  5391.   luaX:next(ls)  -- skip RETURN
  5392.   if self:block_follow(ls.t.token) or ls.t.token == ";" then
  5393.     first, nret = 0, 0  -- return no values
  5394.   else
  5395.     nret = self:explist1(ls, e)  -- optional return values
  5396.     if self:hasmultret(e.k) then
  5397.       luaK:setmultret(fs, e)
  5398.       if e.k == "VCALL" and nret == 1 then  -- tail call?
  5399.         luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
  5400.         assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
  5401.       end
  5402.       first = fs.nactvar
  5403.       nret = self.LUA_MULTRET  -- return all values
  5404.     else
  5405.       if nret == 1 then  -- only one single value?
  5406.         first = luaK:exp2anyreg(fs, e)
  5407.       else
  5408.         luaK:exp2nextreg(fs, e)  -- values must go to the 'stack'
  5409.         first = fs.nactvar  -- return all 'active' values
  5410.         assert(nret == fs.freereg - first)
  5411.       end
  5412.     end--if
  5413.   end--if
  5414.   luaK:ret(fs, first, nret)
  5415. end
  5416.  
  5417. ------------------------------------------------------------------------
  5418. -- initial parsing for statements, calls a lot of functions
  5419. -- * returns boolean instead of 0|1
  5420. -- * used in chunk()
  5421. ------------------------------------------------------------------------
  5422. function luaY:statement(ls)
  5423.   local line = ls.linenumber  -- may be needed for error messages
  5424.   local c = ls.t.token
  5425.   if c == "TK_IF" then  -- stat -> ifstat
  5426.     self:ifstat(ls, line)
  5427.     return false
  5428.   elseif c == "TK_WHILE" then  -- stat -> whilestat
  5429.     self:whilestat(ls, line)
  5430.     return false
  5431.   elseif c == "TK_DO" then  -- stat -> DO block END
  5432.     luaX:next(ls)  -- skip DO
  5433.     self:block(ls)
  5434.     self:check_match(ls, "TK_END", "TK_DO", line)
  5435.     return false
  5436.   elseif c == "TK_FOR" then  -- stat -> forstat
  5437.     self:forstat(ls, line)
  5438.     return false
  5439.   elseif c == "TK_REPEAT" then  -- stat -> repeatstat
  5440.     self:repeatstat(ls, line)
  5441.     return false
  5442.   elseif c == "TK_FUNCTION" then  -- stat -> funcstat
  5443.     self:funcstat(ls, line)
  5444.     return false
  5445.   elseif c == "TK_LOCAL" then  -- stat -> localstat
  5446.     luaX:next(ls)  -- skip LOCAL
  5447.     if self:testnext(ls, "TK_FUNCTION") then  -- local function?
  5448.       self:localfunc(ls)
  5449.     else
  5450.       self:localstat(ls)
  5451.     end
  5452.     return false
  5453.   elseif c == "TK_RETURN" then  -- stat -> retstat
  5454.     self:retstat(ls)
  5455.     return true  -- must be last statement
  5456.   elseif c == "TK_BREAK" then  -- stat -> breakstat
  5457.     luaX:next(ls)  -- skip BREAK
  5458.     self:breakstat(ls)
  5459.     return true  -- must be last statement
  5460.   else
  5461.     self:exprstat(ls)
  5462.     return false  -- to avoid warnings
  5463.   end--if c
  5464. end
  5465.  
  5466. ------------------------------------------------------------------------
  5467. -- parse a chunk, which consists of a bunch of statements
  5468. -- * used in parser(), body(), block(), repeatstat()
  5469. ------------------------------------------------------------------------
  5470. function luaY:chunk(ls)
  5471.   -- chunk -> { stat [';'] }
  5472.   local islast = false
  5473.   self:enterlevel(ls)
  5474.   while not islast and not self:block_follow(ls.t.token) do
  5475.     islast = self:statement(ls)
  5476.     self:testnext(ls, ";")
  5477.     assert(ls.fs.f.maxstacksize >= ls.fs.freereg and
  5478.                ls.fs.freereg >= ls.fs.nactvar)
  5479.     ls.fs.freereg = ls.fs.nactvar  -- free registers
  5480.   end
  5481.   self:leavelevel(ls)
  5482. end
  5483.  
  5484. -- }======================================================================
  5485. return luaY
  5486. end
  5487.  
  5488. function LuaZ()
  5489. local script = script.LuaZ
  5490. --[[--------------------------------------------------------------------
  5491.  
  5492.   lzio.lua
  5493.   Lua buffered streams in Lua
  5494.   This file is part of Yueliang.
  5495.  
  5496.   Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
  5497.   The COPYRIGHT file describes the conditions
  5498.   under which this software may be distributed.
  5499.  
  5500.   See the ChangeLog for more information.
  5501.  
  5502. ----------------------------------------------------------------------]]
  5503.  
  5504. --[[--------------------------------------------------------------------
  5505. -- Notes:
  5506. -- * EOZ is implemented as a string, "EOZ"
  5507. -- * Format of z structure (ZIO)
  5508. --     z.n       -- bytes still unread
  5509. --     z.p       -- last read position position in buffer
  5510. --     z.reader  -- chunk reader function
  5511. --     z.data    -- additional data
  5512. -- * Current position, p, is now last read index instead of a pointer
  5513. --
  5514. -- Not implemented:
  5515. -- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk
  5516. -- * luaZ_read: used only in lundump.c:ezread to read +1 bytes
  5517. -- * luaZ_openspace: dropped; let Lua handle buffers as strings (used in
  5518. --   lundump.c:LoadString & lvm.c:luaV_concat)
  5519. -- * luaZ buffer macros: dropped; buffers are handled as strings
  5520. -- * lauxlib.c:getF reader implementation has an extraline flag to
  5521. --   skip over a shbang (#!) line, this is not implemented here
  5522. --
  5523. -- Added:
  5524. -- (both of the following are vaguely adapted from lauxlib.c)
  5525. -- * luaZ:make_getS: create Reader from a string
  5526. -- * luaZ:make_getF: create Reader that reads from a file
  5527. --
  5528. -- Changed in 5.1.x:
  5529. -- * Chunkreader renamed to Reader (ditto with Chunkwriter)
  5530. -- * Zio struct: no more name string, added Lua state for reader
  5531. --   (however, Yueliang readers do not require a Lua state)
  5532. ----------------------------------------------------------------------]]
  5533.  
  5534. local luaZ = {}
  5535.  
  5536. ------------------------------------------------------------------------
  5537. -- * reader() should return a string, or nil if nothing else to parse.
  5538. --   Additional data can be set only during stream initialization
  5539. -- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string)
  5540. -- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h)
  5541. -- * Original Reader typedef:
  5542. --   const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
  5543. -- * This Lua chunk reader implementation:
  5544. --   returns string or nil, no arguments to function
  5545. ------------------------------------------------------------------------
  5546.  
  5547. ------------------------------------------------------------------------
  5548. -- create a chunk reader from a source string
  5549. ------------------------------------------------------------------------
  5550. function luaZ:make_getS(buff)
  5551.   local b = buff
  5552.   return function() -- chunk reader anonymous function here
  5553.     if not b then return nil end
  5554.     local data = b
  5555.     b = nil
  5556.     return data
  5557.   end
  5558. end
  5559.  
  5560. ------------------------------------------------------------------------
  5561. -- create a chunk reader from a source file
  5562. ------------------------------------------------------------------------
  5563. --[[
  5564. function luaZ:make_getF(filename)
  5565.   local LUAL_BUFFERSIZE = 512
  5566.   local h = io.open(filename, "r")
  5567.   if not h then return nil end
  5568.   return function() -- chunk reader anonymous function here
  5569.     if not h or io.type(h) == "closed file" then return nil end
  5570.     local buff = h:read(LUAL_BUFFERSIZE)
  5571.     if not buff then h:close(); h = nil end
  5572.     return buff
  5573.   end
  5574. end
  5575. --]]
  5576. ------------------------------------------------------------------------
  5577. -- creates a zio input stream
  5578. -- returns the ZIO structure, z
  5579. ------------------------------------------------------------------------
  5580. function luaZ:init(reader, data, name)
  5581.   if not reader then return end
  5582.   local z = {}
  5583.   z.reader = reader
  5584.   z.data = data or ""
  5585.   z.name = name
  5586.   -- set up additional data for reading
  5587.   if not data or data == "" then z.n = 0 else z.n = #data end
  5588.   z.p = 0
  5589.   return z
  5590. end
  5591.  
  5592. ------------------------------------------------------------------------
  5593. -- fill up input buffer
  5594. ------------------------------------------------------------------------
  5595. function luaZ:fill(z)
  5596.   local buff = z.reader()
  5597.   z.data = buff
  5598.   if not buff or buff == "" then return "EOZ" end
  5599.   z.n, z.p = #buff - 1, 1
  5600.   return string.sub(buff, 1, 1)
  5601. end
  5602.  
  5603. ------------------------------------------------------------------------
  5604. -- get next character from the input stream
  5605. -- * local n, p are used to optimize code generation
  5606. ------------------------------------------------------------------------
  5607. function luaZ:zgetc(z)
  5608.   local n, p = z.n, z.p + 1
  5609.   if n > 0 then
  5610.     z.n, z.p = n - 1, p
  5611.     return string.sub(z.data, p, p)
  5612.   else
  5613.     return self:fill(z)
  5614.   end
  5615. end
  5616.  
  5617. return luaZ
  5618. end
  5619.  
  5620. do
  5621.     local Dependencies = {
  5622.         'FiOne',
  5623.         'LuaK',
  5624.         'LuaP',
  5625.         'LuaU',
  5626.         'LuaX',
  5627.         'LuaY',
  5628.         'LuaZ',
  5629.     }
  5630.     for i, v in pairs(Dependencies) do
  5631.         Instance.new("ModuleScript", script).Name = v
  5632.         local SavedVals = {}
  5633.     end
  5634. end
  5635.  
  5636. return assert(require(script)(_G.source, getfenv()))()
Add Comment
Please, Sign In to add comment