aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-23 21:58:02 +1000
committerDavid Walter Seikel2012-01-23 21:58:02 +1000
commit2d1df4714e2736dbde7855ddcd76b4c1de822fa5 (patch)
treec80e4622631c92dbe8dd6375d187702d084c2f2b /LuaSL/testLua/yueliang-0.4.1/orig-5.1.3
parentRemove the conflict, and the comment. lol (diff)
downloadSledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.zip
SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.gz
SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.bz2
SledjHamr-2d1df4714e2736dbde7855ddcd76b4c1de822fa5.tar.xz
Added a big bunch of example lua scripts for testing the speed of lua compiling.
Diffstat (limited to '')
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README54
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua1125
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua372
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua686
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua432
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua1747
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua71
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua125
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua99
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua3
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua99
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua580
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua59
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua202
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua41
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua174
16 files changed, 5869 insertions, 0 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README
new file mode 100644
index 0000000..06fea0a
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/README
@@ -0,0 +1,54 @@
1orig-5.1.3
2
3This is a straightforward port of the Lua 5.1.3 front end (lexical
4analyzer, parser, code generator, binary chunk dumper.)
5
6The front end files are:
7
8 lopcodes.lua opcode definition
9 lzio.lua input streams
10 llex.lua lexical analyzer
11 lparser.lua parser
12 lcode.lua code generator
13 ldump.lua binary chunk dumper
14
15Status: operational, passes all current tests (non-exhaustive)
16
17Major test scripts are:
18
19 test/test_llex.lua exercises test cases
20 test/test_lparser2.lua exercises test cases
21
22luac.lua is a clone of Lua 5.1.3's luac.lua, except that it generates a
23binary chunk using Yueliang's front end implementation.
24
25See the README file in orig-5.0.3 for a discussion.
26
27The following is some performance data. Note that absolutely nothing has
28been done to optimize the code; it is meant to mirror the original C as
29an educational tool.
30
31 lzio llex TOTAL Speed (1)
32 (bytes) (bytes) (bytes) (KB/s)
33----------------------------------------------
34(in orig-5.0.3:)
35----------------------------------------------
36normal 2219 12639 14585 404.9
37stripped 1292 7618 8910
38----------------------------------------------
39(in orig-5.0.3:)
40----------------------------------------------
41normal - - - 389.7
42stripped - - -
43----------------------------------------------
44
45(1) Speed was benchmarked using a Sempron 3000+. Benchmark scripts are
46in the test directories. Best of first three figures quoted. This is a
47measurement of raw lexer speed, i.e. tokens are read but no processing
48is done. All files are read in entirely before running the lexer.
49
50For Lua 5.1.1, see Yueliang 0.2.1, which was the last release of Lua
515.1.1 material.
52
53For Lua 5.1.2, see Yueliang 0.2.2, which was the last release of Lua
545.1.2 material.
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua
new file mode 100644
index 0000000..4dc8548
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lcode.lua
@@ -0,0 +1,1125 @@
1--[[--------------------------------------------------------------------
2
3 lcode.lua
4 Lua 5 code generator in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * one function manipulate a pointer argument with a simple data type
18-- (can't be emulated by a table, ambiguous), now returns that value:
19-- luaK:concat(fs, l1, l2)
20-- * luaM_growvector uses the faux luaY:growvector, for limit checking
21-- * some function parameters changed to boolean, additional code
22-- translates boolean back to 1/0 for instruction fields
23--
24-- Not implemented:
25-- * NOTE there is a failed assert in luaK:addk, a porting problem
26--
27-- Added:
28-- * constant MAXSTACK from llimits.h
29-- * luaK:ttisnumber(o) (from lobject.h)
30-- * luaK:nvalue(o) (from lobject.h)
31-- * luaK:setnilvalue(o) (from lobject.h)
32-- * luaK:setnvalue(o, x) (from lobject.h)
33-- * luaK:setbvalue(o, x) (from lobject.h)
34-- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted
35-- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted
36-- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod,
37-- luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h)
38-- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct
39--
40-- Changed in 5.1.x:
41-- * enum BinOpr has a new entry, OPR_MOD
42-- * enum UnOpr has a new entry, OPR_LEN
43-- * binopistest, unused in 5.0.x, has been deleted
44-- * macro setmultret is new
45-- * functions isnumeral, luaK_ret, boolK are new
46-- * funcion nilK was named nil_constant in 5.0.x
47-- * function interface changed: need_value, patchtestreg, concat
48-- * TObject now a TValue
49-- * functions luaK_setreturns, luaK_setoneret are new
50-- * function luaK:setcallreturns deleted, to be replaced by:
51-- luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret
52-- * functions constfolding, codearith, codecomp are new
53-- * luaK:codebinop has been deleted
54-- * function luaK_setlist is new
55-- * OPR_MULT renamed to OPR_MUL
56----------------------------------------------------------------------]]
57
58-- requires luaP, luaX, luaY
59luaK = {}
60
61------------------------------------------------------------------------
62-- constants used by code generator
63------------------------------------------------------------------------
64-- maximum stack for a Lua function
65luaK.MAXSTACK = 250 -- (from llimits.h)
66
67--[[--------------------------------------------------------------------
68-- other functions
69----------------------------------------------------------------------]]
70
71------------------------------------------------------------------------
72-- emulation of TValue macros (these are from lobject.h)
73-- * TValue is a table since lcode passes references around
74-- * tt member field removed, using Lua's type() instead
75-- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
76-- is used in an assert for testing, see checkliveness(g,obj)
77------------------------------------------------------------------------
78function luaK:ttisnumber(o)
79 if o then return type(o.value) == "number" else return false end
80end
81function luaK:nvalue(o) return o.value end
82function luaK:setnilvalue(o) o.value = nil end
83function luaK:setsvalue(o, x) o.value = x end
84luaK.setnvalue = luaK.setsvalue
85luaK.sethvalue = luaK.setsvalue
86luaK.setbvalue = luaK.setsvalue
87
88------------------------------------------------------------------------
89-- The luai_num* macros define the primitive operations over numbers.
90-- * this is not the entire set of primitive operations from luaconf.h
91-- * used in luaK:constfolding()
92------------------------------------------------------------------------
93function luaK:numadd(a, b) return a + b end
94function luaK:numsub(a, b) return a - b end
95function luaK:nummul(a, b) return a * b end
96function luaK:numdiv(a, b) return a / b end
97function luaK:nummod(a, b) return a % b end
98 -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
99function luaK:numpow(a, b) return a ^ b end
100function luaK:numunm(a) return -a end
101function luaK:numisnan(a) return not a == a end
102 -- a NaN cannot equal another NaN
103
104--[[--------------------------------------------------------------------
105-- code generator functions
106----------------------------------------------------------------------]]
107
108------------------------------------------------------------------------
109-- Marks the end of a patch list. It is an invalid value both as an absolute
110-- address, and as a list link (would link an element to itself).
111------------------------------------------------------------------------
112luaK.NO_JUMP = -1
113
114------------------------------------------------------------------------
115-- grep "ORDER OPR" if you change these enums
116------------------------------------------------------------------------
117luaK.BinOpr = {
118 OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5,
119 OPR_CONCAT = 6,
120 OPR_NE = 7, OPR_EQ = 8,
121 OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12,
122 OPR_AND = 13, OPR_OR = 14,
123 OPR_NOBINOPR = 15,
124}
125
126-- * UnOpr is used by luaK:prefix's op argument, but not directly used
127-- because the function receives the symbols as strings, e.g. "OPR_NOT"
128luaK.UnOpr = {
129 OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3
130}
131
132------------------------------------------------------------------------
133-- returns the instruction object for given e (expdesc), was a macro
134------------------------------------------------------------------------
135function luaK:getcode(fs, e)
136 return fs.f.code[e.info]
137end
138
139------------------------------------------------------------------------
140-- codes an instruction with a signed Bx (sBx) field, was a macro
141-- * used in luaK:jump(), (lparser) luaY:forbody()
142------------------------------------------------------------------------
143function luaK:codeAsBx(fs, o, A, sBx)
144 return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
145end
146
147------------------------------------------------------------------------
148-- set the expdesc e instruction for multiple returns, was a macro
149------------------------------------------------------------------------
150function luaK:setmultret(fs, e)
151 self:setreturns(fs, e, luaY.LUA_MULTRET)
152end
153
154------------------------------------------------------------------------
155-- there is a jump if patch lists are not identical, was a macro
156-- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
157------------------------------------------------------------------------
158function luaK:hasjumps(e)
159 return e.t ~= e.f
160end
161
162------------------------------------------------------------------------
163-- true if the expression is a constant number (for constant folding)
164-- * used in constfolding(), infix()
165------------------------------------------------------------------------
166function luaK:isnumeral(e)
167 return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
168end
169
170------------------------------------------------------------------------
171-- codes loading of nil, optimization done if consecutive locations
172-- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
173------------------------------------------------------------------------
174function luaK:_nil(fs, from, n)
175 if fs.pc > fs.lasttarget then -- no jumps to current position?
176 if fs.pc == 0 then -- function start?
177 if from >= fs.nactvar then
178 return -- positions are already clean
179 end
180 else
181 local previous = fs.f.code[fs.pc - 1]
182 if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
183 local pfrom = luaP:GETARG_A(previous)
184 local pto = luaP:GETARG_B(previous)
185 if pfrom <= from and from <= pto + 1 then -- can connect both?
186 if from + n - 1 > pto then
187 luaP:SETARG_B(previous, from + n - 1)
188 end
189 return
190 end
191 end
192 end
193 end
194 self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
195end
196
197------------------------------------------------------------------------
198--
199-- * used in multiple locations
200------------------------------------------------------------------------
201function luaK:jump(fs)
202 local jpc = fs.jpc -- save list of jumps to here
203 fs.jpc = self.NO_JUMP
204 local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
205 j = self:concat(fs, j, jpc) -- keep them on hold
206 return j
207end
208
209------------------------------------------------------------------------
210-- codes a RETURN instruction
211-- * used in luaY:close_func(), luaY:retstat()
212------------------------------------------------------------------------
213function luaK:ret(fs, first, nret)
214 self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
215end
216
217------------------------------------------------------------------------
218--
219-- * used in luaK:jumponcond(), luaK:codecomp()
220------------------------------------------------------------------------
221function luaK:condjump(fs, op, A, B, C)
222 self:codeABC(fs, op, A, B, C)
223 return self:jump(fs)
224end
225
226------------------------------------------------------------------------
227--
228-- * used in luaK:patchlistaux(), luaK:concat()
229------------------------------------------------------------------------
230function luaK:fixjump(fs, pc, dest)
231 local jmp = fs.f.code[pc]
232 local offset = dest - (pc + 1)
233 lua_assert(dest ~= self.NO_JUMP)
234 if math.abs(offset) > luaP.MAXARG_sBx then
235 luaX:syntaxerror(fs.ls, "control structure too long")
236 end
237 luaP:SETARG_sBx(jmp, offset)
238end
239
240------------------------------------------------------------------------
241-- returns current 'pc' and marks it as a jump target (to avoid wrong
242-- optimizations with consecutive instructions not in the same basic block).
243-- * used in multiple locations
244-- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
245------------------------------------------------------------------------
246function luaK:getlabel(fs)
247 fs.lasttarget = fs.pc
248 return fs.pc
249end
250
251------------------------------------------------------------------------
252--
253-- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
254-- luaK:concat()
255------------------------------------------------------------------------
256function luaK:getjump(fs, pc)
257 local offset = luaP:GETARG_sBx(fs.f.code[pc])
258 if offset == self.NO_JUMP then -- point to itself represents end of list
259 return self.NO_JUMP -- end of list
260 else
261 return (pc + 1) + offset -- turn offset into absolute position
262 end
263end
264
265------------------------------------------------------------------------
266--
267-- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
268------------------------------------------------------------------------
269function luaK:getjumpcontrol(fs, pc)
270 local pi = fs.f.code[pc]
271 local ppi = fs.f.code[pc - 1]
272 if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
273 return ppi
274 else
275 return pi
276 end
277end
278
279------------------------------------------------------------------------
280-- check whether list has any jump that do not produce a value
281-- (or produce an inverted value)
282-- * return value changed to boolean
283-- * used only in luaK:exp2reg()
284------------------------------------------------------------------------
285function luaK:need_value(fs, list)
286 while list ~= self.NO_JUMP do
287 local i = self:getjumpcontrol(fs, list)
288 if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end
289 list = self:getjump(fs, list)
290 end
291 return false -- not found
292end
293
294------------------------------------------------------------------------
295--
296-- * used in luaK:removevalues(), luaK:patchlistaux()
297------------------------------------------------------------------------
298function luaK:patchtestreg(fs, node, reg)
299 local i = self:getjumpcontrol(fs, node)
300 if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
301 return false -- cannot patch other instructions
302 end
303 if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
304 luaP:SETARG_A(i, reg)
305 else -- no register to put value or register already has the value
306 -- due to use of a table as i, i cannot be replaced by another table
307 -- so the following is required; there is no change to ARG_C
308 luaP:SET_OPCODE(i, "OP_TEST")
309 local b = luaP:GETARG_B(i)
310 luaP:SETARG_A(i, b)
311 luaP:SETARG_B(i, 0)
312 -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
313 end
314 return true
315end
316
317------------------------------------------------------------------------
318--
319-- * used only in luaK:codenot()
320------------------------------------------------------------------------
321function luaK:removevalues(fs, list)
322 while list ~= self.NO_JUMP do
323 self:patchtestreg(fs, list, luaP.NO_REG)
324 list = self:getjump(fs, list)
325 end
326end
327
328------------------------------------------------------------------------
329--
330-- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
331------------------------------------------------------------------------
332function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
333 while list ~= self.NO_JUMP do
334 local _next = self:getjump(fs, list)
335 if self:patchtestreg(fs, list, reg) then
336 self:fixjump(fs, list, vtarget)
337 else
338 self:fixjump(fs, list, dtarget) -- jump to default target
339 end
340 list = _next
341 end
342end
343
344------------------------------------------------------------------------
345--
346-- * used only in luaK:code()
347------------------------------------------------------------------------
348function luaK:dischargejpc(fs)
349 self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
350 fs.jpc = self.NO_JUMP
351end
352
353------------------------------------------------------------------------
354--
355-- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
356------------------------------------------------------------------------
357function luaK:patchlist(fs, list, target)
358 if target == fs.pc then
359 self:patchtohere(fs, list)
360 else
361 lua_assert(target < fs.pc)
362 self:patchlistaux(fs, list, target, luaP.NO_REG, target)
363 end
364end
365
366------------------------------------------------------------------------
367--
368-- * used in multiple locations
369------------------------------------------------------------------------
370function luaK:patchtohere(fs, list)
371 self:getlabel(fs)
372 fs.jpc = self:concat(fs, fs.jpc, list)
373end
374
375------------------------------------------------------------------------
376-- * l1 was a pointer, now l1 is returned and callee assigns the value
377-- * used in multiple locations
378------------------------------------------------------------------------
379function luaK:concat(fs, l1, l2)
380 if l2 == self.NO_JUMP then return l1
381 elseif l1 == self.NO_JUMP then
382 return l2
383 else
384 local list = l1
385 local _next = self:getjump(fs, list)
386 while _next ~= self.NO_JUMP do -- find last element
387 list = _next
388 _next = self:getjump(fs, list)
389 end
390 self:fixjump(fs, list, l2)
391 end
392 return l1
393end
394
395------------------------------------------------------------------------
396--
397-- * used in luaK:reserveregs(), (lparser) luaY:forlist()
398------------------------------------------------------------------------
399function luaK:checkstack(fs, n)
400 local newstack = fs.freereg + n
401 if newstack > fs.f.maxstacksize then
402 if newstack >= self.MAXSTACK then
403 luaX:syntaxerror(fs.ls, "function or expression too complex")
404 end
405 fs.f.maxstacksize = newstack
406 end
407end
408
409------------------------------------------------------------------------
410--
411-- * used in multiple locations
412------------------------------------------------------------------------
413function luaK:reserveregs(fs, n)
414 self:checkstack(fs, n)
415 fs.freereg = fs.freereg + n
416end
417
418------------------------------------------------------------------------
419--
420-- * used in luaK:freeexp(), luaK:dischargevars()
421------------------------------------------------------------------------
422function luaK:freereg(fs, reg)
423 if not luaP:ISK(reg) and reg >= fs.nactvar then
424 fs.freereg = fs.freereg - 1
425 lua_assert(reg == fs.freereg)
426 end
427end
428
429------------------------------------------------------------------------
430--
431-- * used in multiple locations
432------------------------------------------------------------------------
433function luaK:freeexp(fs, e)
434 if e.k == "VNONRELOC" then
435 self:freereg(fs, e.info)
436 end
437end
438
439------------------------------------------------------------------------
440-- * TODO NOTE implementation is not 100% correct, since the assert fails
441-- * luaH_set, setobj deleted; direct table access used instead
442-- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
443------------------------------------------------------------------------
444function luaK:addk(fs, k, v)
445 local L = fs.L
446 local idx = fs.h[k.value]
447 --TValue *idx = luaH_set(L, fs->h, k); /* C */
448 local f = fs.f
449 if self:ttisnumber(idx) then
450 --TODO this assert currently FAILS (last tested for 5.0.2)
451 --lua_assert(fs.f.k[self:nvalue(idx)] == v)
452 --lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
453 return self:nvalue(idx)
454 else -- constant not found; create a new entry
455 idx = {}
456 self:setnvalue(idx, fs.nk)
457 fs.h[k.value] = idx
458 -- setnvalue(idx, cast_num(fs->nk)); /* C */
459 luaY:growvector(L, f.k, fs.nk, f.sizek, nil,
460 luaP.MAXARG_Bx, "constant table overflow")
461 -- loop to initialize empty f.k positions not required
462 f.k[fs.nk] = v
463 -- setobj(L, &f->k[fs->nk], v); /* C */
464 -- luaC_barrier(L, f, v); /* GC */
465 local nk = fs.nk
466 fs.nk = fs.nk + 1
467 return nk
468 end
469
470end
471
472------------------------------------------------------------------------
473-- creates and sets a string object
474-- * used in (lparser) luaY:codestring(), luaY:singlevar()
475------------------------------------------------------------------------
476function luaK:stringK(fs, s)
477 local o = {} -- TValue
478 self:setsvalue(o, s)
479 return self:addk(fs, o, o)
480end
481
482------------------------------------------------------------------------
483-- creates and sets a number object
484-- * used in luaK:prefix() for negative (or negation of) numbers
485-- * used in (lparser) luaY:simpleexp(), luaY:fornum()
486------------------------------------------------------------------------
487function luaK:numberK(fs, r)
488 local o = {} -- TValue
489 self:setnvalue(o, r)
490 return self:addk(fs, o, o)
491end
492
493------------------------------------------------------------------------
494-- creates and sets a boolean object
495-- * used only in luaK:exp2RK()
496------------------------------------------------------------------------
497function luaK:boolK(fs, b)
498 local o = {} -- TValue
499 self:setbvalue(o, b)
500 return self:addk(fs, o, o)
501end
502
503------------------------------------------------------------------------
504-- creates and sets a nil object
505-- * used only in luaK:exp2RK()
506------------------------------------------------------------------------
507function luaK:nilK(fs)
508 local k, v = {}, {} -- TValue
509 self:setnilvalue(v)
510 -- cannot use nil as key; instead use table itself to represent nil
511 self:sethvalue(k, fs.h)
512 return self:addk(fs, k, v)
513end
514
515------------------------------------------------------------------------
516--
517-- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
518------------------------------------------------------------------------
519function luaK:setreturns(fs, e, nresults)
520 if e.k == "VCALL" then -- expression is an open function call?
521 luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
522 elseif e.k == "VVARARG" then
523 luaP:SETARG_B(self:getcode(fs, e), nresults + 1);
524 luaP:SETARG_A(self:getcode(fs, e), fs.freereg);
525 luaK:reserveregs(fs, 1)
526 end
527end
528
529------------------------------------------------------------------------
530--
531-- * used in luaK:dischargevars(), (lparser) luaY:assignment()
532------------------------------------------------------------------------
533function luaK:setoneret(fs, e)
534 if e.k == "VCALL" then -- expression is an open function call?
535 e.k = "VNONRELOC"
536 e.info = luaP:GETARG_A(self:getcode(fs, e))
537 elseif e.k == "VVARARG" then
538 luaP:SETARG_B(self:getcode(fs, e), 2)
539 e.k = "VRELOCABLE" -- can relocate its simple result
540 end
541end
542
543------------------------------------------------------------------------
544--
545-- * used in multiple locations
546------------------------------------------------------------------------
547function luaK:dischargevars(fs, e)
548 local k = e.k
549 if k == "VLOCAL" then
550 e.k = "VNONRELOC"
551 elseif k == "VUPVAL" then
552 e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
553 e.k = "VRELOCABLE"
554 elseif k == "VGLOBAL" then
555 e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
556 e.k = "VRELOCABLE"
557 elseif k == "VINDEXED" then
558 self:freereg(fs, e.aux)
559 self:freereg(fs, e.info)
560 e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
561 e.k = "VRELOCABLE"
562 elseif k == "VVARARG" or k == "VCALL" then
563 self:setoneret(fs, e)
564 else
565 -- there is one value available (somewhere)
566 end
567end
568
569------------------------------------------------------------------------
570--
571-- * used only in luaK:exp2reg()
572------------------------------------------------------------------------
573function luaK:code_label(fs, A, b, jump)
574 self:getlabel(fs) -- those instructions may be jump targets
575 return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
576end
577
578------------------------------------------------------------------------
579--
580-- * used in luaK:discharge2anyreg(), luaK:exp2reg()
581------------------------------------------------------------------------
582function luaK:discharge2reg(fs, e, reg)
583 self:dischargevars(fs, e)
584 local k = e.k
585 if k == "VNIL" then
586 self:_nil(fs, reg, 1)
587 elseif k == "VFALSE" or k == "VTRUE" then
588 self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
589 elseif k == "VK" then
590 self:codeABx(fs, "OP_LOADK", reg, e.info)
591 elseif k == "VKNUM" then
592 self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
593 elseif k == "VRELOCABLE" then
594 local pc = self:getcode(fs, e)
595 luaP:SETARG_A(pc, reg)
596 elseif k == "VNONRELOC" then
597 if reg ~= e.info then
598 self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
599 end
600 else
601 lua_assert(e.k == "VVOID" or e.k == "VJMP")
602 return -- nothing to do...
603 end
604 e.info = reg
605 e.k = "VNONRELOC"
606end
607
608------------------------------------------------------------------------
609--
610-- * used in luaK:jumponcond(), luaK:codenot()
611------------------------------------------------------------------------
612function luaK:discharge2anyreg(fs, e)
613 if e.k ~= "VNONRELOC" then
614 self:reserveregs(fs, 1)
615 self:discharge2reg(fs, e, fs.freereg - 1)
616 end
617end
618
619------------------------------------------------------------------------
620--
621-- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
622------------------------------------------------------------------------
623function luaK:exp2reg(fs, e, reg)
624 self:discharge2reg(fs, e, reg)
625 if e.k == "VJMP" then
626 e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
627 end
628 if self:hasjumps(e) then
629 local final -- position after whole expression
630 local p_f = self.NO_JUMP -- position of an eventual LOAD false
631 local p_t = self.NO_JUMP -- position of an eventual LOAD true
632 if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
633 local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
634 p_f = self:code_label(fs, reg, 0, 1)
635 p_t = self:code_label(fs, reg, 1, 0)
636 self:patchtohere(fs, fj)
637 end
638 final = self:getlabel(fs)
639 self:patchlistaux(fs, e.f, final, reg, p_f)
640 self:patchlistaux(fs, e.t, final, reg, p_t)
641 end
642 e.f, e.t = self.NO_JUMP, self.NO_JUMP
643 e.info = reg
644 e.k = "VNONRELOC"
645end
646
647------------------------------------------------------------------------
648--
649-- * used in multiple locations
650------------------------------------------------------------------------
651function luaK:exp2nextreg(fs, e)
652 self:dischargevars(fs, e)
653 self:freeexp(fs, e)
654 self:reserveregs(fs, 1)
655 self:exp2reg(fs, e, fs.freereg - 1)
656end
657
658------------------------------------------------------------------------
659--
660-- * used in multiple locations
661------------------------------------------------------------------------
662function luaK:exp2anyreg(fs, e)
663 self:dischargevars(fs, e)
664 if e.k == "VNONRELOC" then
665 if not self:hasjumps(e) then -- exp is already in a register
666 return e.info
667 end
668 if e.info >= fs.nactvar then -- reg. is not a local?
669 self:exp2reg(fs, e, e.info) -- put value on it
670 return e.info
671 end
672 end
673 self:exp2nextreg(fs, e) -- default
674 return e.info
675end
676
677------------------------------------------------------------------------
678--
679-- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
680-- * used in (lparser) luaY:yindex()
681------------------------------------------------------------------------
682function luaK:exp2val(fs, e)
683 if self:hasjumps(e) then
684 self:exp2anyreg(fs, e)
685 else
686 self:dischargevars(fs, e)
687 end
688end
689
690------------------------------------------------------------------------
691--
692-- * used in multiple locations
693------------------------------------------------------------------------
694function luaK:exp2RK(fs, e)
695 self:exp2val(fs, e)
696 local k = e.k
697 if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
698 if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand?
699 -- converted from a 2-deep ternary operator expression
700 if e.k == "VNIL" then
701 e.info = self:nilK(fs)
702 else
703 e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval)
704 or self:boolK(fs, e.k == "VTRUE")
705 end
706 e.k = "VK"
707 return luaP:RKASK(e.info)
708 end
709 elseif k == "VK" then
710 if e.info <= luaP.MAXINDEXRK then -- constant fit in argC?
711 return luaP:RKASK(e.info)
712 end
713 else
714 -- default
715 end
716 -- not a constant in the right range: put it in a register
717 return self:exp2anyreg(fs, e)
718end
719
720------------------------------------------------------------------------
721--
722-- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
723------------------------------------------------------------------------
724function luaK:storevar(fs, var, ex)
725 local k = var.k
726 if k == "VLOCAL" then
727 self:freeexp(fs, ex)
728 self:exp2reg(fs, ex, var.info)
729 return
730 elseif k == "VUPVAL" then
731 local e = self:exp2anyreg(fs, ex)
732 self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
733 elseif k == "VGLOBAL" then
734 local e = self:exp2anyreg(fs, ex)
735 self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
736 elseif k == "VINDEXED" then
737 local e = self:exp2RK(fs, ex)
738 self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
739 else
740 lua_assert(0) -- invalid var kind to store
741 end
742 self:freeexp(fs, ex)
743end
744
745------------------------------------------------------------------------
746--
747-- * used only in (lparser) luaY:primaryexp()
748------------------------------------------------------------------------
749function luaK:_self(fs, e, key)
750 self:exp2anyreg(fs, e)
751 self:freeexp(fs, e)
752 local func = fs.freereg
753 self:reserveregs(fs, 2)
754 self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
755 self:freeexp(fs, key)
756 e.info = func
757 e.k = "VNONRELOC"
758end
759
760------------------------------------------------------------------------
761--
762-- * used in luaK:goiftrue(), luaK:codenot()
763------------------------------------------------------------------------
764function luaK:invertjump(fs, e)
765 local pc = self:getjumpcontrol(fs, e.info)
766 lua_assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and
767 luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and
768 luaP:GET_OPCODE(pc) ~= "OP_TEST")
769 luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
770end
771
772------------------------------------------------------------------------
773--
774-- * used in luaK:goiftrue(), luaK:goiffalse()
775------------------------------------------------------------------------
776function luaK:jumponcond(fs, e, cond)
777 if e.k == "VRELOCABLE" then
778 local ie = self:getcode(fs, e)
779 if luaP:GET_OPCODE(ie) == "OP_NOT" then
780 fs.pc = fs.pc - 1 -- remove previous OP_NOT
781 return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
782 end
783 -- else go through
784 end
785 self:discharge2anyreg(fs, e)
786 self:freeexp(fs, e)
787 return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
788end
789
790------------------------------------------------------------------------
791--
792-- * used in luaK:infix(), (lparser) luaY:cond()
793------------------------------------------------------------------------
794function luaK:goiftrue(fs, e)
795 local pc -- pc of last jump
796 self:dischargevars(fs, e)
797 local k = e.k
798 if k == "VK" or k == "VKNUM" or k == "VTRUE" then
799 pc = self.NO_JUMP -- always true; do nothing
800 elseif k == "VFALSE" then
801 pc = self:jump(fs) -- always jump
802 elseif k == "VJMP" then
803 self:invertjump(fs, e)
804 pc = e.info
805 else
806 pc = self:jumponcond(fs, e, false)
807 end
808 e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list
809 self:patchtohere(fs, e.t)
810 e.t = self.NO_JUMP
811end
812
813------------------------------------------------------------------------
814--
815-- * used in luaK:infix()
816------------------------------------------------------------------------
817function luaK:goiffalse(fs, e)
818 local pc -- pc of last jump
819 self:dischargevars(fs, e)
820 local k = e.k
821 if k == "VNIL" or k == "VFALSE"then
822 pc = self.NO_JUMP -- always false; do nothing
823 elseif k == "VTRUE" then
824 pc = self:jump(fs) -- always jump
825 elseif k == "VJMP" then
826 pc = e.info
827 else
828 pc = self:jumponcond(fs, e, true)
829 end
830 e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list
831 self:patchtohere(fs, e.f)
832 e.f = self.NO_JUMP
833end
834
835------------------------------------------------------------------------
836--
837-- * used only in luaK:prefix()
838------------------------------------------------------------------------
839function luaK:codenot(fs, e)
840 self:dischargevars(fs, e)
841 local k = e.k
842 if k == "VNIL" or k == "VFALSE" then
843 e.k = "VTRUE"
844 elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
845 e.k = "VFALSE"
846 elseif k == "VJMP" then
847 self:invertjump(fs, e)
848 elseif k == "VRELOCABLE" or k == "VNONRELOC" then
849 self:discharge2anyreg(fs, e)
850 self:freeexp(fs, e)
851 e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
852 e.k = "VRELOCABLE"
853 else
854 lua_assert(0) -- cannot happen
855 end
856 -- interchange true and false lists
857 e.f, e.t = e.t, e.f
858 self:removevalues(fs, e.f)
859 self:removevalues(fs, e.t)
860end
861
862------------------------------------------------------------------------
863--
864-- * used in (lparser) luaY:field(), luaY:primaryexp()
865------------------------------------------------------------------------
866function luaK:indexed(fs, t, k)
867 t.aux = self:exp2RK(fs, k)
868 t.k = "VINDEXED"
869end
870
871------------------------------------------------------------------------
872--
873-- * used only in luaK:codearith()
874------------------------------------------------------------------------
875function luaK:constfolding(op, e1, e2)
876 local r
877 if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end
878 local v1 = e1.nval
879 local v2 = e2.nval
880 if op == "OP_ADD" then
881 r = self:numadd(v1, v2)
882 elseif op == "OP_SUB" then
883 r = self:numsub(v1, v2)
884 elseif op == "OP_MUL" then
885 r = self:nummul(v1, v2)
886 elseif op == "OP_DIV" then
887 if v2 == 0 then return false end -- do not attempt to divide by 0
888 r = self:numdiv(v1, v2)
889 elseif op == "OP_MOD" then
890 if v2 == 0 then return false end -- do not attempt to divide by 0
891 r = self:nummod(v1, v2)
892 elseif op == "OP_POW" then
893 r = self:numpow(v1, v2)
894 elseif op == "OP_UNM" then
895 r = self:numunm(v1)
896 elseif op == "OP_LEN" then
897 return false -- no constant folding for 'len'
898 else
899 lua_assert(0)
900 r = 0
901 end
902 if self:numisnan(r) then return false end -- do not attempt to produce NaN
903 e1.nval = r
904 return true
905end
906
907------------------------------------------------------------------------
908--
909-- * used in luaK:prefix(), luaK:posfix()
910------------------------------------------------------------------------
911function luaK:codearith(fs, op, e1, e2)
912 if self:constfolding(op, e1, e2) then
913 return
914 else
915 local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
916 local o1 = self:exp2RK(fs, e1)
917 if o1 > o2 then
918 self:freeexp(fs, e1)
919 self:freeexp(fs, e2)
920 else
921 self:freeexp(fs, e2)
922 self:freeexp(fs, e1)
923 end
924 e1.info = self:codeABC(fs, op, 0, o1, o2)
925 e1.k = "VRELOCABLE"
926 end
927end
928
929------------------------------------------------------------------------
930--
931-- * used only in luaK:posfix()
932------------------------------------------------------------------------
933function luaK:codecomp(fs, op, cond, e1, e2)
934 local o1 = self:exp2RK(fs, e1)
935 local o2 = self:exp2RK(fs, e2)
936 self:freeexp(fs, e2)
937 self:freeexp(fs, e1)
938 if cond == 0 and op ~= "OP_EQ" then
939 -- exchange args to replace by `<' or `<='
940 o1, o2 = o2, o1 -- o1 <==> o2
941 cond = 1
942 end
943 e1.info = self:condjump(fs, op, cond, o1, o2)
944 e1.k = "VJMP"
945end
946
947------------------------------------------------------------------------
948--
949-- * used only in (lparser) luaY:subexpr()
950------------------------------------------------------------------------
951function luaK:prefix(fs, op, e)
952 local e2 = {} -- expdesc
953 e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
954 e2.k = "VKNUM"
955 e2.nval = 0
956 if op == "OPR_MINUS" then
957 if not self:isnumeral(e) then
958 self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants
959 end
960 self:codearith(fs, "OP_UNM", e, e2)
961 elseif op == "OPR_NOT" then
962 self:codenot(fs, e)
963 elseif op == "OPR_LEN" then
964 self:exp2anyreg(fs, e) -- cannot operate on constants
965 self:codearith(fs, "OP_LEN", e, e2)
966 else
967 lua_assert(0)
968 end
969end
970
971------------------------------------------------------------------------
972--
973-- * used only in (lparser) luaY:subexpr()
974------------------------------------------------------------------------
975function luaK:infix(fs, op, v)
976 if op == "OPR_AND" then
977 self:goiftrue(fs, v)
978 elseif op == "OPR_OR" then
979 self:goiffalse(fs, v)
980 elseif op == "OPR_CONCAT" then
981 self:exp2nextreg(fs, v) -- operand must be on the 'stack'
982 elseif op == "OPR_ADD" or op == "OPR_SUB" or
983 op == "OPR_MUL" or op == "OPR_DIV" or
984 op == "OPR_MOD" or op == "OPR_POW" then
985 if not self:isnumeral(v) then self:exp2RK(fs, v) end
986 else
987 self:exp2RK(fs, v)
988 end
989end
990
991------------------------------------------------------------------------
992--
993-- * used only in (lparser) luaY:subexpr()
994------------------------------------------------------------------------
995-- table lookups to simplify testing
996luaK.arith_op = {
997 OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL",
998 OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW",
999}
1000luaK.comp_op = {
1001 OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT",
1002 OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE",
1003}
1004luaK.comp_cond = {
1005 OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1,
1006 OPR_LE = 1, OPR_GT = 0, OPR_GE = 0,
1007}
1008function luaK:posfix(fs, op, e1, e2)
1009 -- needed because e1 = e2 doesn't copy values...
1010 -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
1011 -- but here, all elements are copied for completeness' sake
1012 local function copyexp(e1, e2)
1013 e1.k = e2.k
1014 e1.info = e2.info; e1.aux = e2.aux
1015 e1.nval = e2.nval
1016 e1.t = e2.t; e1.f = e2.f
1017 end
1018 if op == "OPR_AND" then
1019 lua_assert(e1.t == self.NO_JUMP) -- list must be closed
1020 self:dischargevars(fs, e2)
1021 e2.f = self:concat(fs, e2.f, e1.f)
1022 copyexp(e1, e2)
1023 elseif op == "OPR_OR" then
1024 lua_assert(e1.f == self.NO_JUMP) -- list must be closed
1025 self:dischargevars(fs, e2)
1026 e2.t = self:concat(fs, e2.t, e1.t)
1027 copyexp(e1, e2)
1028 elseif op == "OPR_CONCAT" then
1029 self:exp2val(fs, e2)
1030 if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
1031 lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
1032 self:freeexp(fs, e1)
1033 luaP:SETARG_B(self:getcode(fs, e2), e1.info)
1034 e1.k = "VRELOCABLE"
1035 e1.info = e2.info
1036 else
1037 self:exp2nextreg(fs, e2) -- operand must be on the 'stack'
1038 self:codearith(fs, "OP_CONCAT", e1, e2)
1039 end
1040 else
1041 -- the following uses a table lookup in place of conditionals
1042 local arith = self.arith_op[op]
1043 if arith then
1044 self:codearith(fs, arith, e1, e2)
1045 else
1046 local comp = self.comp_op[op]
1047 if comp then
1048 self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
1049 else
1050 lua_assert(0)
1051 end
1052 end--if arith
1053 end--if op
1054end
1055
1056------------------------------------------------------------------------
1057-- adjusts debug information for last instruction written, in order to
1058-- change the line where item comes into existence
1059-- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
1060------------------------------------------------------------------------
1061function luaK:fixline(fs, line)
1062 fs.f.lineinfo[fs.pc - 1] = line
1063end
1064
1065------------------------------------------------------------------------
1066-- general function to write an instruction into the instruction buffer,
1067-- sets debug information too
1068-- * used in luaK:codeABC(), luaK:codeABx()
1069-- * called directly by (lparser) luaY:whilestat()
1070------------------------------------------------------------------------
1071function luaK:code(fs, i, line)
1072 local f = fs.f
1073 self:dischargejpc(fs) -- 'pc' will change
1074 -- put new instruction in code array
1075 luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
1076 luaY.MAX_INT, "code size overflow")
1077 f.code[fs.pc] = i
1078 -- save corresponding line information
1079 luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
1080 luaY.MAX_INT, "code size overflow")
1081 f.lineinfo[fs.pc] = line
1082 local pc = fs.pc
1083 fs.pc = fs.pc + 1
1084 return pc
1085end
1086
1087------------------------------------------------------------------------
1088-- writes an instruction of type ABC
1089-- * calls luaK:code()
1090------------------------------------------------------------------------
1091function luaK:codeABC(fs, o, a, b, c)
1092 lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
1093 lua_assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
1094 lua_assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
1095 return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
1096end
1097
1098------------------------------------------------------------------------
1099-- writes an instruction of type ABx
1100-- * calls luaK:code(), called by luaK:codeAsBx()
1101------------------------------------------------------------------------
1102function luaK:codeABx(fs, o, a, bc)
1103 lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABx or
1104 luaP:getOpMode(o) == luaP.OpMode.iAsBx)
1105 lua_assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
1106 return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
1107end
1108
1109------------------------------------------------------------------------
1110--
1111-- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
1112------------------------------------------------------------------------
1113function luaK:setlist(fs, base, nelems, tostore)
1114 local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1
1115 local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
1116 lua_assert(tostore ~= 0)
1117 if c <= luaP.MAXARG_C then
1118 self:codeABC(fs, "OP_SETLIST", base, b, c)
1119 else
1120 self:codeABC(fs, "OP_SETLIST", base, b, 0)
1121 self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
1122 end
1123 fs.freereg = base + 1 -- free registers with list values
1124end
1125
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua
new file mode 100644
index 0000000..b9380e1
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/ldump.lua
@@ -0,0 +1,372 @@
1--[[--------------------------------------------------------------------
2
3 ldump.lua
4 Save precompiled Lua chunks
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * WARNING! byte order (little endian) and data type sizes for header
18-- signature values hard-coded; see luaU:header
19-- * chunk writer generators are included, see below
20-- * one significant difference is that instructions are still in table
21-- form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to
22-- convert them into 4-char strings
23--
24-- Not implemented:
25-- * DumpVar, DumpMem has been removed
26-- * DumpVector folded into folded into DumpDebug, DumpCode
27--
28-- Added:
29-- * for convenience, the following two functions have been added:
30-- luaU:make_setS: create a chunk writer that writes to a string
31-- luaU:make_setF: create a chunk writer that writes to a file
32-- (lua.h contains a typedef for lua_Writer/lua_Chunkwriter, and
33-- a Lua-based implementation exists, writer() in lstrlib.c)
34-- * luaU:ttype(o) (from lobject.h)
35-- * for converting number types to its binary equivalent:
36-- luaU:from_double(x): encode double value for writing
37-- luaU:from_int(x): encode integer value for writing
38-- (error checking is limited for these conversion functions)
39-- (double conversion does not support denormals or NaNs)
40--
41-- Changed in 5.1.x:
42-- * the dumper was mostly rewritten in Lua 5.1.x, so notes on the
43-- differences between 5.0.x and 5.1.x is limited
44-- * LUAC_VERSION bumped to 0x51, LUAC_FORMAT added
45-- * developer is expected to adjust LUAC_FORMAT in order to identify
46-- non-standard binary chunk formats
47-- * header signature code is smaller, has been simplified, and is
48-- tested as a single unit; its logic is shared with the undumper
49-- * no more endian conversion, invalid endianness mean rejection
50-- * opcode field sizes are no longer exposed in the header
51-- * code moved to front of a prototype, followed by constants
52-- * debug information moved to the end of the binary chunk, and the
53-- relevant functions folded into a single function
54-- * luaU:dump returns a writer status code
55-- * chunk writer now implements status code because dumper uses it
56-- * luaU:endianness removed
57----------------------------------------------------------------------]]
58
59--requires luaP
60luaU = {}
61
62-- mark for precompiled code ('<esc>Lua') (from lua.h)
63luaU.LUA_SIGNATURE = "\27Lua"
64
65-- constants used by dumper (from lua.h)
66luaU.LUA_TNUMBER = 3
67luaU.LUA_TSTRING = 4
68luaU.LUA_TNIL = 0
69luaU.LUA_TBOOLEAN = 1
70luaU.LUA_TNONE = -1
71
72-- constants for header of binary files (from lundump.h)
73luaU.LUAC_VERSION = 0x51 -- this is Lua 5.1
74luaU.LUAC_FORMAT = 0 -- this is the official format
75luaU.LUAC_HEADERSIZE = 12 -- size of header of binary files
76
77--[[--------------------------------------------------------------------
78-- Additional functions to handle chunk writing
79-- * to use make_setS and make_setF, see test_ldump.lua elsewhere
80----------------------------------------------------------------------]]
81
82------------------------------------------------------------------------
83-- create a chunk writer that writes to a string
84-- * returns the writer function and a table containing the string
85-- * to get the final result, look in buff.data
86------------------------------------------------------------------------
87function luaU:make_setS()
88 local buff = {}
89 buff.data = ""
90 local writer =
91 function(s, buff) -- chunk writer
92 if not s then return 0 end
93 buff.data = buff.data..s
94 return 0
95 end
96 return writer, buff
97end
98
99------------------------------------------------------------------------
100-- create a chunk writer that writes to a file
101-- * returns the writer function and a table containing the file handle
102-- * if a nil is passed, then writer should close the open file
103------------------------------------------------------------------------
104function luaU:make_setF(filename)
105 local buff = {}
106 buff.h = io.open(filename, "wb")
107 if not buff.h then return nil end
108 local writer =
109 function(s, buff) -- chunk writer
110 if not buff.h then return 0 end
111 if not s then
112 if buff.h:close() then return 0 end
113 else
114 if buff.h:write(s) then return 0 end
115 end
116 return 1
117 end
118 return writer, buff
119end
120
121------------------------------------------------------------------------
122-- works like the lobject.h version except that TObject used in these
123-- scripts only has a 'value' field, no 'tt' field (native types used)
124------------------------------------------------------------------------
125function luaU:ttype(o)
126 local tt = type(o.value)
127 if tt == "number" then return self.LUA_TNUMBER
128 elseif tt == "string" then return self.LUA_TSTRING
129 elseif tt == "nil" then return self.LUA_TNIL
130 elseif tt == "boolean" then return self.LUA_TBOOLEAN
131 else
132 return self.LUA_TNONE -- the rest should not appear
133 end
134end
135
136-----------------------------------------------------------------------
137-- converts a IEEE754 double number to an 8-byte little-endian string
138-- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake
139-- * supports +/- Infinity, but not denormals or NaNs
140-----------------------------------------------------------------------
141function luaU:from_double(x)
142 local function grab_byte(v)
143 local c = v % 256
144 return (v - c) / 256, string.char(c)
145 end
146 local sign = 0
147 if x < 0 then sign = 1; x = -x end
148 local mantissa, exponent = math.frexp(x)
149 if x == 0 then -- zero
150 mantissa, exponent = 0, 0
151 elseif x == 1/0 then
152 mantissa, exponent = 0, 2047
153 else
154 mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53)
155 exponent = exponent + 1022
156 end
157 local v, byte = "" -- convert to bytes
158 x = math.floor(mantissa)
159 for i = 1,6 do
160 x, byte = grab_byte(x); v = v..byte -- 47:0
161 end
162 x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48
163 x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56
164 return v
165end
166
167-----------------------------------------------------------------------
168-- converts a number to a little-endian 32-bit integer string
169-- * input value assumed to not overflow, can be signed/unsigned
170-----------------------------------------------------------------------
171function luaU:from_int(x)
172 local v = ""
173 x = math.floor(x)
174 if x < 0 then x = 4294967296 + x end -- ULONG_MAX+1
175 for i = 1, 4 do
176 local c = x % 256
177 v = v..string.char(c); x = math.floor(x / 256)
178 end
179 return v
180end
181
182--[[--------------------------------------------------------------------
183-- Functions to make a binary chunk
184-- * many functions have the size parameter removed, since output is
185-- in the form of a string and some sizes are implicit or hard-coded
186----------------------------------------------------------------------]]
187
188--[[--------------------------------------------------------------------
189-- struct DumpState:
190-- L -- lua_State (not used in this script)
191-- writer -- lua_Writer (chunk writer function)
192-- data -- void* (chunk writer context or data already written)
193-- strip -- if true, don't write any debug information
194-- status -- if non-zero, an error has occured
195----------------------------------------------------------------------]]
196
197------------------------------------------------------------------------
198-- dumps a block of bytes
199-- * lua_unlock(D.L), lua_lock(D.L) unused
200------------------------------------------------------------------------
201function luaU:DumpBlock(b, D)
202 if D.status == 0 then
203 -- lua_unlock(D->L);
204 D.status = D.write(b, D.data)
205 -- lua_lock(D->L);
206 end
207end
208
209------------------------------------------------------------------------
210-- dumps a char
211------------------------------------------------------------------------
212function luaU:DumpChar(y, D)
213 self:DumpBlock(string.char(y), D)
214end
215
216------------------------------------------------------------------------
217-- dumps a 32-bit signed or unsigned integer (for int) (hard-coded)
218------------------------------------------------------------------------
219function luaU:DumpInt(x, D)
220 self:DumpBlock(self:from_int(x), D)
221end
222
223------------------------------------------------------------------------
224-- dumps a lua_Number (hard-coded as a double)
225------------------------------------------------------------------------
226function luaU:DumpNumber(x, D)
227 self:DumpBlock(self:from_double(x), D)
228end
229
230------------------------------------------------------------------------
231-- dumps a Lua string (size type is hard-coded)
232------------------------------------------------------------------------
233function luaU:DumpString(s, D)
234 if s == nil then
235 self:DumpInt(0, D)
236 else
237 s = s.."\0" -- include trailing '\0'
238 self:DumpInt(#s, D)
239 self:DumpBlock(s, D)
240 end
241end
242
243------------------------------------------------------------------------
244-- dumps instruction block from function prototype
245------------------------------------------------------------------------
246function luaU:DumpCode(f, D)
247 local n = f.sizecode
248 --was DumpVector
249 self:DumpInt(n, D)
250 for i = 0, n - 1 do
251 self:DumpBlock(luaP:Instruction(f.code[i]), D)
252 end
253end
254
255------------------------------------------------------------------------
256-- dump constant pool from function prototype
257-- * bvalue(o), nvalue(o) and rawtsvalue(o) macros removed
258------------------------------------------------------------------------
259function luaU:DumpConstants(f, D)
260 local n = f.sizek
261 self:DumpInt(n, D)
262 for i = 0, n - 1 do
263 local o = f.k[i] -- TValue
264 local tt = self:ttype(o)
265 self:DumpChar(tt, D)
266 if tt == self.LUA_TNIL then
267 elseif tt == self.LUA_TBOOLEAN then
268 self:DumpChar(o.value and 1 or 0, D)
269 elseif tt == self.LUA_TNUMBER then
270 self:DumpNumber(o.value, D)
271 elseif tt == self.LUA_TSTRING then
272 self:DumpString(o.value, D)
273 else
274 --lua_assert(0) -- cannot happen
275 end
276 end
277 n = f.sizep
278 self:DumpInt(n, D)
279 for i = 0, n - 1 do
280 self:DumpFunction(f.p[i], f.source, D)
281 end
282end
283
284------------------------------------------------------------------------
285-- dump debug information
286------------------------------------------------------------------------
287function luaU:DumpDebug(f, D)
288 local n
289 n = D.strip and 0 or f.sizelineinfo -- dump line information
290 --was DumpVector
291 self:DumpInt(n, D)
292 for i = 0, n - 1 do
293 self:DumpInt(f.lineinfo[i], D)
294 end
295 n = D.strip and 0 or f.sizelocvars -- dump local information
296 self:DumpInt(n, D)
297 for i = 0, n - 1 do
298 self:DumpString(f.locvars[i].varname, D)
299 self:DumpInt(f.locvars[i].startpc, D)
300 self:DumpInt(f.locvars[i].endpc, D)
301 end
302 n = D.strip and 0 or f.sizeupvalues -- dump upvalue information
303 self:DumpInt(n, D)
304 for i = 0, n - 1 do
305 self:DumpString(f.upvalues[i], D)
306 end
307end
308
309------------------------------------------------------------------------
310-- dump child function prototypes from function prototype
311------------------------------------------------------------------------
312function luaU:DumpFunction(f, p, D)
313 local source = f.source
314 if source == p or D.strip then source = nil end
315 self:DumpString(source, D)
316 self:DumpInt(f.lineDefined, D)
317 self:DumpInt(f.lastlinedefined, D)
318 self:DumpChar(f.nups, D)
319 self:DumpChar(f.numparams, D)
320 self:DumpChar(f.is_vararg, D)
321 self:DumpChar(f.maxstacksize, D)
322 self:DumpCode(f, D)
323 self:DumpConstants(f, D)
324 self:DumpDebug(f, D)
325end
326
327------------------------------------------------------------------------
328-- dump Lua header section (some sizes hard-coded)
329------------------------------------------------------------------------
330function luaU:DumpHeader(D)
331 local h = self:header()
332 assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert
333 self:DumpBlock(h, D)
334end
335
336------------------------------------------------------------------------
337-- make header (from lundump.c)
338-- returns the header string
339------------------------------------------------------------------------
340function luaU:header()
341 local x = 1
342 return self.LUA_SIGNATURE..
343 string.char(
344 self.LUAC_VERSION,
345 self.LUAC_FORMAT,
346 x, -- endianness (1=little)
347 4, -- sizeof(int)
348 4, -- sizeof(size_t)
349 4, -- sizeof(Instruction)
350 8, -- sizeof(lua_Number)
351 0) -- is lua_Number integral?
352end
353
354------------------------------------------------------------------------
355-- dump Lua function as precompiled chunk
356-- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
357-- * w, data are created from make_setS, make_setF
358------------------------------------------------------------------------
359function luaU:dump(L, f, w, data, strip)
360 local D = {} -- DumpState
361 D.L = L
362 D.write = w
363 D.data = data
364 D.strip = strip
365 D.status = 0
366 self:DumpHeader(D)
367 self:DumpFunction(f, nil, D)
368 -- added: for a chunk writer writing to a file, this final call with
369 -- nil data is to indicate to the writer to close the file
370 D.write(nil, D.data)
371 return D.status
372end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua
new file mode 100644
index 0000000..7949326
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/llex.lua
@@ -0,0 +1,686 @@
1--[[--------------------------------------------------------------------
2
3 llex.lua
4 Lua lexical analyzer in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * intended to 'imitate' llex.c code; performance is not a concern
18-- * tokens are strings; code structure largely retained
19-- * deleted stuff (compared to llex.c) are noted, comments retained
20-- * nextc() returns the currently read character to simplify coding
21-- here; next() in llex.c does not return anything
22-- * compatibility code is marked with "--#" comments
23--
24-- Added:
25-- * luaX:chunkid (function luaO_chunkid from lobject.c)
26-- * luaX:str2d (function luaO_str2d from lobject.c)
27-- * luaX.LUA_QS used in luaX:lexerror (from luaconf.h)
28-- * luaX.LUA_COMPAT_LSTR in luaX:read_long_string (from luaconf.h)
29-- * luaX.MAX_INT used in luaX:inclinenumber (from llimits.h)
30--
31-- To use the lexer:
32-- (1) luaX:init() to initialize the lexer
33-- (2) luaX:setinput() to set the input stream to lex
34-- (3) call luaX:next() or luaX:luaX:lookahead() to get tokens,
35-- until "TK_EOS": luaX:next()
36-- * since EOZ is returned as a string, be careful when regexp testing
37--
38-- Not implemented:
39-- * luaX_newstring: not required by this Lua implementation
40-- * buffer MAX_SIZET size limit (from llimits.h) test not implemented
41-- in the interest of performance
42-- * locale-aware number handling is largely redundant as Lua's
43-- tonumber() function is already capable of this
44--
45-- Changed in 5.1.x:
46-- * TK_NAME token order moved down
47-- * string representation for TK_NAME, TK_NUMBER, TK_STRING changed
48-- * token struct renamed to lower case (LS -> ls)
49-- * LexState struct: removed nestlevel, added decpoint
50-- * error message functions have been greatly simplified
51-- * token2string renamed to luaX_tokens, exposed in llex.h
52-- * lexer now handles all kinds of newlines, including CRLF
53-- * shbang first line handling removed from luaX:setinput;
54-- it is now done in lauxlib.c (luaL_loadfile)
55-- * next(ls) macro renamed to nextc(ls) due to new luaX_next function
56-- * EXTRABUFF and MAXNOCHECK removed due to lexer changes
57-- * checkbuffer(ls, len) macro deleted
58-- * luaX:read_numeral now has 3 support functions: luaX:trydecpoint,
59-- luaX:buffreplace and (luaO_str2d from lobject.c) luaX:str2d
60-- * luaX:read_numeral is now more promiscuous in slurping characters;
61-- hexadecimal numbers was added, locale-aware decimal points too
62-- * luaX:skip_sep is new; used by luaX:read_long_string
63-- * luaX:read_long_string handles new-style long blocks, with some
64-- optional compatibility code
65-- * luaX:llex: parts changed to support new-style long blocks
66-- * luaX:llex: readname functionality has been folded in
67-- * luaX:llex: removed test for control characters
68----------------------------------------------------------------------]]
69
70luaX = {}
71
72-- FIRST_RESERVED is not required as tokens are manipulated as strings
73-- TOKEN_LEN deleted; maximum length of a reserved word not needed
74
75------------------------------------------------------------------------
76-- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
77------------------------------------------------------------------------
78
79-- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
80-- other terminal symbols: TK_NAME to TK_EOS
81luaX.RESERVED = [[
82TK_AND and
83TK_BREAK break
84TK_DO do
85TK_ELSE else
86TK_ELSEIF elseif
87TK_END end
88TK_FALSE false
89TK_FOR for
90TK_FUNCTION function
91TK_IF if
92TK_IN in
93TK_LOCAL local
94TK_NIL nil
95TK_NOT not
96TK_OR or
97TK_REPEAT repeat
98TK_RETURN return
99TK_THEN then
100TK_TRUE true
101TK_UNTIL until
102TK_WHILE while
103TK_CONCAT ..
104TK_DOTS ...
105TK_EQ ==
106TK_GE >=
107TK_LE <=
108TK_NE ~=
109TK_NAME <name>
110TK_NUMBER <number>
111TK_STRING <string>
112TK_EOS <eof>]]
113
114-- NUM_RESERVED is not required; number of reserved words
115
116--[[--------------------------------------------------------------------
117-- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed
118-- so that lexer functions can use its table element, ls.t.seminfo
119--
120-- SemInfo (struct no longer needed, a mixed-type value is used)
121--
122-- Token (struct of ls.t and ls.lookahead):
123-- token -- token symbol
124-- seminfo -- semantics information
125--
126-- LexState (struct of ls; ls is initialized by luaX:setinput):
127-- current -- current character (charint)
128-- linenumber -- input line counter
129-- lastline -- line of last token 'consumed'
130-- t -- current token (table: struct Token)
131-- lookahead -- look ahead token (table: struct Token)
132-- fs -- 'FuncState' is private to the parser
133-- L -- LuaState
134-- z -- input stream
135-- buff -- buffer for tokens
136-- source -- current source name
137-- decpoint -- locale decimal point
138-- nestlevel -- level of nested non-terminals
139----------------------------------------------------------------------]]
140
141-- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init
142
143luaX.MAXSRC = 80
144luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above)
145luaX.LUA_QS = "'%s'"
146luaX.LUA_COMPAT_LSTR = 1
147--luaX.MAX_SIZET = 4294967293
148
149------------------------------------------------------------------------
150-- initialize lexer
151-- * original luaX_init has code to create and register token strings
152-- * luaX.tokens: TK_* -> token
153-- * luaX.enums: token -> TK_* (used in luaX:llex)
154------------------------------------------------------------------------
155function luaX:init()
156 local tokens, enums = {}, {}
157 for v in string.gmatch(self.RESERVED, "[^\n]+") do
158 local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
159 tokens[tok] = str
160 enums[str] = tok
161 end
162 self.tokens = tokens
163 self.enums = enums
164end
165
166------------------------------------------------------------------------
167-- returns a suitably-formatted chunk name or id
168-- * from lobject.c, used in llex.c and ldebug.c
169-- * the result, out, is returned (was first argument)
170------------------------------------------------------------------------
171function luaX:chunkid(source, bufflen)
172 local out
173 local first = string.sub(source, 1, 1)
174 if first == "=" then
175 out = string.sub(source, 2, bufflen) -- remove first char
176 else -- out = "source", or "...source"
177 if first == "@" then
178 source = string.sub(source, 2) -- skip the '@'
179 bufflen = bufflen - #" '...' "
180 local l = #source
181 out = ""
182 if l > bufflen then
183 source = string.sub(source, 1 + l - bufflen) -- get last part of file name
184 out = out.."..."
185 end
186 out = out..source
187 else -- out = [string "string"]
188 local len = string.find(source, "[\n\r]") -- stop at first newline
189 len = len and (len - 1) or #source
190 bufflen = bufflen - #(" [string \"...\"] ")
191 if len > bufflen then len = bufflen end
192 out = "[string \""
193 if len < #source then -- must truncate?
194 out = out..string.sub(source, 1, len).."..."
195 else
196 out = out..source
197 end
198 out = out.."\"]"
199 end
200 end
201 return out
202end
203
204--[[--------------------------------------------------------------------
205-- Support functions for lexer
206-- * all lexer errors eventually reaches lexerror:
207 syntaxerror -> lexerror
208----------------------------------------------------------------------]]
209
210------------------------------------------------------------------------
211-- look up token and return keyword if found (also called by parser)
212------------------------------------------------------------------------
213function luaX:token2str(ls, token)
214 if string.sub(token, 1, 3) ~= "TK_" then
215 if string.find(token, "%c") then
216 return string.format("char(%d)", string.byte(token))
217 end
218 return token
219 else
220 return self.tokens[token]
221 end
222end
223
224------------------------------------------------------------------------
225-- throws a lexer error
226-- * txtToken has been made local to luaX:lexerror
227-- * can't communicate LUA_ERRSYNTAX, so it is unimplemented
228------------------------------------------------------------------------
229function luaX:lexerror(ls, msg, token)
230 local function txtToken(ls, token)
231 if token == "TK_NAME" or
232 token == "TK_STRING" or
233 token == "TK_NUMBER" then
234 return ls.buff
235 else
236 return self:token2str(ls, token)
237 end
238 end
239 local buff = self:chunkid(ls.source, self.MAXSRC)
240 local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg)
241 if token then
242 msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token))
243 end
244 -- luaD_throw(ls->L, LUA_ERRSYNTAX)
245 error(msg)
246end
247
248------------------------------------------------------------------------
249-- throws a syntax error (mainly called by parser)
250-- * ls.t.token has to be set by the function calling luaX:llex
251-- (see luaX:next and luaX:lookahead elsewhere in this file)
252------------------------------------------------------------------------
253function luaX:syntaxerror(ls, msg)
254 self:lexerror(ls, msg, ls.t.token)
255end
256
257------------------------------------------------------------------------
258-- move on to next line
259------------------------------------------------------------------------
260function luaX:currIsNewline(ls)
261 return ls.current == "\n" or ls.current == "\r"
262end
263
264function luaX:inclinenumber(ls)
265 local old = ls.current
266 -- lua_assert(currIsNewline(ls))
267 self:nextc(ls) -- skip '\n' or '\r'
268 if self:currIsNewline(ls) and ls.current ~= old then
269 self:nextc(ls) -- skip '\n\r' or '\r\n'
270 end
271 ls.linenumber = ls.linenumber + 1
272 if ls.linenumber >= self.MAX_INT then
273 self:syntaxerror(ls, "chunk has too many lines")
274 end
275end
276
277------------------------------------------------------------------------
278-- initializes an input stream for lexing
279-- * if ls (the lexer state) is passed as a table, then it is filled in,
280-- otherwise it has to be retrieved as a return value
281-- * LUA_MINBUFFER not used; buffer handling not required any more
282------------------------------------------------------------------------
283function luaX:setinput(L, ls, z, source)
284 if not ls then ls = {} end -- create struct
285 if not ls.lookahead then ls.lookahead = {} end
286 if not ls.t then ls.t = {} end
287 ls.decpoint = "."
288 ls.L = L
289 ls.lookahead.token = "TK_EOS" -- no look-ahead token
290 ls.z = z
291 ls.fs = nil
292 ls.linenumber = 1
293 ls.lastline = 1
294 ls.source = source
295 self:nextc(ls) -- read first char
296end
297
298--[[--------------------------------------------------------------------
299-- LEXICAL ANALYZER
300----------------------------------------------------------------------]]
301
302------------------------------------------------------------------------
303-- checks if current character read is found in the set 'set'
304------------------------------------------------------------------------
305function luaX:check_next(ls, set)
306 if not string.find(set, ls.current, 1, 1) then
307 return false
308 end
309 self:save_and_next(ls)
310 return true
311end
312
313------------------------------------------------------------------------
314-- retrieve next token, checking the lookahead buffer if necessary
315-- * note that the macro next(ls) in llex.c is now luaX:nextc
316-- * utilized used in lparser.c (various places)
317------------------------------------------------------------------------
318function luaX:next(ls)
319 ls.lastline = ls.linenumber
320 if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token?
321 -- this must be copy-by-value
322 ls.t.seminfo = ls.lookahead.seminfo -- use this one
323 ls.t.token = ls.lookahead.token
324 ls.lookahead.token = "TK_EOS" -- and discharge it
325 else
326 ls.t.token = self:llex(ls, ls.t) -- read next token
327 end
328end
329
330------------------------------------------------------------------------
331-- fill in the lookahead buffer
332-- * utilized used in lparser.c:constructor
333------------------------------------------------------------------------
334function luaX:lookahead(ls)
335 -- lua_assert(ls.lookahead.token == "TK_EOS")
336 ls.lookahead.token = self:llex(ls, ls.lookahead)
337end
338
339------------------------------------------------------------------------
340-- gets the next character and returns it
341-- * this is the next() macro in llex.c; see notes at the beginning
342------------------------------------------------------------------------
343function luaX:nextc(ls)
344 local c = luaZ:zgetc(ls.z)
345 ls.current = c
346 return c
347end
348
349------------------------------------------------------------------------
350-- saves the given character into the token buffer
351-- * buffer handling code removed, not used in this implementation
352-- * test for maximum token buffer length not used, makes things faster
353------------------------------------------------------------------------
354
355function luaX:save(ls, c)
356 local buff = ls.buff
357 -- if you want to use this, please uncomment luaX.MAX_SIZET further up
358 --if #buff > self.MAX_SIZET then
359 -- self:lexerror(ls, "lexical element too long")
360 --end
361 ls.buff = buff..c
362end
363
364------------------------------------------------------------------------
365-- save current character into token buffer, grabs next character
366-- * like luaX:nextc, returns the character read for convenience
367------------------------------------------------------------------------
368function luaX:save_and_next(ls)
369 self:save(ls, ls.current)
370 return self:nextc(ls)
371end
372
373------------------------------------------------------------------------
374-- LUA_NUMBER
375-- * luaX:read_numeral is the main lexer function to read a number
376-- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions
377------------------------------------------------------------------------
378
379------------------------------------------------------------------------
380-- string to number converter (was luaO_str2d from lobject.c)
381-- * returns the number, nil if fails (originally returns a boolean)
382-- * conversion function originally lua_str2number(s,p), a macro which
383-- maps to the strtod() function by default (from luaconf.h)
384------------------------------------------------------------------------
385function luaX:str2d(s)
386 local result = tonumber(s)
387 if result then return result end
388 -- conversion failed
389 if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant?
390 result = tonumber(s, 16)
391 if result then return result end -- most common case
392 -- Was: invalid trailing characters?
393 -- In C, this function then skips over trailing spaces.
394 -- true is returned if nothing else is found except for spaces.
395 -- If there is still something else, then it returns a false.
396 -- All this is not necessary using Lua's tonumber.
397 end
398 return nil
399end
400
401------------------------------------------------------------------------
402-- single-character replacement, for locale-aware decimal points
403------------------------------------------------------------------------
404function luaX:buffreplace(ls, from, to)
405 local result, buff = "", ls.buff
406 for p = 1, #buff do
407 local c = string.sub(buff, p, p)
408 if c == from then c = to end
409 result = result..c
410 end
411 ls.buff = result
412end
413
414------------------------------------------------------------------------
415-- Attempt to convert a number by translating '.' decimal points to
416-- the decimal point character used by the current locale. This is not
417-- needed in Yueliang as Lua's tonumber() is already locale-aware.
418-- Instead, the code is here in case the user implements localeconv().
419------------------------------------------------------------------------
420function luaX:trydecpoint(ls, Token)
421 -- format error: try to update decimal point separator
422 local old = ls.decpoint
423 -- translate the following to Lua if you implement localeconv():
424 -- struct lconv *cv = localeconv();
425 -- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
426 self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator
427 local seminfo = self:str2d(ls.buff)
428 Token.seminfo = seminfo
429 if not seminfo then
430 -- format error with correct decimal point: no more options
431 self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message)
432 self:lexerror(ls, "malformed number", "TK_NUMBER")
433 end
434end
435
436------------------------------------------------------------------------
437-- main number conversion function
438-- * "^%w$" needed in the scan in order to detect "EOZ"
439------------------------------------------------------------------------
440function luaX:read_numeral(ls, Token)
441 -- lua_assert(string.find(ls.current, "%d"))
442 repeat
443 self:save_and_next(ls)
444 until string.find(ls.current, "%D") and ls.current ~= "."
445 if self:check_next(ls, "Ee") then -- 'E'?
446 self:check_next(ls, "+-") -- optional exponent sign
447 end
448 while string.find(ls.current, "^%w$") or ls.current == "_" do
449 self:save_and_next(ls)
450 end
451 self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point
452 local seminfo = self:str2d(ls.buff)
453 Token.seminfo = seminfo
454 if not seminfo then -- format error?
455 self:trydecpoint(ls, Token) -- try to update decimal point separator
456 end
457end
458
459------------------------------------------------------------------------
460-- count separators ("=") in a long string delimiter
461-- * used by luaX:read_long_string
462------------------------------------------------------------------------
463function luaX:skip_sep(ls)
464 local count = 0
465 local s = ls.current
466 -- lua_assert(s == "[" or s == "]")
467 self:save_and_next(ls)
468 while ls.current == "=" do
469 self:save_and_next(ls)
470 count = count + 1
471 end
472 return (ls.current == s) and count or (-count) - 1
473end
474
475------------------------------------------------------------------------
476-- reads a long string or long comment
477------------------------------------------------------------------------
478function luaX:read_long_string(ls, Token, sep)
479 local cont = 0
480 self:save_and_next(ls) -- skip 2nd '['
481 if self:currIsNewline(ls) then -- string starts with a newline?
482 self:inclinenumber(ls) -- skip it
483 end
484 while true do
485 local c = ls.current
486 if c == "EOZ" then
487 self:lexerror(ls, Token and "unfinished long string" or
488 "unfinished long comment", "TK_EOS")
489 elseif c == "[" then
490 --# compatibility code start
491 if self.LUA_COMPAT_LSTR then
492 if self:skip_sep(ls) == sep then
493 self:save_and_next(ls) -- skip 2nd '['
494 cont = cont + 1
495 --# compatibility code start
496 if self.LUA_COMPAT_LSTR == 1 then
497 if sep == 0 then
498 self:lexerror(ls, "nesting of [[...]] is deprecated", "[")
499 end
500 end
501 --# compatibility code end
502 end
503 end
504 --# compatibility code end
505 elseif c == "]" then
506 if self:skip_sep(ls) == sep then
507 self:save_and_next(ls) -- skip 2nd ']'
508 --# compatibility code start
509 if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then
510 cont = cont - 1
511 if sep == 0 and cont >= 0 then break end
512 end
513 --# compatibility code end
514 break
515 end
516 elseif self:currIsNewline(ls) then
517 self:save(ls, "\n")
518 self:inclinenumber(ls)
519 if not Token then ls.buff = "" end -- avoid wasting space
520 else -- default
521 if Token then
522 self:save_and_next(ls)
523 else
524 self:nextc(ls)
525 end
526 end--if c
527 end--while
528 if Token then
529 local p = 3 + sep
530 Token.seminfo = string.sub(ls.buff, p, -p)
531 end
532end
533
534------------------------------------------------------------------------
535-- reads a string
536-- * has been restructured significantly compared to the original C code
537------------------------------------------------------------------------
538
539function luaX:read_string(ls, del, Token)
540 self:save_and_next(ls)
541 while ls.current ~= del do
542 local c = ls.current
543 if c == "EOZ" then
544 self:lexerror(ls, "unfinished string", "TK_EOS")
545 elseif self:currIsNewline(ls) then
546 self:lexerror(ls, "unfinished string", "TK_STRING")
547 elseif c == "\\" then
548 c = self:nextc(ls) -- do not save the '\'
549 if self:currIsNewline(ls) then -- go through
550 self:save(ls, "\n")
551 self:inclinenumber(ls)
552 elseif c ~= "EOZ" then -- will raise an error next loop
553 -- escapes handling greatly simplified here:
554 local i = string.find("abfnrtv", c, 1, 1)
555 if i then
556 self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i))
557 self:nextc(ls)
558 elseif not string.find(c, "%d") then
559 self:save_and_next(ls) -- handles \\, \", \', and \?
560 else -- \xxx
561 c, i = 0, 0
562 repeat
563 c = 10 * c + ls.current
564 self:nextc(ls)
565 i = i + 1
566 until i >= 3 or not string.find(ls.current, "%d")
567 if c > 255 then -- UCHAR_MAX
568 self:lexerror(ls, "escape sequence too large", "TK_STRING")
569 end
570 self:save(ls, string.char(c))
571 end
572 end
573 else
574 self:save_and_next(ls)
575 end--if c
576 end--while
577 self:save_and_next(ls) -- skip delimiter
578 Token.seminfo = string.sub(ls.buff, 2, -2)
579end
580
581------------------------------------------------------------------------
582-- main lexer function
583------------------------------------------------------------------------
584function luaX:llex(ls, Token)
585 ls.buff = ""
586 while true do
587 local c = ls.current
588 ----------------------------------------------------------------
589 if self:currIsNewline(ls) then
590 self:inclinenumber(ls)
591 ----------------------------------------------------------------
592 elseif c == "-" then
593 c = self:nextc(ls)
594 if c ~= "-" then return "-" end
595 -- else is a comment
596 local sep = -1
597 if self:nextc(ls) == '[' then
598 sep = self:skip_sep(ls)
599 ls.buff = "" -- 'skip_sep' may dirty the buffer
600 end
601 if sep >= 0 then
602 self:read_long_string(ls, nil, sep) -- long comment
603 ls.buff = ""
604 else -- else short comment
605 while not self:currIsNewline(ls) and ls.current ~= "EOZ" do
606 self:nextc(ls)
607 end
608 end
609 ----------------------------------------------------------------
610 elseif c == "[" then
611 local sep = self:skip_sep(ls)
612 if sep >= 0 then
613 self:read_long_string(ls, Token, sep)
614 return "TK_STRING"
615 elseif sep == -1 then
616 return "["
617 else
618 self:lexerror(ls, "invalid long string delimiter", "TK_STRING")
619 end
620 ----------------------------------------------------------------
621 elseif c == "=" then
622 c = self:nextc(ls)
623 if c ~= "=" then return "="
624 else self:nextc(ls); return "TK_EQ" end
625 ----------------------------------------------------------------
626 elseif c == "<" then
627 c = self:nextc(ls)
628 if c ~= "=" then return "<"
629 else self:nextc(ls); return "TK_LE" end
630 ----------------------------------------------------------------
631 elseif c == ">" then
632 c = self:nextc(ls)
633 if c ~= "=" then return ">"
634 else self:nextc(ls); return "TK_GE" end
635 ----------------------------------------------------------------
636 elseif c == "~" then
637 c = self:nextc(ls)
638 if c ~= "=" then return "~"
639 else self:nextc(ls); return "TK_NE" end
640 ----------------------------------------------------------------
641 elseif c == "\"" or c == "'" then
642 self:read_string(ls, c, Token)
643 return "TK_STRING"
644 ----------------------------------------------------------------
645 elseif c == "." then
646 c = self:save_and_next(ls)
647 if self:check_next(ls, ".") then
648 if self:check_next(ls, ".") then
649 return "TK_DOTS" -- ...
650 else return "TK_CONCAT" -- ..
651 end
652 elseif not string.find(c, "%d") then
653 return "."
654 else
655 self:read_numeral(ls, Token)
656 return "TK_NUMBER"
657 end
658 ----------------------------------------------------------------
659 elseif c == "EOZ" then
660 return "TK_EOS"
661 ----------------------------------------------------------------
662 else -- default
663 if string.find(c, "%s") then
664 -- lua_assert(self:currIsNewline(ls))
665 self:nextc(ls)
666 elseif string.find(c, "%d") then
667 self:read_numeral(ls, Token)
668 return "TK_NUMBER"
669 elseif string.find(c, "[_%a]") then
670 -- identifier or reserved word
671 repeat
672 c = self:save_and_next(ls)
673 until c == "EOZ" or not string.find(c, "[_%w]")
674 local ts = ls.buff
675 local tok = self.enums[ts]
676 if tok then return tok end -- reserved word?
677 Token.seminfo = ts
678 return "TK_NAME"
679 else
680 self:nextc(ls)
681 return c -- single-char tokens (+ - / ...)
682 end
683 ----------------------------------------------------------------
684 end--if c
685 end--while
686end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua
new file mode 100644
index 0000000..e7dbbe8
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lopcodes.lua
@@ -0,0 +1,432 @@
1--[[--------------------------------------------------------------------
2
3 lopcodes.lua
4 Lua 5 virtual machine opcodes in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * an Instruction is a table with OP, A, B, C, Bx elements; this
18-- makes the code easy to follow and should allow instruction handling
19-- to work with doubles and ints
20-- * WARNING luaP:Instruction outputs instructions encoded in little-
21-- endian form and field size and positions are hard-coded
22--
23-- Not implemented:
24-- *
25--
26-- Added:
27-- * luaP:CREATE_Inst(c): create an inst from a number (for OP_SETLIST)
28-- * luaP:Instruction(i): convert field elements to a 4-char string
29-- * luaP:DecodeInst(x): convert 4-char string into field elements
30--
31-- Changed in 5.1.x:
32-- * POS_OP added, instruction field positions changed
33-- * some symbol names may have changed, e.g. LUAI_BITSINT
34-- * new operators for RK indices: BITRK, ISK(x), INDEXK(r), RKASK(x)
35-- * OP_MOD, OP_LEN is new
36-- * OP_TEST is now OP_TESTSET, OP_TEST is new
37-- * OP_FORLOOP, OP_TFORLOOP adjusted, OP_FORPREP is new
38-- * OP_TFORPREP deleted
39-- * OP_SETLIST and OP_SETLISTO merged and extended
40-- * OP_VARARG is new
41-- * many changes to implementation of OpMode data
42----------------------------------------------------------------------]]
43
44luaP = {}
45
46--[[
47===========================================================================
48 We assume that instructions are unsigned numbers.
49 All instructions have an opcode in the first 6 bits.
50 Instructions can have the following fields:
51 'A' : 8 bits
52 'B' : 9 bits
53 'C' : 9 bits
54 'Bx' : 18 bits ('B' and 'C' together)
55 'sBx' : signed Bx
56
57 A signed argument is represented in excess K; that is, the number
58 value is the unsigned value minus K. K is exactly the maximum value
59 for that argument (so that -max is represented by 0, and +max is
60 represented by 2*max), which is half the maximum for the corresponding
61 unsigned argument.
62===========================================================================
63--]]
64
65luaP.OpMode = { iABC = 0, iABx = 1, iAsBx = 2 } -- basic instruction format
66
67------------------------------------------------------------------------
68-- size and position of opcode arguments.
69-- * WARNING size and position is hard-coded elsewhere in this script
70------------------------------------------------------------------------
71luaP.SIZE_C = 9
72luaP.SIZE_B = 9
73luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B
74luaP.SIZE_A = 8
75
76luaP.SIZE_OP = 6
77
78luaP.POS_OP = 0
79luaP.POS_A = luaP.POS_OP + luaP.SIZE_OP
80luaP.POS_C = luaP.POS_A + luaP.SIZE_A
81luaP.POS_B = luaP.POS_C + luaP.SIZE_C
82luaP.POS_Bx = luaP.POS_C
83
84------------------------------------------------------------------------
85-- limits for opcode arguments.
86-- we use (signed) int to manipulate most arguments,
87-- so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
88------------------------------------------------------------------------
89-- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is
90-- running on a Lua VM with double or int as LUA_NUMBER
91
92luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1
93luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed
94
95luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1
96luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1
97luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1
98
99-- creates a mask with 'n' 1 bits at position 'p'
100-- MASK1(n,p) deleted, not required
101-- creates a mask with 'n' 0 bits at position 'p'
102-- MASK0(n,p) deleted, not required
103
104--[[--------------------------------------------------------------------
105 Visual representation for reference:
106
107 31 | | | 0 bit position
108 +-----+-----+-----+----------+
109 | B | C | A | Opcode | iABC format
110 +-----+-----+-----+----------+
111 - 9 - 9 - 8 - 6 - field sizes
112 +-----+-----+-----+----------+
113 | [s]Bx | A | Opcode | iABx | iAsBx format
114 +-----+-----+-----+----------+
115
116----------------------------------------------------------------------]]
117
118------------------------------------------------------------------------
119-- the following macros help to manipulate instructions
120-- * changed to a table object representation, very clean compared to
121-- the [nightmare] alternatives of using a number or a string
122-- * Bx is a separate element from B and C, since there is never a need
123-- to split Bx in the parser or code generator
124------------------------------------------------------------------------
125
126-- these accept or return opcodes in the form of string names
127function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end
128function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end
129
130function luaP:GETARG_A(i) return i.A end
131function luaP:SETARG_A(i, u) i.A = u end
132
133function luaP:GETARG_B(i) return i.B end
134function luaP:SETARG_B(i, b) i.B = b end
135
136function luaP:GETARG_C(i) return i.C end
137function luaP:SETARG_C(i, b) i.C = b end
138
139function luaP:GETARG_Bx(i) return i.Bx end
140function luaP:SETARG_Bx(i, b) i.Bx = b end
141
142function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end
143function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end
144
145function luaP:CREATE_ABC(o,a,b,c)
146 return {OP = self.OpCode[o], A = a, B = b, C = c}
147end
148
149function luaP:CREATE_ABx(o,a,bc)
150 return {OP = self.OpCode[o], A = a, Bx = bc}
151end
152
153------------------------------------------------------------------------
154-- create an instruction from a number (for OP_SETLIST)
155------------------------------------------------------------------------
156function luaP:CREATE_Inst(c)
157 local o = c % 64
158 c = (c - o) / 64
159 local a = c % 256
160 c = (c - a) / 256
161 return self:CREATE_ABx(o, a, c)
162end
163
164------------------------------------------------------------------------
165-- returns a 4-char string little-endian encoded form of an instruction
166------------------------------------------------------------------------
167function luaP:Instruction(i)
168 if i.Bx then
169 -- change to OP/A/B/C format
170 i.C = i.Bx % 512
171 i.B = (i.Bx - i.C) / 512
172 end
173 local I = i.A * 64 + i.OP
174 local c0 = I % 256
175 I = i.C * 64 + (I - c0) / 256 -- 6 bits of A left
176 local c1 = I % 256
177 I = i.B * 128 + (I - c1) / 256 -- 7 bits of C left
178 local c2 = I % 256
179 local c3 = (I - c2) / 256
180 return string.char(c0, c1, c2, c3)
181end
182
183------------------------------------------------------------------------
184-- decodes a 4-char little-endian string into an instruction struct
185------------------------------------------------------------------------
186function luaP:DecodeInst(x)
187 local byte = string.byte
188 local i = {}
189 local I = byte(x, 1)
190 local op = I % 64
191 i.OP = op
192 I = byte(x, 2) * 4 + (I - op) / 64 -- 2 bits of c0 left
193 local a = I % 256
194 i.A = a
195 I = byte(x, 3) * 4 + (I - a) / 256 -- 2 bits of c1 left
196 local c = I % 512
197 i.C = c
198 i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left
199 local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))]
200 if opmode ~= "iABC" then
201 i.Bx = i.B * 512 + i.C
202 end
203 return i
204end
205
206------------------------------------------------------------------------
207-- Macros to operate RK indices
208-- * these use arithmetic instead of bit ops
209------------------------------------------------------------------------
210
211-- this bit 1 means constant (0 means register)
212luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1)
213
214-- test whether value is a constant
215function luaP:ISK(x) return x >= self.BITRK end
216
217-- gets the index of the constant
218function luaP:INDEXK(r) return x - self.BITRK end
219
220luaP.MAXINDEXRK = luaP.BITRK - 1
221
222-- code a constant index as a RK value
223function luaP:RKASK(x) return x + self.BITRK end
224
225------------------------------------------------------------------------
226-- invalid register that fits in 8 bits
227------------------------------------------------------------------------
228luaP.NO_REG = luaP.MAXARG_A
229
230------------------------------------------------------------------------
231-- R(x) - register
232-- Kst(x) - constant (in constant table)
233-- RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
234------------------------------------------------------------------------
235
236------------------------------------------------------------------------
237-- grep "ORDER OP" if you change these enums
238------------------------------------------------------------------------
239
240--[[--------------------------------------------------------------------
241Lua virtual machine opcodes (enum OpCode):
242------------------------------------------------------------------------
243name args description
244------------------------------------------------------------------------
245OP_MOVE A B R(A) := R(B)
246OP_LOADK A Bx R(A) := Kst(Bx)
247OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++
248OP_LOADNIL A B R(A) := ... := R(B) := nil
249OP_GETUPVAL A B R(A) := UpValue[B]
250OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)]
251OP_GETTABLE A B C R(A) := R(B)[RK(C)]
252OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A)
253OP_SETUPVAL A B UpValue[B] := R(A)
254OP_SETTABLE A B C R(A)[RK(B)] := RK(C)
255OP_NEWTABLE A B C R(A) := {} (size = B,C)
256OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)]
257OP_ADD A B C R(A) := RK(B) + RK(C)
258OP_SUB A B C R(A) := RK(B) - RK(C)
259OP_MUL A B C R(A) := RK(B) * RK(C)
260OP_DIV A B C R(A) := RK(B) / RK(C)
261OP_MOD A B C R(A) := RK(B) % RK(C)
262OP_POW A B C R(A) := RK(B) ^ RK(C)
263OP_UNM A B R(A) := -R(B)
264OP_NOT A B R(A) := not R(B)
265OP_LEN A B R(A) := length of R(B)
266OP_CONCAT A B C R(A) := R(B).. ... ..R(C)
267OP_JMP sBx pc+=sBx
268OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++
269OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++
270OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++
271OP_TEST A C if not (R(A) <=> C) then pc++
272OP_TESTSET A B C if (R(B) <=> C) then R(A) := R(B) else pc++
273OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
274OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1))
275OP_RETURN A B return R(A), ... ,R(A+B-2) (see note)
276OP_FORLOOP A sBx R(A)+=R(A+2);
277 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
278OP_FORPREP A sBx R(A)-=R(A+2); pc+=sBx
279OP_TFORLOOP A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
280 if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
281OP_SETLIST A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
282OP_CLOSE A close all variables in the stack up to (>=) R(A)
283OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
284OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg
285----------------------------------------------------------------------]]
286
287luaP.opnames = {} -- opcode names
288luaP.OpCode = {} -- lookup name -> number
289luaP.ROpCode = {} -- lookup number -> name
290
291------------------------------------------------------------------------
292-- ORDER OP
293------------------------------------------------------------------------
294local i = 0
295for v in string.gmatch([[
296MOVE LOADK LOADBOOL LOADNIL GETUPVAL
297GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE
298NEWTABLE SELF ADD SUB MUL
299DIV MOD POW UNM NOT
300LEN CONCAT JMP EQ LT
301LE TEST TESTSET CALL TAILCALL
302RETURN FORLOOP FORPREP TFORLOOP SETLIST
303CLOSE CLOSURE VARARG
304]], "%S+") do
305 local n = "OP_"..v
306 luaP.opnames[i] = v
307 luaP.OpCode[n] = i
308 luaP.ROpCode[i] = n
309 i = i + 1
310end
311luaP.NUM_OPCODES = i
312
313--[[
314===========================================================================
315 Notes:
316 (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
317 and can be 0: OP_CALL then sets 'top' to last_result+1, so
318 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
319 (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
320 set top (like in OP_CALL with C == 0).
321 (*) In OP_RETURN, if (B == 0) then return up to 'top'
322 (*) In OP_SETLIST, if (B == 0) then B = 'top';
323 if (C == 0) then next 'instruction' is real C
324 (*) For comparisons, A specifies what condition the test should accept
325 (true or false).
326 (*) All 'skips' (pc++) assume that next instruction is a jump
327===========================================================================
328--]]
329
330--[[--------------------------------------------------------------------
331 masks for instruction properties. The format is:
332 bits 0-1: op mode
333 bits 2-3: C arg mode
334 bits 4-5: B arg mode
335 bit 6: instruction set register A
336 bit 7: operator is a test
337
338 for OpArgMask:
339 OpArgN - argument is not used
340 OpArgU - argument is used
341 OpArgR - argument is a register or a jump offset
342 OpArgK - argument is a constant or register/constant
343----------------------------------------------------------------------]]
344
345-- was enum OpArgMask
346luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 }
347
348------------------------------------------------------------------------
349-- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC
350-- * accepts opcode parameter as strings, e.g. "OP_MOVE"
351------------------------------------------------------------------------
352
353function luaP:getOpMode(m)
354 return self.opmodes[self.OpCode[m]] % 4
355end
356
357function luaP:getBMode(m)
358 return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4
359end
360
361function luaP:getCMode(m)
362 return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4
363end
364
365function luaP:testAMode(m)
366 return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2
367end
368
369function luaP:testTMode(m)
370 return math.floor(self.opmodes[self.OpCode[m]] / 128)
371end
372
373-- luaP_opnames[] is set above, as the luaP.opnames table
374
375-- number of list items to accumulate before a SETLIST instruction
376luaP.LFIELDS_PER_FLUSH = 50
377
378------------------------------------------------------------------------
379-- build instruction properties array
380-- * deliberately coded to look like the C equivalent
381------------------------------------------------------------------------
382local function opmode(t, a, b, c, m)
383 local luaP = luaP
384 return t * 128 + a * 64 +
385 luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m]
386end
387
388-- ORDER OP
389luaP.opmodes = {
390-- T A B C mode opcode
391 opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_LOADK
392 opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_LOADBOOL
393 opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LOADNIL
394 opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_GETUPVAL
395 opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_GETGLOBAL
396 opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_GETTABLE
397 opmode(0, 0, "OpArgK", "OpArgN", "iABx"), -- OP_SETGLOBAL
398 opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_SETUPVAL
399 opmode(0, 0, "OpArgK", "OpArgK", "iABC"), -- OP_SETTABLE
400 opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_NEWTABLE
401 opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_SELF
402 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_ADD
403 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_SUB
404 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MUL
405 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_DIV
406 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MOD
407 opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_POW
408 opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_UNM
409 opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_NOT
410 opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LEN
411 opmode(0, 1, "OpArgR", "OpArgR", "iABC"), -- OP_CONCAT
412 opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"), -- OP_JMP
413 opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_EQ
414 opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LT
415 opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LE
416 opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TEST
417 opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TESTSET
418 opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_CALL
419 opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_TAILCALL
420 opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_RETURN
421 opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORLOOP
422 opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORPREP
423 opmode(1, 0, "OpArgN", "OpArgU", "iABC"), -- OP_TFORLOOP
424 opmode(0, 0, "OpArgU", "OpArgU", "iABC"), -- OP_SETLIST
425 opmode(0, 0, "OpArgN", "OpArgN", "iABC"), -- OP_CLOSE
426 opmode(0, 1, "OpArgU", "OpArgN", "iABx"), -- OP_CLOSURE
427 opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_VARARG
428}
429-- an awkward way to set a zero-indexed table...
430luaP.opmodes[0] =
431 opmode(0, 1, "OpArgR", "OpArgN", "iABC") -- OP_MOVE
432
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua
new file mode 100644
index 0000000..2535056
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua
@@ -0,0 +1,1747 @@
1--[[--------------------------------------------------------------------
2
3 lparser.lua
4 Lua 5 parser in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * some unused C code that were not converted are kept as comments
18-- * LUA_COMPAT_VARARG option changed into a comment block
19-- * for value/size specific code added, look for 'NOTE: '
20--
21-- Not implemented:
22-- * luaX_newstring not needed by this Lua implementation
23-- * luaG_checkcode() in lua_assert is not currently implemented
24--
25-- Added:
26-- * some constants added from various header files
27-- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h)
28-- * luaY:LUA_QL needed for error messages (from luaconf.h)
29-- * luaY:growvector (from lmem.h) -- skeleton only, limit checking
30-- * luaY.SHRT_MAX (from <limits.h>) for registerlocalvar
31-- * luaY:newproto (from lfunc.c)
32-- * luaY:int2fb (from lobject.c)
33-- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation
34-- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop
35--
36-- Changed in 5.1.x:
37-- * various code changes are not detailed...
38-- * names of constants may have changed, e.g. added a LUAI_ prefix
39-- * struct expkind: added VKNUM, VVARARG; VCALL's info changed?
40-- * struct expdesc: added nval
41-- * struct FuncState: upvalues data type changed to upvaldesc
42-- * macro hasmultret is new
43-- * function checklimit moved to parser from lexer
44-- * functions anchor_token, errorlimit, checknext are new
45-- * checknext is new, equivalent to 5.0.x's check, see check too
46-- * luaY:next and luaY:lookahead moved to lexer
47-- * break keyword no longer skipped in luaY:breakstat
48-- * function new_localvarstr replaced by new_localvarliteral
49-- * registerlocalvar limits local variables to SHRT_MAX
50-- * create_local deleted, new_localvarliteral used instead
51-- * constant LUAI_MAXUPVALUES increased to 60
52-- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed
53-- * function interface changed: singlevaraux, singlevar
54-- * enterlevel and leavelevel uses nCcalls to track call depth
55-- * added a name argument to main entry function, luaY:parser
56-- * function luaY_index changed to yindex
57-- * luaY:int2fb()'s table size encoding format has been changed
58-- * luaY:log2() no longer needed for table constructors
59-- * function code_params deleted, functionality folded in parlist
60-- * vararg flags handling (is_vararg) changes; also see VARARG_*
61-- * LUA_COMPATUPSYNTAX section for old-style upvalues removed
62-- * repeatstat() calls chunk() instead of block()
63-- * function interface changed: cond, test_then_block
64-- * while statement implementation considerably simplified; MAXEXPWHILE
65-- and EXTRAEXP no longer required, no limits to the complexity of a
66-- while condition
67-- * repeat, forbody statement implementation has major changes,
68-- mostly due to new scoping behaviour of local variables
69-- * OPR_MULT renamed to OPR_MUL
70----------------------------------------------------------------------]]
71
72--requires luaP, luaX, luaK
73luaY = {}
74
75--[[--------------------------------------------------------------------
76-- Expression descriptor
77-- * expkind changed to string constants; luaY:assignment was the only
78-- function to use a relational operator with this enumeration
79-- VVOID -- no value
80-- VNIL -- no value
81-- VTRUE -- no value
82-- VFALSE -- no value
83-- VK -- info = index of constant in 'k'
84-- VKNUM -- nval = numerical value
85-- VLOCAL -- info = local register
86-- VUPVAL, -- info = index of upvalue in 'upvalues'
87-- VGLOBAL -- info = index of table; aux = index of global name in 'k'
88-- VINDEXED -- info = table register; aux = index register (or 'k')
89-- VJMP -- info = instruction pc
90-- VRELOCABLE -- info = instruction pc
91-- VNONRELOC -- info = result register
92-- VCALL -- info = instruction pc
93-- VVARARG -- info = instruction pc
94} ----------------------------------------------------------------------]]
95
96--[[--------------------------------------------------------------------
97-- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
98-- implementation ignores all instances of u and s usage
99-- struct expdesc:
100-- k -- (enum: expkind)
101-- info, aux -- (int, int)
102-- nval -- (lua_Number)
103-- t -- patch list of 'exit when true'
104-- f -- patch list of 'exit when false'
105----------------------------------------------------------------------]]
106
107--[[--------------------------------------------------------------------
108-- struct upvaldesc:
109-- k -- (lu_byte)
110-- info -- (lu_byte)
111----------------------------------------------------------------------]]
112
113--[[--------------------------------------------------------------------
114-- state needed to generate code for a given function
115-- struct FuncState:
116-- f -- current function header (table: Proto)
117-- h -- table to find (and reuse) elements in 'k' (table: Table)
118-- prev -- enclosing function (table: FuncState)
119-- ls -- lexical state (table: LexState)
120-- L -- copy of the Lua state (table: lua_State)
121-- bl -- chain of current blocks (table: BlockCnt)
122-- pc -- next position to code (equivalent to 'ncode')
123-- lasttarget -- 'pc' of last 'jump target'
124-- jpc -- list of pending jumps to 'pc'
125-- freereg -- first free register
126-- nk -- number of elements in 'k'
127-- np -- number of elements in 'p'
128-- nlocvars -- number of elements in 'locvars'
129-- nactvar -- number of active local variables
130-- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc)
131-- actvar[LUAI_MAXVARS] -- declared-variable stack
132----------------------------------------------------------------------]]
133
134------------------------------------------------------------------------
135-- constants used by parser
136-- * picks up duplicate values from luaX if required
137------------------------------------------------------------------------
138luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h)
139
140luaY.SHRT_MAX = 32767 -- (from <limits.h>)
141luaY.LUAI_MAXVARS = 200 -- (luaconf.h)
142luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h)
143luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h)
144 -- * INT_MAX-2 for 32-bit systems
145luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h)
146
147luaY.VARARG_HASARG = 1 -- (from lobject.h)
148-- NOTE: HASARG_MASK is value-specific
149luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
150luaY.VARARG_ISVARARG = 2
151-- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
152luaY.VARARG_NEEDSARG = 4
153
154luaY.LUA_MULTRET = -1 -- (lua.h)
155
156--[[--------------------------------------------------------------------
157-- other functions
158----------------------------------------------------------------------]]
159
160------------------------------------------------------------------------
161-- LUA_QL describes how error messages quote program elements.
162-- CHANGE it if you want a different appearance. (from luaconf.h)
163------------------------------------------------------------------------
164function luaY:LUA_QL(x)
165 return "'"..x.."'"
166end
167
168------------------------------------------------------------------------
169-- this is a stripped-down luaM_growvector (from lmem.h) which is a
170-- macro based on luaM_growaux (in lmem.c); all the following does is
171-- reproduce the size limit checking logic of the original function
172-- so that error behaviour is identical; all arguments preserved for
173-- convenience, even those which are unused
174-- * set the t field to nil, since this originally does a sizeof(t)
175-- * size (originally a pointer) is never updated, their final values
176-- are set by luaY:close_func(), so overall things should still work
177------------------------------------------------------------------------
178function luaY:growvector(L, v, nelems, size, t, limit, e)
179 if nelems >= limit then
180 error(e) -- was luaG_runerror
181 end
182end
183
184------------------------------------------------------------------------
185-- initialize a new function prototype structure (from lfunc.c)
186-- * used only in open_func()
187------------------------------------------------------------------------
188function luaY:newproto(L)
189 local f = {} -- Proto
190 -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
191 f.k = {}
192 f.sizek = 0
193 f.p = {}
194 f.sizep = 0
195 f.code = {}
196 f.sizecode = 0
197 f.sizelineinfo = 0
198 f.sizeupvalues = 0
199 f.nups = 0
200 f.upvalues = {}
201 f.numparams = 0
202 f.is_vararg = 0
203 f.maxstacksize = 0
204 f.lineinfo = {}
205 f.sizelocvars = 0
206 f.locvars = {}
207 f.lineDefined = 0
208 f.lastlinedefined = 0
209 f.source = nil
210 return f
211end
212
213------------------------------------------------------------------------
214-- converts an integer to a "floating point byte", represented as
215-- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
216-- eeeee != 0 and (xxx) otherwise.
217------------------------------------------------------------------------
218function luaY:int2fb(x)
219 local e = 0 -- exponent
220 while x >= 16 do
221 x = math.floor((x + 1) / 2)
222 e = e + 1
223 end
224 if x < 8 then
225 return x
226 else
227 return ((e + 1) * 8) + (x - 8)
228 end
229end
230
231--[[--------------------------------------------------------------------
232-- parser functions
233----------------------------------------------------------------------]]
234
235------------------------------------------------------------------------
236-- true of the kind of expression produces multiple return values
237------------------------------------------------------------------------
238function luaY:hasmultret(k)
239 return k == "VCALL" or k == "VVARARG"
240end
241
242------------------------------------------------------------------------
243-- convenience function to access active local i, returns entry
244------------------------------------------------------------------------
245function luaY:getlocvar(fs, i)
246 return fs.f.locvars[ fs.actvar[i] ]
247end
248
249------------------------------------------------------------------------
250-- check a limit, string m provided as an error message
251------------------------------------------------------------------------
252function luaY:checklimit(fs, v, l, m)
253 if v > l then self:errorlimit(fs, l, m) end
254end
255
256--[[--------------------------------------------------------------------
257-- nodes for block list (list of active blocks)
258-- struct BlockCnt:
259-- previous -- chain (table: BlockCnt)
260-- breaklist -- list of jumps out of this loop
261-- nactvar -- # active local variables outside the breakable structure
262-- upval -- true if some variable in the block is an upvalue (boolean)
263-- isbreakable -- true if 'block' is a loop (boolean)
264----------------------------------------------------------------------]]
265
266------------------------------------------------------------------------
267-- prototypes for recursive non-terminal functions
268------------------------------------------------------------------------
269-- prototypes deleted; not required in Lua
270
271------------------------------------------------------------------------
272-- reanchor if last token is has a constant string, see close_func()
273-- * used only in close_func()
274------------------------------------------------------------------------
275function luaY:anchor_token(ls)
276 if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
277 -- not relevant to Lua implementation of parser
278 -- local ts = ls.t.seminfo
279 -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
280 end
281end
282
283------------------------------------------------------------------------
284-- throws a syntax error if token expected is not there
285------------------------------------------------------------------------
286function luaY:error_expected(ls, token)
287 luaX:syntaxerror(ls,
288 string.format(self.LUA_QS.." expected", luaX:token2str(ls, token)))
289end
290
291------------------------------------------------------------------------
292-- prepares error message for display, for limits exceeded
293-- * used only in checklimit()
294------------------------------------------------------------------------
295function luaY:errorlimit(fs, limit, what)
296 local msg = (fs.f.linedefined == 0) and
297 string.format("main function has more than %d %s", limit, what) or
298 string.format("function at line %d has more than %d %s",
299 fs.f.linedefined, limit, what)
300 luaX:lexerror(fs.ls, msg, 0)
301end
302
303------------------------------------------------------------------------
304-- tests for a token, returns outcome
305-- * return value changed to boolean
306------------------------------------------------------------------------
307function luaY:testnext(ls, c)
308 if ls.t.token == c then
309 luaX:next(ls)
310 return true
311 else
312 return false
313 end
314end
315
316------------------------------------------------------------------------
317-- check for existence of a token, throws error if not found
318------------------------------------------------------------------------
319function luaY:check(ls, c)
320 if ls.t.token ~= c then
321 self:error_expected(ls, c)
322 end
323end
324
325------------------------------------------------------------------------
326-- verify existence of a token, then skip it
327------------------------------------------------------------------------
328function luaY:checknext(ls, c)
329 self:check(ls, c)
330 luaX:next(ls)
331end
332
333------------------------------------------------------------------------
334-- throws error if condition not matched
335------------------------------------------------------------------------
336function luaY:check_condition(ls, c, msg)
337 if not c then luaX:syntaxerror(ls, msg) end
338end
339
340------------------------------------------------------------------------
341-- verifies token conditions are met or else throw error
342------------------------------------------------------------------------
343function luaY:check_match(ls, what, who, where)
344 if not self:testnext(ls, what) then
345 if where == ls.linenumber then
346 self:error_expected(ls, what)
347 else
348 luaX:syntaxerror(ls, string.format(
349 self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)",
350 luaX:token2str(ls, what), luaX:token2str(ls, who), where))
351 end
352 end
353end
354
355------------------------------------------------------------------------
356-- expect that token is a name, return the name
357------------------------------------------------------------------------
358function luaY:str_checkname(ls)
359 self:check(ls, "TK_NAME")
360 local ts = ls.t.seminfo
361 luaX:next(ls)
362 return ts
363end
364
365------------------------------------------------------------------------
366-- initialize a struct expdesc, expression description data structure
367------------------------------------------------------------------------
368function luaY:init_exp(e, k, i)
369 e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
370 e.k = k
371 e.info = i
372end
373
374------------------------------------------------------------------------
375-- adds given string s in string pool, sets e as VK
376------------------------------------------------------------------------
377function luaY:codestring(ls, e, s)
378 self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
379end
380
381------------------------------------------------------------------------
382-- consume a name token, adds it to string pool, sets e as VK
383------------------------------------------------------------------------
384function luaY:checkname(ls, e)
385 self:codestring(ls, e, self:str_checkname(ls))
386end
387
388------------------------------------------------------------------------
389-- creates struct entry for a local variable
390-- * used only in new_localvar()
391------------------------------------------------------------------------
392function luaY:registerlocalvar(ls, varname)
393 local fs = ls.fs
394 local f = fs.f
395 self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
396 nil, self.SHRT_MAX, "too many local variables")
397 -- loop to initialize empty f.locvar positions not required
398 f.locvars[fs.nlocvars] = {} -- LocVar
399 f.locvars[fs.nlocvars].varname = varname
400 -- luaC_objbarrier(ls.L, f, varname) /* GC */
401 local nlocvars = fs.nlocvars
402 fs.nlocvars = fs.nlocvars + 1
403 return nlocvars
404end
405
406------------------------------------------------------------------------
407-- creates a new local variable given a name and an offset from nactvar
408-- * used in fornum(), forlist(), parlist(), body()
409------------------------------------------------------------------------
410function luaY:new_localvarliteral(ls, v, n)
411 self:new_localvar(ls, v, n)
412end
413
414------------------------------------------------------------------------
415-- register a local variable, set in active variable list
416------------------------------------------------------------------------
417function luaY:new_localvar(ls, name, n)
418 local fs = ls.fs
419 self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
420 fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
421end
422
423------------------------------------------------------------------------
424-- adds nvars number of new local variables, set debug information
425------------------------------------------------------------------------
426function luaY:adjustlocalvars(ls, nvars)
427 local fs = ls.fs
428 fs.nactvar = fs.nactvar + nvars
429 for i = nvars, 1, -1 do
430 self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
431 end
432end
433
434------------------------------------------------------------------------
435-- removes a number of locals, set debug information
436------------------------------------------------------------------------
437function luaY:removevars(ls, tolevel)
438 local fs = ls.fs
439 while fs.nactvar > tolevel do
440 fs.nactvar = fs.nactvar - 1
441 self:getlocvar(fs, fs.nactvar).endpc = fs.pc
442 end
443end
444
445------------------------------------------------------------------------
446-- returns an existing upvalue index based on the given name, or
447-- creates a new upvalue struct entry and returns the new index
448-- * used only in singlevaraux()
449------------------------------------------------------------------------
450function luaY:indexupvalue(fs, name, v)
451 local f = fs.f
452 for i = 0, f.nups - 1 do
453 if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
454 lua_assert(f.upvalues[i] == name)
455 return i
456 end
457 end
458 -- new one
459 self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
460 self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues,
461 nil, self.MAX_INT, "")
462 -- loop to initialize empty f.upvalues positions not required
463 f.upvalues[f.nups] = name
464 -- luaC_objbarrier(fs->L, f, name); /* GC */
465 lua_assert(v.k == "VLOCAL" or v.k == "VUPVAL")
466 -- this is a partial copy; only k & info fields used
467 fs.upvalues[f.nups] = { k = v.k, info = v.info }
468 local nups = f.nups
469 f.nups = f.nups + 1
470 return nups
471end
472
473------------------------------------------------------------------------
474-- search the local variable namespace of the given fs for a match
475-- * used only in singlevaraux()
476------------------------------------------------------------------------
477function luaY:searchvar(fs, n)
478 for i = fs.nactvar - 1, 0, -1 do
479 if n == self:getlocvar(fs, i).varname then
480 return i
481 end
482 end
483 return -1 -- not found
484end
485
486------------------------------------------------------------------------
487-- * mark upvalue flags in function states up to a given level
488-- * used only in singlevaraux()
489------------------------------------------------------------------------
490function luaY:markupval(fs, level)
491 local bl = fs.bl
492 while bl and bl.nactvar > level do bl = bl.previous end
493 if bl then bl.upval = true end
494end
495
496------------------------------------------------------------------------
497-- handle locals, globals and upvalues and related processing
498-- * search mechanism is recursive, calls itself to search parents
499-- * used only in singlevar()
500------------------------------------------------------------------------
501function luaY:singlevaraux(fs, n, var, base)
502 if fs == nil then -- no more levels?
503 self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
504 return "VGLOBAL"
505 else
506 local v = self:searchvar(fs, n) -- look up at current level
507 if v >= 0 then
508 self:init_exp(var, "VLOCAL", v)
509 if base == 0 then
510 self:markupval(fs, v) -- local will be used as an upval
511 end
512 return "VLOCAL"
513 else -- not found at current level; try upper one
514 if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
515 return "VGLOBAL"
516 end
517 var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL
518 var.k = "VUPVAL" -- upvalue in this level
519 return "VUPVAL"
520 end--if v
521 end--if fs
522end
523
524------------------------------------------------------------------------
525-- consume a name token, creates a variable (global|local|upvalue)
526-- * used in prefixexp(), funcname()
527------------------------------------------------------------------------
528function luaY:singlevar(ls, var)
529 local varname = self:str_checkname(ls)
530 local fs = ls.fs
531 if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
532 var.info = luaK:stringK(fs, varname) -- info points to global name
533 end
534end
535
536------------------------------------------------------------------------
537-- adjust RHS to match LHS in an assignment
538-- * used in assignment(), forlist(), localstat()
539------------------------------------------------------------------------
540function luaY:adjust_assign(ls, nvars, nexps, e)
541 local fs = ls.fs
542 local extra = nvars - nexps
543 if self:hasmultret(e.k) then
544 extra = extra + 1 -- includes call itself
545 if extra <= 0 then extra = 0 end
546 luaK:setreturns(fs, e, extra) -- last exp. provides the difference
547 if extra > 1 then luaK:reserveregs(fs, extra - 1) end
548 else
549 if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression
550 if extra > 0 then
551 local reg = fs.freereg
552 luaK:reserveregs(fs, extra)
553 luaK:_nil(fs, reg, extra)
554 end
555 end
556end
557
558------------------------------------------------------------------------
559-- tracks and limits parsing depth, assert check at end of parsing
560------------------------------------------------------------------------
561function luaY:enterlevel(ls)
562 ls.L.nCcalls = ls.L.nCcalls + 1
563 if ls.L.nCcalls > self.LUAI_MAXCCALLS then
564 luaX:lexerror(ls, "chunk has too many syntax levels", 0)
565 end
566end
567
568------------------------------------------------------------------------
569-- tracks parsing depth, a pair with luaY:enterlevel()
570------------------------------------------------------------------------
571function luaY:leavelevel(ls)
572 ls.L.nCcalls = ls.L.nCcalls - 1
573end
574
575------------------------------------------------------------------------
576-- enters a code unit, initializes elements
577------------------------------------------------------------------------
578function luaY:enterblock(fs, bl, isbreakable)
579 bl.breaklist = luaK.NO_JUMP
580 bl.isbreakable = isbreakable
581 bl.nactvar = fs.nactvar
582 bl.upval = false
583 bl.previous = fs.bl
584 fs.bl = bl
585 lua_assert(fs.freereg == fs.nactvar)
586end
587
588------------------------------------------------------------------------
589-- leaves a code unit, close any upvalues
590------------------------------------------------------------------------
591function luaY:leaveblock(fs)
592 local bl = fs.bl
593 fs.bl = bl.previous
594 self:removevars(fs.ls, bl.nactvar)
595 if bl.upval then
596 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
597 end
598 -- a block either controls scope or breaks (never both)
599 lua_assert(not bl.isbreakable or not bl.upval)
600 lua_assert(bl.nactvar == fs.nactvar)
601 fs.freereg = fs.nactvar -- free registers
602 luaK:patchtohere(fs, bl.breaklist)
603end
604
605------------------------------------------------------------------------
606-- implement the instantiation of a function prototype, append list of
607-- upvalues after the instantiation instruction
608-- * used only in body()
609------------------------------------------------------------------------
610function luaY:pushclosure(ls, func, v)
611 local fs = ls.fs
612 local f = fs.f
613 self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
614 luaP.MAXARG_Bx, "constant table overflow")
615 -- loop to initialize empty f.p positions not required
616 f.p[fs.np] = func.f
617 fs.np = fs.np + 1
618 -- luaC_objbarrier(ls->L, f, func->f); /* C */
619 self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
620 for i = 0, func.f.nups - 1 do
621 local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
622 luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
623 end
624end
625
626------------------------------------------------------------------------
627-- opening of a function
628------------------------------------------------------------------------
629function luaY:open_func(ls, fs)
630 local L = ls.L
631 local f = self:newproto(ls.L)
632 fs.f = f
633 fs.prev = ls.fs -- linked list of funcstates
634 fs.ls = ls
635 fs.L = L
636 ls.fs = fs
637 fs.pc = 0
638 fs.lasttarget = -1
639 fs.jpc = luaK.NO_JUMP
640 fs.freereg = 0
641 fs.nk = 0
642 fs.np = 0
643 fs.nlocvars = 0
644 fs.nactvar = 0
645 fs.bl = nil
646 f.source = ls.source
647 f.maxstacksize = 2 -- registers 0/1 are always valid
648 fs.h = {} -- constant table; was luaH_new call
649 -- anchor table of constants and prototype (to avoid being collected)
650 -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
651 -- setptvalue2s(L, L->top, f); incr_top(L);
652end
653
654------------------------------------------------------------------------
655-- closing of a function
656------------------------------------------------------------------------
657function luaY:close_func(ls)
658 local L = ls.L
659 local fs = ls.fs
660 local f = fs.f
661 self:removevars(ls, 0)
662 luaK:ret(fs, 0, 0) -- final return
663 -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
664 -- f->locvars, f->upvalues; not required for Lua table arrays
665 f.sizecode = fs.pc
666 f.sizelineinfo = fs.pc
667 f.sizek = fs.nk
668 f.sizep = fs.np
669 f.sizelocvars = fs.nlocvars
670 f.sizeupvalues = f.nups
671 --lua_assert(luaG_checkcode(f)) -- currently not implemented
672 lua_assert(fs.bl == nil)
673 ls.fs = fs.prev
674 -- the following is not required for this implementation; kept here
675 -- for completeness
676 -- L->top -= 2; /* remove table and prototype from the stack */
677 -- last token read was anchored in defunct function; must reanchor it
678 if fs then self:anchor_token(ls) end
679end
680
681------------------------------------------------------------------------
682-- parser initialization function
683-- * note additional sub-tables needed for LexState, FuncState
684------------------------------------------------------------------------
685function luaY:parser(L, z, buff, name)
686 local lexstate = {} -- LexState
687 lexstate.t = {}
688 lexstate.lookahead = {}
689 local funcstate = {} -- FuncState
690 funcstate.upvalues = {}
691 funcstate.actvar = {}
692 -- the following nCcalls initialization added for convenience
693 L.nCcalls = 0
694 lexstate.buff = buff
695 luaX:setinput(L, lexstate, z, name)
696 self:open_func(lexstate, funcstate)
697 funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg
698 luaX:next(lexstate) -- read first token
699 self:chunk(lexstate)
700 self:check(lexstate, "TK_EOS")
701 self:close_func(lexstate)
702 lua_assert(funcstate.prev == nil)
703 lua_assert(funcstate.f.nups == 0)
704 lua_assert(lexstate.fs == nil)
705 return funcstate.f
706end
707
708--[[--------------------------------------------------------------------
709-- GRAMMAR RULES
710----------------------------------------------------------------------]]
711
712------------------------------------------------------------------------
713-- parse a function name suffix, for function call specifications
714-- * used in primaryexp(), funcname()
715------------------------------------------------------------------------
716function luaY:field(ls, v)
717 -- field -> ['.' | ':'] NAME
718 local fs = ls.fs
719 local key = {} -- expdesc
720 luaK:exp2anyreg(fs, v)
721 luaX:next(ls) -- skip the dot or colon
722 self:checkname(ls, key)
723 luaK:indexed(fs, v, key)
724end
725
726------------------------------------------------------------------------
727-- parse a table indexing suffix, for constructors, expressions
728-- * used in recfield(), primaryexp()
729------------------------------------------------------------------------
730function luaY:yindex(ls, v)
731 -- index -> '[' expr ']'
732 luaX:next(ls) -- skip the '['
733 self:expr(ls, v)
734 luaK:exp2val(ls.fs, v)
735 self:checknext(ls, "]")
736end
737
738--[[--------------------------------------------------------------------
739-- Rules for Constructors
740----------------------------------------------------------------------]]
741
742--[[--------------------------------------------------------------------
743-- struct ConsControl:
744-- v -- last list item read (table: struct expdesc)
745-- t -- table descriptor (table: struct expdesc)
746-- nh -- total number of 'record' elements
747-- na -- total number of array elements
748-- tostore -- number of array elements pending to be stored
749----------------------------------------------------------------------]]
750
751------------------------------------------------------------------------
752-- parse a table record (hash) field
753-- * used in constructor()
754------------------------------------------------------------------------
755function luaY:recfield(ls, cc)
756 -- recfield -> (NAME | '['exp1']') = exp1
757 local fs = ls.fs
758 local reg = ls.fs.freereg
759 local key, val = {}, {} -- expdesc
760 if ls.t.token == "TK_NAME" then
761 self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
762 self:checkname(ls, key)
763 else -- ls->t.token == '['
764 self:yindex(ls, key)
765 end
766 cc.nh = cc.nh + 1
767 self:checknext(ls, "=")
768 local rkkey = luaK:exp2RK(fs, key)
769 self:expr(ls, val)
770 luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
771 fs.freereg = reg -- free registers
772end
773
774------------------------------------------------------------------------
775-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
776-- * used in constructor()
777------------------------------------------------------------------------
778function luaY:closelistfield(fs, cc)
779 if cc.v.k == "VVOID" then return end -- there is no list item
780 luaK:exp2nextreg(fs, cc.v)
781 cc.v.k = "VVOID"
782 if cc.tostore == luaP.LFIELDS_PER_FLUSH then
783 luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush
784 cc.tostore = 0 -- no more items pending
785 end
786end
787
788------------------------------------------------------------------------
789-- emit a set list instruction at the end of parsing list constructor
790-- * used in constructor()
791------------------------------------------------------------------------
792function luaY:lastlistfield(fs, cc)
793 if cc.tostore == 0 then return end
794 if self:hasmultret(cc.v.k) then
795 luaK:setmultret(fs, cc.v)
796 luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
797 cc.na = cc.na - 1 -- do not count last expression (unknown number of elements)
798 else
799 if cc.v.k ~= "VVOID" then
800 luaK:exp2nextreg(fs, cc.v)
801 end
802 luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
803 end
804end
805
806------------------------------------------------------------------------
807-- parse a table list (array) field
808-- * used in constructor()
809------------------------------------------------------------------------
810function luaY:listfield(ls, cc)
811 self:expr(ls, cc.v)
812 self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
813 cc.na = cc.na + 1
814 cc.tostore = cc.tostore + 1
815end
816
817------------------------------------------------------------------------
818-- parse a table constructor
819-- * used in funcargs(), simpleexp()
820------------------------------------------------------------------------
821function luaY:constructor(ls, t)
822 -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
823 -- field -> recfield | listfield
824 -- fieldsep -> ',' | ';'
825 local fs = ls.fs
826 local line = ls.linenumber
827 local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
828 local cc = {} -- ConsControl
829 cc.v = {}
830 cc.na, cc.nh, cc.tostore = 0, 0, 0
831 cc.t = t
832 self:init_exp(t, "VRELOCABLE", pc)
833 self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
834 luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
835 self:checknext(ls, "{")
836 repeat
837 lua_assert(cc.v.k == "VVOID" or cc.tostore > 0)
838 if ls.t.token == "}" then break end
839 self:closelistfield(fs, cc)
840 local c = ls.t.token
841
842 if c == "TK_NAME" then -- may be listfields or recfields
843 luaX:lookahead(ls)
844 if ls.lookahead.token ~= "=" then -- expression?
845 self:listfield(ls, cc)
846 else
847 self:recfield(ls, cc)
848 end
849 elseif c == "[" then -- constructor_item -> recfield
850 self:recfield(ls, cc)
851 else -- constructor_part -> listfield
852 self:listfield(ls, cc)
853 end
854 until not self:testnext(ls, ",") and not self:testnext(ls, ";")
855 self:check_match(ls, "}", "{", line)
856 self:lastlistfield(fs, cc)
857 luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
858 luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
859end
860
861-- }======================================================================
862
863------------------------------------------------------------------------
864-- parse the arguments (parameters) of a function declaration
865-- * used in body()
866------------------------------------------------------------------------
867function luaY:parlist(ls)
868 -- parlist -> [ param { ',' param } ]
869 local fs = ls.fs
870 local f = fs.f
871 local nparams = 0
872 f.is_vararg = 0
873 if ls.t.token ~= ")" then -- is 'parlist' not empty?
874 repeat
875 local c = ls.t.token
876 if c == "TK_NAME" then -- param -> NAME
877 self:new_localvar(ls, self:str_checkname(ls), nparams)
878 nparams = nparams + 1
879 elseif c == "TK_DOTS" then -- param -> `...'
880 luaX:next(ls)
881-- [[
882-- #if defined(LUA_COMPAT_VARARG)
883 -- use `arg' as default name
884 self:new_localvarliteral(ls, "arg", nparams)
885 nparams = nparams + 1
886 f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
887-- #endif
888--]]
889 f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
890 else
891 luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected")
892 end
893 until f.is_vararg ~= 0 or not self:testnext(ls, ",")
894 end--if
895 self:adjustlocalvars(ls, nparams)
896 -- NOTE: the following works only when HASARG_MASK is 2!
897 f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
898 luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
899end
900
901------------------------------------------------------------------------
902-- parse function declaration body
903-- * used in simpleexp(), localfunc(), funcstat()
904------------------------------------------------------------------------
905function luaY:body(ls, e, needself, line)
906 -- body -> '(' parlist ')' chunk END
907 local new_fs = {} -- FuncState
908 new_fs.upvalues = {}
909 new_fs.actvar = {}
910 self:open_func(ls, new_fs)
911 new_fs.f.lineDefined = line
912 self:checknext(ls, "(")
913 if needself then
914 self:new_localvarliteral(ls, "self", 0)
915 self:adjustlocalvars(ls, 1)
916 end
917 self:parlist(ls)
918 self:checknext(ls, ")")
919 self:chunk(ls)
920 new_fs.f.lastlinedefined = ls.linenumber
921 self:check_match(ls, "TK_END", "TK_FUNCTION", line)
922 self:close_func(ls)
923 self:pushclosure(ls, new_fs, e)
924end
925
926------------------------------------------------------------------------
927-- parse a list of comma-separated expressions
928-- * used is multiple locations
929------------------------------------------------------------------------
930function luaY:explist1(ls, v)
931 -- explist1 -> expr { ',' expr }
932 local n = 1 -- at least one expression
933 self:expr(ls, v)
934 while self:testnext(ls, ",") do
935 luaK:exp2nextreg(ls.fs, v)
936 self:expr(ls, v)
937 n = n + 1
938 end
939 return n
940end
941
942------------------------------------------------------------------------
943-- parse the parameters of a function call
944-- * contrast with parlist(), used in function declarations
945-- * used in primaryexp()
946------------------------------------------------------------------------
947function luaY:funcargs(ls, f)
948 local fs = ls.fs
949 local args = {} -- expdesc
950 local nparams
951 local line = ls.linenumber
952 local c = ls.t.token
953 if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
954 if line ~= ls.lastline then
955 luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
956 end
957 luaX:next(ls)
958 if ls.t.token == ")" then -- arg list is empty?
959 args.k = "VVOID"
960 else
961 self:explist1(ls, args)
962 luaK:setmultret(fs, args)
963 end
964 self:check_match(ls, ")", "(", line)
965 elseif c == "{" then -- funcargs -> constructor
966 self:constructor(ls, args)
967 elseif c == "TK_STRING" then -- funcargs -> STRING
968 self:codestring(ls, args, ls.t.seminfo)
969 luaX:next(ls) -- must use 'seminfo' before 'next'
970 else
971 luaX:syntaxerror(ls, "function arguments expected")
972 return
973 end
974 lua_assert(f.k == "VNONRELOC")
975 local base = f.info -- base register for call
976 if self:hasmultret(args.k) then
977 nparams = self.LUA_MULTRET -- open call
978 else
979 if args.k ~= "VVOID" then
980 luaK:exp2nextreg(fs, args) -- close last argument
981 end
982 nparams = fs.freereg - (base + 1)
983 end
984 self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
985 luaK:fixline(fs, line)
986 fs.freereg = base + 1 -- call remove function and arguments and leaves
987 -- (unless changed) one result
988end
989
990--[[--------------------------------------------------------------------
991-- Expression parsing
992----------------------------------------------------------------------]]
993
994------------------------------------------------------------------------
995-- parses an expression in parentheses or a single variable
996-- * used in primaryexp()
997------------------------------------------------------------------------
998function luaY:prefixexp(ls, v)
999 -- prefixexp -> NAME | '(' expr ')'
1000 local c = ls.t.token
1001 if c == "(" then
1002 local line = ls.linenumber
1003 luaX:next(ls)
1004 self:expr(ls, v)
1005 self:check_match(ls, ")", "(", line)
1006 luaK:dischargevars(ls.fs, v)
1007 elseif c == "TK_NAME" then
1008 self:singlevar(ls, v)
1009 else
1010 luaX:syntaxerror(ls, "unexpected symbol")
1011 end--if c
1012 return
1013end
1014
1015------------------------------------------------------------------------
1016-- parses a prefixexp (an expression in parentheses or a single variable)
1017-- or a function call specification
1018-- * used in simpleexp(), assignment(), exprstat()
1019------------------------------------------------------------------------
1020function luaY:primaryexp(ls, v)
1021 -- primaryexp ->
1022 -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
1023 local fs = ls.fs
1024 self:prefixexp(ls, v)
1025 while true do
1026 local c = ls.t.token
1027 if c == "." then -- field
1028 self:field(ls, v)
1029 elseif c == "[" then -- '[' exp1 ']'
1030 local key = {} -- expdesc
1031 luaK:exp2anyreg(fs, v)
1032 self:yindex(ls, key)
1033 luaK:indexed(fs, v, key)
1034 elseif c == ":" then -- ':' NAME funcargs
1035 local key = {} -- expdesc
1036 luaX:next(ls)
1037 self:checkname(ls, key)
1038 luaK:_self(fs, v, key)
1039 self:funcargs(ls, v)
1040 elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
1041 luaK:exp2nextreg(fs, v)
1042 self:funcargs(ls, v)
1043 else
1044 return
1045 end--if c
1046 end--while
1047end
1048
1049------------------------------------------------------------------------
1050-- parses general expression types, constants handled here
1051-- * used in subexpr()
1052------------------------------------------------------------------------
1053function luaY:simpleexp(ls, v)
1054 -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
1055 -- constructor | FUNCTION body | primaryexp
1056 local c = ls.t.token
1057 if c == "TK_NUMBER" then
1058 self:init_exp(v, "VKNUM", 0)
1059 v.nval = ls.t.seminfo
1060 elseif c == "TK_STRING" then
1061 self:codestring(ls, v, ls.t.seminfo)
1062 elseif c == "TK_NIL" then
1063 self:init_exp(v, "VNIL", 0)
1064 elseif c == "TK_TRUE" then
1065 self:init_exp(v, "VTRUE", 0)
1066 elseif c == "TK_FALSE" then
1067 self:init_exp(v, "VFALSE", 0)
1068 elseif c == "TK_DOTS" then -- vararg
1069 local fs = ls.fs
1070 self:check_condition(ls, fs.f.is_vararg ~= 0,
1071 "cannot use "..self:LUA_QL("...").." outside a vararg function");
1072 -- NOTE: the following substitutes for a bitop, but is value-specific
1073 local is_vararg = fs.f.is_vararg
1074 if is_vararg >= self.VARARG_NEEDSARG then
1075 fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg'
1076 end
1077 self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
1078 elseif c == "{" then -- constructor
1079 self:constructor(ls, v)
1080 return
1081 elseif c == "TK_FUNCTION" then
1082 luaX:next(ls)
1083 self:body(ls, v, false, ls.linenumber)
1084 return
1085 else
1086 self:primaryexp(ls, v)
1087 return
1088 end--if c
1089 luaX:next(ls)
1090end
1091
1092------------------------------------------------------------------------
1093-- Translates unary operators tokens if found, otherwise returns
1094-- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
1095-- * used in subexpr()
1096------------------------------------------------------------------------
1097function luaY:getunopr(op)
1098 if op == "TK_NOT" then
1099 return "OPR_NOT"
1100 elseif op == "-" then
1101 return "OPR_MINUS"
1102 elseif op == "#" then
1103 return "OPR_LEN"
1104 else
1105 return "OPR_NOUNOPR"
1106 end
1107end
1108
1109------------------------------------------------------------------------
1110-- Translates binary operator tokens if found, otherwise returns
1111-- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
1112-- * used in subexpr()
1113------------------------------------------------------------------------
1114luaY.getbinopr_table = {
1115 ["+"] = "OPR_ADD",
1116 ["-"] = "OPR_SUB",
1117 ["*"] = "OPR_MUL",
1118 ["/"] = "OPR_DIV",
1119 ["%"] = "OPR_MOD",
1120 ["^"] = "OPR_POW",
1121 ["TK_CONCAT"] = "OPR_CONCAT",
1122 ["TK_NE"] = "OPR_NE",
1123 ["TK_EQ"] = "OPR_EQ",
1124 ["<"] = "OPR_LT",
1125 ["TK_LE"] = "OPR_LE",
1126 [">"] = "OPR_GT",
1127 ["TK_GE"] = "OPR_GE",
1128 ["TK_AND"] = "OPR_AND",
1129 ["TK_OR"] = "OPR_OR",
1130}
1131function luaY:getbinopr(op)
1132 local opr = self.getbinopr_table[op]
1133 if opr then return opr else return "OPR_NOBINOPR" end
1134end
1135
1136------------------------------------------------------------------------
1137-- the following priority table consists of pairs of left/right values
1138-- for binary operators (was a static const struct); grep for ORDER OPR
1139-- * the following struct is replaced:
1140-- static const struct {
1141-- lu_byte left; /* left priority for each binary operator */
1142-- lu_byte right; /* right priority */
1143-- } priority[] = { /* ORDER OPR */
1144------------------------------------------------------------------------
1145luaY.priority = {
1146 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%'
1147 {10, 9}, {5, 4}, -- power and concat (right associative)
1148 {3, 3}, {3, 3}, -- equality
1149 {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order
1150 {2, 2}, {1, 1} -- logical (and/or)
1151}
1152
1153luaY.UNARY_PRIORITY = 8 -- priority for unary operators
1154
1155------------------------------------------------------------------------
1156-- Parse subexpressions. Includes handling of unary operators and binary
1157-- operators. A subexpr is given the rhs priority level of the operator
1158-- immediately left of it, if any (limit is -1 if none,) and if a binop
1159-- is found, limit is compared with the lhs priority level of the binop
1160-- in order to determine which executes first.
1161------------------------------------------------------------------------
1162
1163------------------------------------------------------------------------
1164-- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1165-- where 'binop' is any binary operator with a priority higher than 'limit'
1166-- * for priority lookups with self.priority[], 1=left and 2=right
1167-- * recursively called
1168-- * used in expr()
1169------------------------------------------------------------------------
1170function luaY:subexpr(ls, v, limit)
1171 self:enterlevel(ls)
1172 local uop = self:getunopr(ls.t.token)
1173 if uop ~= "OPR_NOUNOPR" then
1174 luaX:next(ls)
1175 self:subexpr(ls, v, self.UNARY_PRIORITY)
1176 luaK:prefix(ls.fs, uop, v)
1177 else
1178 self:simpleexp(ls, v)
1179 end
1180 -- expand while operators have priorities higher than 'limit'
1181 local op = self:getbinopr(ls.t.token)
1182 while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
1183 local v2 = {} -- expdesc
1184 luaX:next(ls)
1185 luaK:infix(ls.fs, op, v)
1186 -- read sub-expression with higher priority
1187 local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
1188 luaK:posfix(ls.fs, op, v, v2)
1189 op = nextop
1190 end
1191 self:leavelevel(ls)
1192 return op -- return first untreated operator
1193end
1194
1195------------------------------------------------------------------------
1196-- Expression parsing starts here. Function subexpr is entered with the
1197-- left operator (which is non-existent) priority of -1, which is lower
1198-- than all actual operators. Expr information is returned in parm v.
1199-- * used in multiple locations
1200------------------------------------------------------------------------
1201function luaY:expr(ls, v)
1202 self:subexpr(ls, v, 0)
1203end
1204
1205-- }====================================================================
1206
1207--[[--------------------------------------------------------------------
1208-- Rules for Statements
1209----------------------------------------------------------------------]]
1210
1211------------------------------------------------------------------------
1212-- checks next token, used as a look-ahead
1213-- * returns boolean instead of 0|1
1214-- * used in retstat(), chunk()
1215------------------------------------------------------------------------
1216function luaY:block_follow(token)
1217 if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
1218 or token == "TK_UNTIL" or token == "TK_EOS" then
1219 return true
1220 else
1221 return false
1222 end
1223end
1224
1225------------------------------------------------------------------------
1226-- parse a code block or unit
1227-- * used in multiple functions
1228------------------------------------------------------------------------
1229function luaY:block(ls)
1230 -- block -> chunk
1231 local fs = ls.fs
1232 local bl = {} -- BlockCnt
1233 self:enterblock(fs, bl, false)
1234 self:chunk(ls)
1235 lua_assert(bl.breaklist == luaK.NO_JUMP)
1236 self:leaveblock(fs)
1237end
1238
1239------------------------------------------------------------------------
1240-- structure to chain all variables in the left-hand side of an
1241-- assignment
1242-- struct LHS_assign:
1243-- prev -- (table: struct LHS_assign)
1244-- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
1245------------------------------------------------------------------------
1246
1247------------------------------------------------------------------------
1248-- check whether, in an assignment to a local variable, the local variable
1249-- is needed in a previous assignment (to a table). If so, save original
1250-- local value in a safe place and use this safe copy in the previous
1251-- assignment.
1252-- * used in assignment()
1253------------------------------------------------------------------------
1254function luaY:check_conflict(ls, lh, v)
1255 local fs = ls.fs
1256 local extra = fs.freereg -- eventual position to save local variable
1257 local conflict = false
1258 while lh do
1259 if lh.v.k == "VINDEXED" then
1260 if lh.v.info == v.info then -- conflict?
1261 conflict = true
1262 lh.v.info = extra -- previous assignment will use safe copy
1263 end
1264 if lh.v.aux == v.info then -- conflict?
1265 conflict = true
1266 lh.v.aux = extra -- previous assignment will use safe copy
1267 end
1268 end
1269 lh = lh.prev
1270 end
1271 if conflict then
1272 luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
1273 luaK:reserveregs(fs, 1)
1274 end
1275end
1276
1277------------------------------------------------------------------------
1278-- parse a variable assignment sequence
1279-- * recursively called
1280-- * used in exprstat()
1281------------------------------------------------------------------------
1282function luaY:assignment(ls, lh, nvars)
1283 local e = {} -- expdesc
1284 -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
1285 local c = lh.v.k
1286 self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
1287 or c == "VINDEXED", "syntax error")
1288 if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
1289 local nv = {} -- LHS_assign
1290 nv.v = {}
1291 nv.prev = lh
1292 self:primaryexp(ls, nv.v)
1293 if nv.v.k == "VLOCAL" then
1294 self:check_conflict(ls, lh, nv.v)
1295 end
1296 self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls,
1297 "variables in assignment")
1298 self:assignment(ls, nv, nvars + 1)
1299 else -- assignment -> '=' explist1
1300 self:checknext(ls, "=")
1301 local nexps = self:explist1(ls, e)
1302 if nexps ~= nvars then
1303 self:adjust_assign(ls, nvars, nexps, e)
1304 if nexps > nvars then
1305 ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
1306 end
1307 else
1308 luaK:setoneret(ls.fs, e) -- close last expression
1309 luaK:storevar(ls.fs, lh.v, e)
1310 return -- avoid default
1311 end
1312 end
1313 self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
1314 luaK:storevar(ls.fs, lh.v, e)
1315end
1316
1317------------------------------------------------------------------------
1318-- parse condition in a repeat statement or an if control structure
1319-- * used in repeatstat(), test_then_block()
1320------------------------------------------------------------------------
1321function luaY:cond(ls)
1322 -- cond -> exp
1323 local v = {} -- expdesc
1324 self:expr(ls, v) -- read condition
1325 if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here
1326 luaK:goiftrue(ls.fs, v)
1327 return v.f
1328end
1329
1330------------------------------------------------------------------------
1331-- parse a break statement
1332-- * used in statements()
1333------------------------------------------------------------------------
1334function luaY:breakstat(ls)
1335 -- stat -> BREAK
1336 local fs = ls.fs
1337 local bl = fs.bl
1338 local upval = false
1339 while bl and not bl.isbreakable do
1340 if bl.upval then upval = true end
1341 bl = bl.previous
1342 end
1343 if not bl then
1344 luaX:syntaxerror(ls, "no loop to break")
1345 end
1346 if upval then
1347 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
1348 end
1349 bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
1350end
1351
1352------------------------------------------------------------------------
1353-- parse a while-do control structure, body processed by block()
1354-- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
1355-- the function's implementation can be removed
1356-- * used in statements()
1357------------------------------------------------------------------------
1358function luaY:whilestat(ls, line)
1359 -- whilestat -> WHILE cond DO block END
1360 local fs = ls.fs
1361 local bl = {} -- BlockCnt
1362 luaX:next(ls) -- skip WHILE
1363 local whileinit = luaK:getlabel(fs)
1364 local condexit = self:cond(ls)
1365 self:enterblock(fs, bl, true)
1366 self:checknext(ls, "TK_DO")
1367 self:block(ls)
1368 luaK:patchlist(fs, luaK:jump(fs), whileinit)
1369 self:check_match(ls, "TK_END", "TK_WHILE", line)
1370 self:leaveblock(fs)
1371 luaK:patchtohere(fs, condexit) -- false conditions finish the loop
1372end
1373
1374------------------------------------------------------------------------
1375-- parse a repeat-until control structure, body parsed by chunk()
1376-- * used in statements()
1377------------------------------------------------------------------------
1378function luaY:repeatstat(ls, line)
1379 -- repeatstat -> REPEAT block UNTIL cond
1380 local fs = ls.fs
1381 local repeat_init = luaK:getlabel(fs)
1382 local bl1, bl2 = {}, {} -- BlockCnt
1383 self:enterblock(fs, bl1, true) -- loop block
1384 self:enterblock(fs, bl2, false) -- scope block
1385 luaX:next(ls) -- skip REPEAT
1386 self:chunk(ls)
1387 self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
1388 local condexit = self:cond(ls) -- read condition (inside scope block)
1389 if not bl2.upval then -- no upvalues?
1390 self:leaveblock(fs) -- finish scope
1391 luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop
1392 else -- complete semantics when there are upvalues
1393 self:breakstat(ls) -- if condition then break
1394 luaK:patchtohere(ls.fs, condexit) -- else...
1395 self:leaveblock(fs) -- finish scope...
1396 luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat
1397 end
1398 self:leaveblock(fs) -- finish loop
1399end
1400
1401------------------------------------------------------------------------
1402-- parse the single expressions needed in numerical for loops
1403-- * used in fornum()
1404------------------------------------------------------------------------
1405function luaY:exp1(ls)
1406 local e = {} -- expdesc
1407 self:expr(ls, e)
1408 local k = e.k
1409 luaK:exp2nextreg(ls.fs, e)
1410 return k
1411end
1412
1413------------------------------------------------------------------------
1414-- parse a for loop body for both versions of the for loop
1415-- * used in fornum(), forlist()
1416------------------------------------------------------------------------
1417function luaY:forbody(ls, base, line, nvars, isnum)
1418 -- forbody -> DO block
1419 local bl = {} -- BlockCnt
1420 local fs = ls.fs
1421 self:adjustlocalvars(ls, 3) -- control variables
1422 self:checknext(ls, "TK_DO")
1423 local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP)
1424 or luaK:jump(fs)
1425 self:enterblock(fs, bl, false) -- scope for declared variables
1426 self:adjustlocalvars(ls, nvars)
1427 luaK:reserveregs(fs, nvars)
1428 self:block(ls)
1429 self:leaveblock(fs) -- end of scope for declared variables
1430 luaK:patchtohere(fs, prep)
1431 local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
1432 or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
1433 luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop
1434 luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
1435end
1436
1437------------------------------------------------------------------------
1438-- parse a numerical for loop, calls forbody()
1439-- * used in forstat()
1440------------------------------------------------------------------------
1441function luaY:fornum(ls, varname, line)
1442 -- fornum -> NAME = exp1,exp1[,exp1] forbody
1443 local fs = ls.fs
1444 local base = fs.freereg
1445 self:new_localvarliteral(ls, "(for index)", 0)
1446 self:new_localvarliteral(ls, "(for limit)", 1)
1447 self:new_localvarliteral(ls, "(for step)", 2)
1448 self:new_localvar(ls, varname, 3)
1449 self:checknext(ls, '=')
1450 self:exp1(ls) -- initial value
1451 self:checknext(ls, ",")
1452 self:exp1(ls) -- limit
1453 if self:testnext(ls, ",") then
1454 self:exp1(ls) -- optional step
1455 else -- default step = 1
1456 luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
1457 luaK:reserveregs(fs, 1)
1458 end
1459 self:forbody(ls, base, line, 1, true)
1460end
1461
1462------------------------------------------------------------------------
1463-- parse a generic for loop, calls forbody()
1464-- * used in forstat()
1465------------------------------------------------------------------------
1466function luaY:forlist(ls, indexname)
1467 -- forlist -> NAME {,NAME} IN explist1 forbody
1468 local fs = ls.fs
1469 local e = {} -- expdesc
1470 local nvars = 0
1471 local base = fs.freereg
1472 -- create control variables
1473 self:new_localvarliteral(ls, "(for generator)", nvars)
1474 nvars = nvars + 1
1475 self:new_localvarliteral(ls, "(for state)", nvars)
1476 nvars = nvars + 1
1477 self:new_localvarliteral(ls, "(for control)", nvars)
1478 nvars = nvars + 1
1479 -- create declared variables
1480 self:new_localvar(ls, indexname, nvars)
1481 nvars = nvars + 1
1482 while self:testnext(ls, ",") do
1483 self:new_localvar(ls, self:str_checkname(ls), nvars)
1484 nvars = nvars + 1
1485 end
1486 self:checknext(ls, "TK_IN")
1487 local line = ls.linenumber
1488 self:adjust_assign(ls, 3, self:explist1(ls, e), e)
1489 luaK:checkstack(fs, 3) -- extra space to call generator
1490 self:forbody(ls, base, line, nvars - 3, false)
1491end
1492
1493------------------------------------------------------------------------
1494-- initial parsing for a for loop, calls fornum() or forlist()
1495-- * used in statements()
1496------------------------------------------------------------------------
1497function luaY:forstat(ls, line)
1498 -- forstat -> FOR (fornum | forlist) END
1499 local fs = ls.fs
1500 local bl = {} -- BlockCnt
1501 self:enterblock(fs, bl, true) -- scope for loop and control variables
1502 luaX:next(ls) -- skip `for'
1503 local varname = self:str_checkname(ls) -- first variable name
1504 local c = ls.t.token
1505 if c == "=" then
1506 self:fornum(ls, varname, line)
1507 elseif c == "," or c == "TK_IN" then
1508 self:forlist(ls, varname)
1509 else
1510 luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected")
1511 end
1512 self:check_match(ls, "TK_END", "TK_FOR", line)
1513 self:leaveblock(fs) -- loop scope (`break' jumps to this point)
1514end
1515
1516------------------------------------------------------------------------
1517-- parse part of an if control structure, including the condition
1518-- * used in ifstat()
1519------------------------------------------------------------------------
1520function luaY:test_then_block(ls)
1521 -- test_then_block -> [IF | ELSEIF] cond THEN block
1522 luaX:next(ls) -- skip IF or ELSEIF
1523 local condexit = self:cond(ls)
1524 self:checknext(ls, "TK_THEN")
1525 self:block(ls) -- `then' part
1526 return condexit
1527end
1528
1529------------------------------------------------------------------------
1530-- parse an if control structure
1531-- * used in statements()
1532------------------------------------------------------------------------
1533function luaY:ifstat(ls, line)
1534 -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
1535 local fs = ls.fs
1536 local escapelist = luaK.NO_JUMP
1537 local flist = self:test_then_block(ls) -- IF cond THEN block
1538 while ls.t.token == "TK_ELSEIF" do
1539 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1540 luaK:patchtohere(fs, flist)
1541 flist = self:test_then_block(ls) -- ELSEIF cond THEN block
1542 end
1543 if ls.t.token == "TK_ELSE" then
1544 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1545 luaK:patchtohere(fs, flist)
1546 luaX:next(ls) -- skip ELSE (after patch, for correct line info)
1547 self:block(ls) -- 'else' part
1548 else
1549 escapelist = luaK:concat(fs, escapelist, flist)
1550 end
1551 luaK:patchtohere(fs, escapelist)
1552 self:check_match(ls, "TK_END", "TK_IF", line)
1553end
1554
1555------------------------------------------------------------------------
1556-- parse a local function statement
1557-- * used in statements()
1558------------------------------------------------------------------------
1559function luaY:localfunc(ls)
1560 local v, b = {}, {} -- expdesc
1561 local fs = ls.fs
1562 self:new_localvar(ls, self:str_checkname(ls), 0)
1563 self:init_exp(v, "VLOCAL", fs.freereg)
1564 luaK:reserveregs(fs, 1)
1565 self:adjustlocalvars(ls, 1)
1566 self:body(ls, b, false, ls.linenumber)
1567 luaK:storevar(fs, v, b)
1568 -- debug information will only see the variable after this point!
1569 self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
1570end
1571
1572------------------------------------------------------------------------
1573-- parse a local variable declaration statement
1574-- * used in statements()
1575------------------------------------------------------------------------
1576function luaY:localstat(ls)
1577 -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
1578 local nvars = 0
1579 local nexps
1580 local e = {} -- expdesc
1581 repeat
1582 self:new_localvar(ls, self:str_checkname(ls), nvars)
1583 nvars = nvars + 1
1584 until not self:testnext(ls, ",")
1585 if self:testnext(ls, "=") then
1586 nexps = self:explist1(ls, e)
1587 else
1588 e.k = "VVOID"
1589 nexps = 0
1590 end
1591 self:adjust_assign(ls, nvars, nexps, e)
1592 self:adjustlocalvars(ls, nvars)
1593end
1594
1595------------------------------------------------------------------------
1596-- parse a function name specification
1597-- * used in funcstat()
1598------------------------------------------------------------------------
1599function luaY:funcname(ls, v)
1600 -- funcname -> NAME {field} [':' NAME]
1601 local needself = false
1602 self:singlevar(ls, v)
1603 while ls.t.token == "." do
1604 self:field(ls, v)
1605 end
1606 if ls.t.token == ":" then
1607 needself = true
1608 self:field(ls, v)
1609 end
1610 return needself
1611end
1612
1613------------------------------------------------------------------------
1614-- parse a function statement
1615-- * used in statements()
1616------------------------------------------------------------------------
1617function luaY:funcstat(ls, line)
1618 -- funcstat -> FUNCTION funcname body
1619 local v, b = {}, {} -- expdesc
1620 luaX:next(ls) -- skip FUNCTION
1621 local needself = self:funcname(ls, v)
1622 self:body(ls, b, needself, line)
1623 luaK:storevar(ls.fs, v, b)
1624 luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
1625end
1626
1627------------------------------------------------------------------------
1628-- parse a function call with no returns or an assignment statement
1629-- * used in statements()
1630------------------------------------------------------------------------
1631function luaY:exprstat(ls)
1632 -- stat -> func | assignment
1633 local fs = ls.fs
1634 local v = {} -- LHS_assign
1635 v.v = {}
1636 self:primaryexp(ls, v.v)
1637 if v.v.k == "VCALL" then -- stat -> func
1638 luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results
1639 else -- stat -> assignment
1640 v.prev = nil
1641 self:assignment(ls, v, 1)
1642 end
1643end
1644
1645------------------------------------------------------------------------
1646-- parse a return statement
1647-- * used in statements()
1648------------------------------------------------------------------------
1649function luaY:retstat(ls)
1650 -- stat -> RETURN explist
1651 local fs = ls.fs
1652 local e = {} -- expdesc
1653 local first, nret -- registers with returned values
1654 luaX:next(ls) -- skip RETURN
1655 if self:block_follow(ls.t.token) or ls.t.token == ";" then
1656 first, nret = 0, 0 -- return no values
1657 else
1658 nret = self:explist1(ls, e) -- optional return values
1659 if self:hasmultret(e.k) then
1660 luaK:setmultret(fs, e)
1661 if e.k == "VCALL" and nret == 1 then -- tail call?
1662 luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
1663 lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
1664 end
1665 first = fs.nactvar
1666 nret = self.LUA_MULTRET -- return all values
1667 else
1668 if nret == 1 then -- only one single value?
1669 first = luaK:exp2anyreg(fs, e)
1670 else
1671 luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
1672 first = fs.nactvar -- return all 'active' values
1673 lua_assert(nret == fs.freereg - first)
1674 end
1675 end--if
1676 end--if
1677 luaK:ret(fs, first, nret)
1678end
1679
1680------------------------------------------------------------------------
1681-- initial parsing for statements, calls a lot of functions
1682-- * returns boolean instead of 0|1
1683-- * used in chunk()
1684------------------------------------------------------------------------
1685function luaY:statement(ls)
1686 local line = ls.linenumber -- may be needed for error messages
1687 local c = ls.t.token
1688 if c == "TK_IF" then -- stat -> ifstat
1689 self:ifstat(ls, line)
1690 return false
1691 elseif c == "TK_WHILE" then -- stat -> whilestat
1692 self:whilestat(ls, line)
1693 return false
1694 elseif c == "TK_DO" then -- stat -> DO block END
1695 luaX:next(ls) -- skip DO
1696 self:block(ls)
1697 self:check_match(ls, "TK_END", "TK_DO", line)
1698 return false
1699 elseif c == "TK_FOR" then -- stat -> forstat
1700 self:forstat(ls, line)
1701 return false
1702 elseif c == "TK_REPEAT" then -- stat -> repeatstat
1703 self:repeatstat(ls, line)
1704 return false
1705 elseif c == "TK_FUNCTION" then -- stat -> funcstat
1706 self:funcstat(ls, line)
1707 return false
1708 elseif c == "TK_LOCAL" then -- stat -> localstat
1709 luaX:next(ls) -- skip LOCAL
1710 if self:testnext(ls, "TK_FUNCTION") then -- local function?
1711 self:localfunc(ls)
1712 else
1713 self:localstat(ls)
1714 end
1715 return false
1716 elseif c == "TK_RETURN" then -- stat -> retstat
1717 self:retstat(ls)
1718 return true -- must be last statement
1719 elseif c == "TK_BREAK" then -- stat -> breakstat
1720 luaX:next(ls) -- skip BREAK
1721 self:breakstat(ls)
1722 return true -- must be last statement
1723 else
1724 self:exprstat(ls)
1725 return false -- to avoid warnings
1726 end--if c
1727end
1728
1729------------------------------------------------------------------------
1730-- parse a chunk, which consists of a bunch of statements
1731-- * used in parser(), body(), block(), repeatstat()
1732------------------------------------------------------------------------
1733function luaY:chunk(ls)
1734 -- chunk -> { stat [';'] }
1735 local islast = false
1736 self:enterlevel(ls)
1737 while not islast and not self:block_follow(ls.t.token) do
1738 islast = self:statement(ls)
1739 self:testnext(ls, ";")
1740 lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg and
1741 ls.fs.freereg >= ls.fs.nactvar)
1742 ls.fs.freereg = ls.fs.nactvar -- free registers
1743 end
1744 self:leavelevel(ls)
1745end
1746
1747-- }======================================================================
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua
new file mode 100644
index 0000000..5f12f79
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/luac.lua
@@ -0,0 +1,71 @@
1--[[--------------------------------------------------------------------
2
3 luac.lua
4 Primitive luac in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * based on luac.lua in the test directory of the 5.1.2 distribution
18-- * usage: lua luac.lua file.lua
19----------------------------------------------------------------------]]
20
21------------------------------------------------------------------------
22-- load and initialize the required modules
23------------------------------------------------------------------------
24dofile("lzio.lua")
25dofile("llex.lua")
26dofile("lopcodes.lua")
27dofile("ldump.lua")
28dofile("lcode.lua")
29dofile("lparser.lua")
30
31luaX:init() -- required by llex
32local LuaState = {} -- dummy, not actually used, but retained since
33 -- the intention is to complete a straight port
34
35------------------------------------------------------------------------
36-- interfacing to yueliang
37------------------------------------------------------------------------
38
39-- currently asserts are enabled because the codebase hasn't been tested
40-- much (if you don't want asserts, just comment them out)
41function lua_assert(test)
42 if not test then error("assertion failed!") end
43end
44
45function yloadfile(filename)
46 -- luaZ:make_getF returns a file chunk reader
47 -- luaZ:init returns a zio input stream
48 local zio = luaZ:init(luaZ:make_getF(filename), nil)
49 if not zio then return end
50 -- luaY:parser parses the input stream
51 -- func is the function prototype in tabular form; in C, func can
52 -- now be used directly by the VM, this can't be done in Lua
53 local func = luaY:parser(LuaState, zio, nil, "@"..filename)
54 -- luaU:make_setS returns a string chunk writer
55 local writer, buff = luaU:make_setS()
56 -- luaU:dump builds a binary chunk
57 luaU:dump(LuaState, func, writer, buff)
58 -- a string.dump equivalent in returned
59 return buff.data
60end
61
62------------------------------------------------------------------------
63-- command line interface
64------------------------------------------------------------------------
65
66assert(arg[1] ~= nil and arg[2] == nil, "usage: lua luac.lua file.lua")
67local f = assert(io.open("luac.out","wb"))
68assert(f:write(assert(yloadfile(arg[1]))))
69assert(io.close(f))
70
71--end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua
new file mode 100644
index 0000000..b5ea985
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lzio.lua
@@ -0,0 +1,125 @@
1--[[--------------------------------------------------------------------
2
3 lzio.lua
4 Lua buffered streams in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * EOZ is implemented as a string, "EOZ"
18-- * Format of z structure (ZIO)
19-- z.n -- bytes still unread
20-- z.p -- last read position position in buffer
21-- z.reader -- chunk reader function
22-- z.data -- additional data
23-- * Current position, p, is now last read index instead of a pointer
24--
25-- Not implemented:
26-- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk
27-- * luaZ_read: used only in lundump.c:ezread to read +1 bytes
28-- * luaZ_openspace: dropped; let Lua handle buffers as strings (used in
29-- lundump.c:LoadString & lvm.c:luaV_concat)
30-- * luaZ buffer macros: dropped; buffers are handled as strings
31-- * lauxlib.c:getF reader implementation has an extraline flag to
32-- skip over a shbang (#!) line, this is not implemented here
33--
34-- Added:
35-- (both of the following are vaguely adapted from lauxlib.c)
36-- * luaZ:make_getS: create Reader from a string
37-- * luaZ:make_getF: create Reader that reads from a file
38--
39-- Changed in 5.1.x:
40-- * Chunkreader renamed to Reader (ditto with Chunkwriter)
41-- * Zio struct: no more name string, added Lua state for reader
42-- (however, Yueliang readers do not require a Lua state)
43----------------------------------------------------------------------]]
44
45luaZ = {}
46
47------------------------------------------------------------------------
48-- * reader() should return a string, or nil if nothing else to parse.
49-- Additional data can be set only during stream initialization
50-- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string)
51-- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h)
52-- * Original Reader typedef:
53-- const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
54-- * This Lua chunk reader implementation:
55-- returns string or nil, no arguments to function
56------------------------------------------------------------------------
57
58------------------------------------------------------------------------
59-- create a chunk reader from a source string
60------------------------------------------------------------------------
61function luaZ:make_getS(buff)
62 local b = buff
63 return function() -- chunk reader anonymous function here
64 if not b then return nil end
65 local data = b
66 b = nil
67 return data
68 end
69end
70
71------------------------------------------------------------------------
72-- create a chunk reader from a source file
73------------------------------------------------------------------------
74function luaZ:make_getF(filename)
75 local LUAL_BUFFERSIZE = 512
76 local h = io.open(filename, "r")
77 if not h then return nil end
78 return function() -- chunk reader anonymous function here
79 if not h or io.type(h) == "closed file" then return nil end
80 local buff = h:read(LUAL_BUFFERSIZE)
81 if not buff then h:close(); h = nil end
82 return buff
83 end
84end
85
86------------------------------------------------------------------------
87-- creates a zio input stream
88-- returns the ZIO structure, z
89------------------------------------------------------------------------
90function luaZ:init(reader, data)
91 if not reader then return end
92 local z = {}
93 z.reader = reader
94 z.data = data or ""
95 z.name = name
96 -- set up additional data for reading
97 if not data or data == "" then z.n = 0 else z.n = #data end
98 z.p = 0
99 return z
100end
101
102------------------------------------------------------------------------
103-- fill up input buffer
104------------------------------------------------------------------------
105function luaZ:fill(z)
106 local buff = z.reader()
107 z.data = buff
108 if not buff or buff == "" then return "EOZ" end
109 z.n, z.p = #buff - 1, 1
110 return string.sub(buff, 1, 1)
111end
112
113------------------------------------------------------------------------
114-- get next character from the input stream
115-- * local n, p are used to optimize code generation
116------------------------------------------------------------------------
117function luaZ:zgetc(z)
118 local n, p = z.n, z.p + 1
119 if n > 0 then
120 z.n, z.p = n - 1, p
121 return string.sub(z.data, p, p)
122 else
123 return self:fill(z)
124 end
125end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua
new file mode 100644
index 0000000..b904470
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/bench_llex.lua
@@ -0,0 +1,99 @@
1--[[--------------------------------------------------------------------
2
3 bench_llex.lua
4 Benchmark test for llex.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15dofile("../lzio.lua")
16dofile("../llex.lua")
17luaX:init()
18
19------------------------------------------------------------------------
20-- load in a standard set of sample files
21-- * file set is 5.0.3 front end set sans luac.lua
22------------------------------------------------------------------------
23
24local fileset, totalsize = {}, 0
25for fn in string.gmatch([[
26../../orig-5.0.3/lcode.lua
27../../orig-5.0.3/ldump.lua
28../../orig-5.0.3/llex.lua
29../../orig-5.0.3/lopcodes.lua
30../../orig-5.0.3/lparser.lua
31../../orig-5.0.3/lzio.lua
32]], "%S+") do
33 fileset[#fileset+1] = fn
34end
35
36for i = 1, #fileset do
37 local fn = fileset[i]
38 local inf = io.open(fn, "rb")
39 if not inf then
40 error("failed to open "..fn.." for reading")
41 end
42 local data = inf:read("*a")
43 local data_sz = #data
44 inf:close()
45 if not data or data_sz == 0 then
46 error("failed to read data from "..fn.." or file is zero-length")
47 end
48 totalsize = totalsize + data_sz
49 fileset[i] = data
50end
51
52------------------------------------------------------------------------
53-- benchmark tester
54------------------------------------------------------------------------
55
56local DURATION = 5 -- how long the benchmark should run
57
58local L = {} -- LuaState
59local LS = {} -- LexState
60
61local time = os.time
62local lexedsize = 0
63local tnow, elapsed = time(), 0
64
65while time() == tnow do end -- wait for second to click over
66tnow = time()
67
68while true do
69 for i = 1, #fileset do
70 ------------------------------------------------------------
71 local chunk = fileset[i]
72 local z = luaZ:init(luaZ:make_getS(chunk), nil)
73 luaX:setinput(L, LS, z, "=string")
74 while true do
75 LS.t.token = luaX:llex(LS, LS.t)
76 local tok, seminfo = LS.t.token, LS.t.seminfo
77 if tok == "TK_EOS" then break end
78 end
79 ------------------------------------------------------------
80 lexedsize = lexedsize + #chunk
81 if time() > tnow then
82 tnow = time()
83 elapsed = elapsed + 1
84 if elapsed >= DURATION then
85 -- report performance of lexer
86 lexedsize = lexedsize / 1024
87 local speed = lexedsize / DURATION
88 print("Lexer performance:")
89 print("Size of data lexed (KB): "..string.format("%.1f", lexedsize))
90 print("Speed of lexer (KB/s): "..string.format("%.1f", speed))
91 -- repeat until user breaks program
92 elapsed = 0
93 end
94 end
95 ------------------------------------------------------------
96 end--for
97end--while
98
99-- end of script
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua
new file mode 100644
index 0000000..dc6eaee
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/sample.lua
@@ -0,0 +1,3 @@
1local a = 47
2local b = "hello, world!"
3print(a, b)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua
new file mode 100644
index 0000000..2d113dd
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_ldump.lua
@@ -0,0 +1,99 @@
1--[[--------------------------------------------------------------------
2
3 test_ldump.lua
4 Test for ldump.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15------------------------------------------------------------------------
16-- test dump chunkwriter style
17------------------------------------------------------------------------
18
19dofile("../lopcodes.lua")
20dofile("../ldump.lua")
21
22-- Original typedef:
23--int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud);
24
25local MyWriter, MyBuff = luaU:make_setS()
26if not MyWriter then
27 error("failed to initialize using make_setS")
28end
29MyWriter("hello, ", MyBuff)
30MyWriter("world!", MyBuff)
31print(MyBuff.data)
32
33local MyWriter, MyBuff = luaU:make_setF("try.txt")
34if not MyWriter then
35 error("failed to initialize using make_setF")
36end
37MyWriter("hello, ", MyBuff)
38MyWriter("world!", MyBuff)
39MyWriter(nil, MyBuff)
40
41------------------------------------------------------------------------
42-- test output of a function prototype
43-- * data can be copied from a ChunkSpy listing output
44------------------------------------------------------------------------
45-- local a = 47
46-- local b = "hello, world!"
47-- print(a, b)
48------------------------------------------------------------------------
49
50local F = {}
51F.source = "sample.lua"
52F.lineDefined = 0
53F.lastlinedefined = 0
54F.nups = 0
55F.numparams = 0
56F.is_vararg = 2
57F.maxstacksize = 5
58F.sizecode = 7
59F.code = {}
60F.code[0] = { OP = 1, A = 0, Bx = 0 }
61F.code[1] = { OP = 1, A = 1, Bx = 1 }
62F.code[2] = { OP = 5, A = 2, Bx = 2 }
63F.code[3] = { OP = 0, A = 3, B = 0, C = 0 }
64F.code[4] = { OP = 0, A = 4, B = 1, C = 0 }
65F.code[5] = { OP = 28, A = 2, B = 3, C = 1 }
66F.code[6] = { OP = 30, A = 0, B = 1, C = 0 }
67F.sizek = 3
68F.k = {}
69F.k[0] = { value = 47 }
70F.k[1] = { value = "hello, world!" }
71F.k[2] = { value = "print" }
72F.sizep = 0
73F.p = {}
74F.sizelineinfo = 7
75F.lineinfo = {}
76F.lineinfo[0] = 1
77F.lineinfo[1] = 2
78F.lineinfo[2] = 3
79F.lineinfo[3] = 3
80F.lineinfo[4] = 3
81F.lineinfo[5] = 3
82F.lineinfo[6] = 3
83F.sizelocvars = 2
84F.locvars = {}
85F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 }
86F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 }
87F.sizeupvalues = 0
88F.upvalues = {}
89
90local L = {}
91--[[
92local Writer, Buff = luaU:make_setS()
93luaU:dump(L, F, Writer, Buff)
94for i = 1, string.len(Buff.data) do
95 io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ")
96end
97--]]
98local Writer, Buff = luaU:make_setF("try.out")
99luaU:dump(L, F, Writer, Buff)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua
new file mode 100644
index 0000000..0548476
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_llex.lua
@@ -0,0 +1,580 @@
1--[[--------------------------------------------------------------------
2
3 test_llex.lua
4 Test for llex.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15------------------------------------------------------------------------
16-- if BRIEF is not set to false, auto-test will silently succeed
17------------------------------------------------------------------------
18BRIEF = true -- if set to true, messages are less verbose
19
20dofile("../lzio.lua")
21dofile("../llex.lua")
22luaX:init()
23
24------------------------------------------------------------------------
25-- simple manual tests
26------------------------------------------------------------------------
27
28--[[
29local L = {} -- LuaState
30local LS = {} -- LexState
31
32local function dump(z)
33 luaX:setinput(L, LS, z, z.name)
34 while true do
35 LS.t.token = luaX:lex(LS, LS.t)
36 local tok, seminfo = LS.t.token, LS.t.seminfo
37 if tok == "TK_NAME" then
38 seminfo = " "..seminfo
39 elseif tok == "TK_NUMBER" then
40 seminfo = " "..seminfo
41 elseif tok == "TK_STRING" then
42 seminfo = " '"..seminfo.."'"
43 else
44 seminfo = ""
45 end
46 io.stdout:write(tok..seminfo.."\n")
47 if tok == "TK_EOS" then break end
48 end
49end
50
51local function try_string(chunk)
52 dump(luaZ:init(luaZ:make_getS(chunk), nil, "=string"))
53end
54local function try_file(filename)
55 dump(luaZ:init(luaZ:make_getF(filename), nil, filename))
56end
57
58z = try_string("local c = luaZ:zgetc(z)")
59z = try_file("test_lzio.lua")
60z = try_file("test_llex.lua")
61os.exit()
62--]]
63
64------------------------------------------------------------------------
65-- auto-testing of simple test cases to validate lexer behaviour:
66-- * NOTE coverage has not been checked; not comprehensive
67-- * only test cases with non-empty comments are processed
68-- * if no result, then the output is displayed for manual decision
69-- (output may be used to set expected success or fail text)
70-- * cases expected to be successful may be a partial match
71-- * cases expected to fail may also be a partial match
72------------------------------------------------------------------------
73
74-- [[
75local function auto_test()
76 local PASS, FAIL = true, false
77 ------------------------------------------------------------------
78 -- table of test cases
79 ------------------------------------------------------------------
80 local test_cases =
81 {
82 -------------------------------------------------------------
83 --{ "comment", -- comment about the test
84 -- "chunk", -- chunk to test
85 -- PASS, -- PASS or FAIL outcome
86 -- "output", -- output to compare against
87 --},
88 -------------------------------------------------------------
89 { "empty chunk string, test EOS",
90 "",
91 PASS, "1 TK_EOS",
92 },
93 -------------------------------------------------------------
94 { "line number counting",
95 "\n\n\r\n",
96 PASS, "4 TK_EOS",
97 },
98 -------------------------------------------------------------
99 { "various whitespaces",
100 " \n\t\t\n \t \t \n\n",
101 PASS, "5 TK_EOS",
102 },
103 -------------------------------------------------------------
104 { "short comment ending in EOS",
105 "-- moo moo",
106 PASS, "1 TK_EOS",
107 },
108 -------------------------------------------------------------
109 { "short comment ending in newline",
110 "-- moo moo\n",
111 PASS, "2 TK_EOS",
112 },
113 -------------------------------------------------------------
114 { "several lines of short comments",
115 "--moo\n-- moo moo\n\n--\tmoo\n",
116 PASS, "5 TK_EOS",
117 },
118 -------------------------------------------------------------
119 { "basic block comment 1",
120 "--[[bovine]]",
121 PASS, "1 TK_EOS",
122 },
123 -------------------------------------------------------------
124 { "basic block comment 2",
125 "--[=[bovine]=]",
126 PASS, "1 TK_EOS",
127 },
128 -------------------------------------------------------------
129 { "basic block comment 3",
130 "--[====[-[[bovine]]-]====]",
131 PASS, "1 TK_EOS",
132 },
133 -------------------------------------------------------------
134 { "unterminated block comment 1",
135 "--[[bovine",
136 FAIL, ":1: unfinished long comment near '<eof>'",
137 },
138 -------------------------------------------------------------
139 { "unterminated block comment 2",
140 "--[==[bovine",
141 FAIL, ":1: unfinished long comment near '<eof>'",
142 },
143 -------------------------------------------------------------
144 { "unterminated block comment 3",
145 "--[[bovine]",
146 FAIL, ":1: unfinished long comment near '<eof>'",
147 },
148 -------------------------------------------------------------
149 { "unterminated block comment 4",
150 "--[[bovine\nmoo moo\nwoof",
151 FAIL, ":3: unfinished long comment near '<eof>'",
152 },
153 -------------------------------------------------------------
154 { "basic long string 1",
155 "\n[[bovine]]\n",
156 PASS, "2 TK_STRING = bovine\n3 TK_EOS",
157 },
158 -------------------------------------------------------------
159 { "basic long string 2",
160 "\n[=[bovine]=]\n",
161 PASS, "2 TK_STRING = bovine\n3 TK_EOS",
162 },
163 -------------------------------------------------------------
164 { "first newline consumed in long string",
165 "[[\nmoo]]",
166 PASS, "2 TK_STRING = moo\n2 TK_EOS",
167 },
168 -------------------------------------------------------------
169 { "multiline long string 1",
170 "[[moo\nmoo moo\n]]",
171 PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS",
172 },
173 -------------------------------------------------------------
174 { "multiline long string 2",
175 "[===[moo\n[=[moo moo]=]\n]===]",
176 PASS, "3 TK_STRING = moo\n[=[moo moo]=]\n\n3 TK_EOS",
177 },
178 -------------------------------------------------------------
179 { "unterminated long string 1",
180 "\n[[\nbovine",
181 FAIL, ":3: unfinished long string near '<eof>'",
182 },
183 -------------------------------------------------------------
184 { "unterminated long string 2",
185 "[[bovine]",
186 FAIL, ":1: unfinished long string near '<eof>'",
187 },
188 -------------------------------------------------------------
189 { "unterminated long string 2",
190 "[==[bovine]==",
191 FAIL, ":1: unfinished long string near '<eof>'",
192 },
193 -------------------------------------------------------------
194 { "complex long string 1",
195 "[=[moo[[moo]]moo]=]",
196 PASS, "moo[[moo]]moo",
197 },
198 -------------------------------------------------------------
199 { "complex long string 2",
200 "[=[moo[[moo[[[[]]]]moo]]moo]=]",
201 PASS, "moo[[moo[[[[]]]]moo]]moo",
202 },
203 -------------------------------------------------------------
204 { "complex long string 3",
205 "[=[[[[[]]]][[[[]]]]]=]",
206 PASS, "[[[[]]]][[[[]]]]",
207 },
208 -------------------------------------------------------------
209 { "deprecated long string 1",
210 "[[moo[[moo]]moo]]",
211 FAIL, ":1: nesting of [[...]] is deprecated near '['",
212 },
213 -------------------------------------------------------------
214 { "deprecated long string 2",
215 "[[[[ \n",
216 FAIL, ":1: nesting of [[...]] is deprecated near '['",
217 },
218 -------------------------------------------------------------
219 { "deprecated long string 3",
220 "[[moo[[moo[[[[]]]]moo]]moo]]",
221 FAIL, ":1: nesting of [[...]] is deprecated near '['",
222 },
223 -------------------------------------------------------------
224 { "deprecated long string 4",
225 "[[[[[[]]]][[[[]]]]]]",
226 FAIL, ":1: nesting of [[...]] is deprecated near '['",
227 },
228 -------------------------------------------------------------
229 { "brackets in long strings 1",
230 "[[moo[moo]]",
231 PASS, "moo[moo",
232 },
233 -------------------------------------------------------------
234 { "brackets in long strings 2",
235 "[=[moo[[moo]moo]]moo]=]",
236 PASS, "moo[[moo]moo]]moo",
237 },
238 -------------------------------------------------------------
239 { "unprocessed escapes in long strings",
240 [[ [=[\a\b\f\n\r\t\v\123]=] ]],
241 PASS, [[\a\b\f\n\r\t\v\123]],
242 },
243 -------------------------------------------------------------
244 { "unbalanced long string",
245 "[[moo]]moo]]",
246 PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS",
247 },
248 -------------------------------------------------------------
249 { "keywords 1",
250 "and break do else",
251 PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS",
252 },
253 -------------------------------------------------------------
254 { "keywords 2",
255 "elseif end false for",
256 PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS",
257 },
258 -------------------------------------------------------------
259 { "keywords 3",
260 "function if in local nil",
261 PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS",
262 },
263 -------------------------------------------------------------
264 { "keywords 4",
265 "not or repeat return",
266 PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS",
267 },
268 -------------------------------------------------------------
269 { "keywords 5",
270 "then true until while",
271 PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS",
272 },
273 -------------------------------------------------------------
274 { "concat and dots",
275 ".. ...",
276 PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS",
277 },
278 -------------------------------------------------------------
279 -- NOTE: in Lua 5.1.x, shbang handling is no longer performed
280 -- in the lexer; it is now done in lauxlib.c (luaL_loadfile)
281 -- so the following cannot be performed by the lexer...
282 -------------------------------------------------------------
283 --{ "shbang handling 1",
284 -- "#blahblah",
285 -- PASS, "1 TK_EOS",
286 --},
287 -------------------------------------------------------------
288 --{ "shbang handling 2",
289 -- "#blahblah\nmoo moo\n",
290 -- PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS",
291 --},
292 -------------------------------------------------------------
293 { "empty string",
294 [['']],
295 PASS, "1 TK_STRING = \n1 TK_EOS",
296 },
297 -------------------------------------------------------------
298 { "single-quoted string",
299 [['bovine']],
300 PASS, "1 TK_STRING = bovine\n1 TK_EOS",
301 },
302 -------------------------------------------------------------
303 { "double-quoted string",
304 [["bovine"]],
305 PASS, "1 TK_STRING = bovine\n1 TK_EOS",
306 },
307 -------------------------------------------------------------
308 { "unterminated string 1",
309 [['moo ]],
310 FAIL, ":1: unfinished string near '<eof>'",
311 },
312 -------------------------------------------------------------
313 { "unterminated string 2",
314 [["moo \n]],
315 FAIL, ":1: unfinished string near '<eof>'",
316 },
317 -------------------------------------------------------------
318 { "escaped newline in string, line number counted",
319 "\"moo\\\nmoo\\\nmoo\"",
320 PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS",
321 },
322 -------------------------------------------------------------
323 { "escaped characters in string 1",
324 [["moo\amoo"]],
325 PASS, "1 TK_STRING = moo\amoo",
326 },
327 -------------------------------------------------------------
328 { "escaped characters in string 2",
329 [["moo\bmoo"]],
330 PASS, "1 TK_STRING = moo\bmoo",
331 },
332 -------------------------------------------------------------
333 { "escaped characters in string 3",
334 [["moo\f\n\r\t\vmoo"]],
335 PASS, "1 TK_STRING = moo\f\n\r\t\vmoo",
336 },
337 -------------------------------------------------------------
338 { "escaped characters in string 4",
339 [["\\ \" \' \? \[ \]"]],
340 PASS, "1 TK_STRING = \\ \" \' \? \[ \]",
341 },
342 -------------------------------------------------------------
343 { "escaped characters in string 5",
344 [["\z \k \: \;"]],
345 PASS, "1 TK_STRING = z k : ;",
346 },
347 -------------------------------------------------------------
348 { "escaped characters in string 6",
349 [["\8 \65 \160 \180K \097097"]],
350 PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n",
351 },
352 -------------------------------------------------------------
353 { "escaped characters in string 7",
354 [["\666"]],
355 FAIL, ":1: escape sequence too large near '\"'",
356 },
357 -------------------------------------------------------------
358 { "simple numbers",
359 "123 123+",
360 PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS",
361 },
362 -------------------------------------------------------------
363 { "longer numbers",
364 "1234567890 12345678901234567890",
365 PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n",
366 },
367 -------------------------------------------------------------
368 { "fractional numbers",
369 ".123 .12345678901234567890",
370 PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n",
371 },
372 -------------------------------------------------------------
373 { "more numbers with decimal points",
374 "12345.67890",
375 PASS, "1 TK_NUMBER = 12345.6789\n",
376 },
377 -------------------------------------------------------------
378 { "malformed number with decimal points",
379 "1.1.",
380 FAIL, ":1: malformed number near '1.1.'",
381 },
382 -------------------------------------------------------------
383 { "double decimal points",
384 ".1.1",
385 FAIL, ":1: malformed number near '.1.1'",
386 },
387 -------------------------------------------------------------
388 { "double dots within numbers",
389 "1..1",
390 FAIL, ":1: malformed number near '1..1'",
391 },
392 -------------------------------------------------------------
393 { "incomplete exponential numbers",
394 "123e",
395 FAIL, ":1: malformed number near '123e'",
396 },
397 -------------------------------------------------------------
398 { "exponential numbers 1",
399 "1234e5 1234e5.",
400 PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'",
401 },
402 -------------------------------------------------------------
403 { "exponential numbers 2",
404 "1234e56 1.23e123",
405 PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n",
406 },
407 -------------------------------------------------------------
408 { "exponential numbers 3",
409 "12.34e+",
410 FAIL, ":1: malformed number near '12.34e+'",
411 },
412 -------------------------------------------------------------
413 { "exponential numbers 4",
414 "12.34e+5 123.4e-5 1234.E+5",
415 PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n",
416 },
417 -------------------------------------------------------------
418 { "hexadecimal numbers",
419 "0x00FF 0X1234 0xDEADBEEF",
420 PASS, "1 TK_NUMBER = 255\n1 TK_NUMBER = 4660\n1 TK_NUMBER = 3735928559\n",
421 },
422 -------------------------------------------------------------
423 { "invalid hexadecimal numbers 1",
424 "0xFOO",
425 FAIL, ":1: malformed number near '0xFOO'",
426 },
427 -------------------------------------------------------------
428 { "invalid hexadecimal numbers 2",
429 "0.BAR",
430 FAIL, ":1: malformed number near '0.BAR'",
431 },
432 -------------------------------------------------------------
433 { "invalid hexadecimal numbers 3",
434 "0BAZ",
435 FAIL, ":1: malformed number near '0BAZ'",
436 },
437 -------------------------------------------------------------
438 { "single character symbols 1",
439 "= > < ~ #",
440 PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n1 CHAR = '#'\n",
441 },
442 -------------------------------------------------------------
443 { "double character symbols",
444 "== >= <= ~=",
445 PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n",
446 },
447 -------------------------------------------------------------
448 { "simple identifiers",
449 "abc ABC",
450 PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS",
451 },
452 -------------------------------------------------------------
453 { "more identifiers",
454 "_abc _ABC",
455 PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS",
456 },
457 -------------------------------------------------------------
458 { "still more identifiers",
459 "_aB_ _123",
460 PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS",
461 },
462 -------------------------------------------------------------
463 -- NOTE: in Lua 5.1.x, this test is no longer performed
464 -------------------------------------------------------------
465 --{ "invalid control character",
466 -- "\4",
467 -- FAIL, ":1: invalid control char near 'char(4)'",
468 --},
469 -------------------------------------------------------------
470 { "single character symbols 2",
471 "` ! @ $ %",
472 PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n",
473 },
474 -------------------------------------------------------------
475 { "single character symbols 3",
476 "^ & * ( )",
477 PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n",
478 },
479 -------------------------------------------------------------
480 { "single character symbols 4",
481 "_ - + \\ |",
482 PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n",
483 },
484 -------------------------------------------------------------
485 { "single character symbols 5",
486 "{ } [ ] :",
487 PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n",
488 },
489 -------------------------------------------------------------
490 { "single character symbols 6",
491 "; , . / ?",
492 PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n",
493 },
494 -------------------------------------------------------------
495 }
496 ------------------------------------------------------------------
497 -- perform a test case
498 ------------------------------------------------------------------
499 function do_test_case(count, test_case)
500 if comment == "" then return end -- skip empty entries
501 local comment, chunk, outcome, matcher = unpack(test_case)
502 local result = PASS
503 local output = ""
504 -- initialize lexer
505 local L, LS = {}, {}
506 local z = luaZ:init(luaZ:make_getS(chunk), nil)
507 luaX:setinput(L, LS, z, "=test")
508 -- lexer test loop
509 repeat
510 -- protected call
511 local status, token = pcall(luaX.llex, luaX, LS, LS.t)
512 LS.t.token = token
513 output = output..LS.linenumber.." "
514 if status then
515 -- successful call
516 if string.len(token) > 1 then
517 if token == "TK_NAME"
518 or token == "TK_NUMBER"
519 or token == "TK_STRING" then
520 token = token.." = "..LS.t.seminfo
521 end
522 elseif string.byte(token) >= 32 then -- displayable chars
523 token = "CHAR = '"..token.."'"
524 else -- control characters
525 token = "CHAR = (".. string.byte(token)..")"
526 end
527 output = output..token.."\n"
528 else
529 -- failed call
530 output = output..token -- token is the error message
531 result = FAIL
532 break
533 end
534 until LS.t.token == "TK_EOS"
535 -- decision making and reporting
536 local head = "Test "..count..": "..comment
537 if matcher == "" then
538 -- nothing to check against, display for manual check
539 print(head.."\nMANUAL please check manually"..
540 "\n--chunk---------------------------------\n"..chunk..
541 "\n--actual--------------------------------\n"..output..
542 "\n\n")
543 return
544 else
545 if outcome == PASS then
546 -- success expected, may be a partial match
547 if string.find(output, matcher, 1, 1) and result == PASS then
548 if not BRIEF then print(head.."\nOK expected success\n") end
549 return
550 end
551 else
552 -- failure expected, may be a partial match
553 if string.find(output, matcher, 1, 1) and result == FAIL then
554 if not BRIEF then print(head.."\nOK expected failure\n") end
555 return
556 end
557 end
558 -- failed because of unmatched string or boolean result
559 local function passfail(status)
560 if status == PASS then return "PASS" else return "FAIL" end
561 end
562 print(head.." *FAILED*"..
563 "\noutcome="..passfail(outcome)..
564 "\nactual= "..passfail(result)..
565 "\n--chunk---------------------------------\n"..chunk..
566 "\n--expected------------------------------\n"..matcher..
567 "\n--actual--------------------------------\n"..output..
568 "\n\n")
569 end
570 end
571 ------------------------------------------------------------------
572 -- perform auto testing
573 ------------------------------------------------------------------
574 for i,test_case in ipairs(test_cases) do
575 do_test_case(i, test_case)
576 end
577end
578
579auto_test()
580--]]
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua
new file mode 100644
index 0000000..8c7abf4
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser.lua
@@ -0,0 +1,59 @@
1--[[--------------------------------------------------------------------
2
3 test_lparser.lua
4 Test for lparser.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15------------------------------------------------------------------------
16-- test the whole kaboodle
17------------------------------------------------------------------------
18
19dofile("../lzio.lua")
20dofile("../llex.lua")
21dofile("../lopcodes.lua")
22dofile("../ldump.lua")
23dofile("../lcode.lua")
24dofile("../lparser.lua")
25
26function lua_assert(test)
27 if not test then error("assertion failed!") end
28end
29
30luaX:init()
31
32------------------------------------------------------------------------
33-- try 1
34------------------------------------------------------------------------
35local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil)
36local LuaState = {}
37local Func = luaY:parser(LuaState, zio, nil, "=string")
38
39--[[
40for i, v in Func do
41 if type(v) == "string" or type(v) == "number" then
42 print(i, v)
43 elseif type(v) == "table" then
44 print(i, "TABLE")
45 end
46end
47--]]
48
49local Writer, Buff = luaU:make_setF("parse1.out")
50luaU:dump(LuaState, Func, Writer, Buff)
51
52------------------------------------------------------------------------
53-- try 2
54------------------------------------------------------------------------
55
56zio = luaZ:init(luaZ:make_getF("sample.lua"), nil)
57Func = luaY:parser(LuaState, zio, nil, "@sample.lua")
58Writer, Buff = luaU:make_setF("parse2.out")
59luaU:dump(LuaState, Func, Writer, Buff)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua
new file mode 100644
index 0000000..e9fa188
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lparser2.lua
@@ -0,0 +1,202 @@
1--[[--------------------------------------------------------------------
2
3 test_lparser2.lua
4 Test for lparser.lua, using the test case file
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * the test cases are in the test_lua directory (test_parser-5.1.lua)
18----------------------------------------------------------------------]]
19
20-- * true if you want an output of all failure cases in native Lua,
21-- for checking whether test cases fail where you intend them to
22local DEBUG_FAILS = false
23
24------------------------------------------------------------------------
25-- test the whole kaboodle
26------------------------------------------------------------------------
27
28dofile("../lzio.lua")
29dofile("../llex.lua")
30dofile("../lopcodes.lua")
31dofile("../ldump.lua")
32dofile("../lcode.lua")
33dofile("../lparser.lua")
34
35function lua_assert(test)
36 if not test then error("assertion failed!") end
37end
38
39luaX:init()
40
41------------------------------------------------------------------------
42-- load test cases
43------------------------------------------------------------------------
44
45dofile("../../test_lua/test_parser-5.1.lua")
46
47local test, expect, heading = {}, {}, {}
48local total, total_pass, total_fail = 0, 0, 0
49
50for ln in string.gmatch(tests_source, "([^\n]*)\n") do
51 if string.find(ln, "^%s*%-%-") then
52 -- comment, ignore
53 else
54 local m, _, head = string.find(ln, "^%s*(TESTS:%s*.*)$")
55 if m then
56 heading[total + 1] = head -- informational heading
57 else
58 total = total + 1
59 local n, _, flag = string.find(ln, "%s*%-%-%s*FAIL%s*$")
60 if n then -- FAIL test case
61 ln = string.sub(ln, 1, n - 1) -- remove comment
62 expect[total] = "FAIL"
63 total_fail = total_fail + 1
64 else -- PASS test case
65 expect[total] = "PASS"
66 total_pass = total_pass + 1
67 end--n
68 test[total] = ln
69 end--m
70 end--ln
71end--for
72
73print("Tests loaded: "..total.." (total), "
74 ..total_pass.." (passes), "
75 ..total_fail.." (fails)")
76
77------------------------------------------------------------------------
78-- verify test cases using native Lua
79------------------------------------------------------------------------
80
81local last_head = "TESTS: no heading yet"
82for i = 1, total do
83 local test_case, expected, head = test[i], expect[i], heading[i]
84 -- show progress
85 if head then
86 last_head = head
87 if DEBUG_FAILS then print("\n"..head.."\n") end
88 end
89 ------------------------------------------------------------------
90 -- perform test
91 local f, err = loadstring(test_case)
92 -- look at outcome
93 ------------------------------------------------------------------
94 if f then-- actual PASS
95 if expected == "FAIL" then
96 print("\nVerified as PASS but expected to FAIL"..
97 "\n-------------------------------------")
98 print("Lastest heading: "..last_head)
99 print("TEST: "..test_case)
100 os.exit()
101 end
102 ------------------------------------------------------------------
103 else-- actual FAIL
104 if expected == "PASS" then
105 print("\nVerified as FAIL but expected to PASS"..
106 "\n-------------------------------------")
107 print("Lastest heading: "..last_head)
108 print("TEST: "..test_case)
109 print("ERROR: "..err)
110 os.exit()
111 end
112 if DEBUG_FAILS then
113 print("TEST: "..test_case)
114 print("ERROR: "..err.."\n")
115 end
116 ------------------------------------------------------------------
117 end--f
118end--for
119
120print("Test cases verified using native Lua, no anomalies.")
121
122------------------------------------------------------------------------
123-- dump binary chunks to a file if something goes wrong
124------------------------------------------------------------------------
125local function Dump(data, filename)
126 h = io.open(filename, "wb")
127 if not h then error("failed to open "..filename.." for writing") end
128 h:write(data)
129 h:close()
130end
131
132------------------------------------------------------------------------
133-- test using Yueliang front end
134------------------------------------------------------------------------
135
136local last_head = "TESTS: no heading yet"
137for i = 1, total do
138 local test_case, expected, head = test[i], expect[i], heading[i]
139 -- show progress
140 if head then last_head = head end
141 ------------------------------------------------------------------
142 -- perform test
143 local LuaState = {}
144 local zio = luaZ:init(luaZ:make_getS(test_case), nil)
145 local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil, "test")
146 -- look at outcome
147 ------------------------------------------------------------------
148 if status then-- actual PASS
149 if expected == "PASS" then
150 -- actual PASS and expected PASS, so check binary chunks
151 local writer, buff = luaU:make_setS()
152 luaU:dump(LuaState, func, writer, buff)
153 local bc1 = buff.data -- Yueliang's output
154 local f = loadstring(test_case, "test")
155 local bc2 = string.dump(f) -- Lua's output
156 local die
157 -- compare outputs
158 if #bc1 ~= #bc2 then
159 Dump(bc1, "bc1.out")
160 Dump(bc2, "bc2.out")
161 die = "binary chunk sizes different"
162 elseif bc1 ~= bc2 then
163 Dump(bc1, "bc1.out")
164 Dump(bc2, "bc2.out")
165 die = "binary chunks different"
166 else
167 -- everything checks out!
168 end
169 if die then
170 print("\nTested PASS and expected to PASS, but chunks different"..
171 "\n------------------------------------------------------")
172 print("Reason: "..die)
173 print("Lastest heading: "..last_head)
174 print("TEST: "..test_case)
175 os.exit()
176 end
177 else-- expected FAIL
178 print("\nTested as PASS but expected to FAIL"..
179 "\n-----------------------------------")
180 print("Lastest heading: "..last_head)
181 print("TEST: "..test_case)
182 os.exit()
183 end
184 ------------------------------------------------------------------
185 else-- actual FAIL
186 if expected == "PASS" then
187 print("\nTested as FAIL but expected to PASS"..
188 "\n-----------------------------------")
189 print("Lastest heading: "..last_head)
190 print("TEST: "..test_case)
191 print("ERROR: "..err)
192 os.exit()
193 end
194 ------------------------------------------------------------------
195 end--status
196 io.stdout:write("\rTesting ["..i.."]...")
197end--for
198print(" done.")
199
200print("Test cases run on Yueliang, no anomalies.")
201
202-- end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua
new file mode 100644
index 0000000..c3879f1
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_lzio.lua
@@ -0,0 +1,41 @@
1--[[--------------------------------------------------------------------
2
3 test_lzio.lua
4 Test for lzio.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15-- manual test for lzio.lua lua-style chunk reader
16
17dofile("../lzio.lua")
18
19local z
20function dump(z)
21 while true do
22 local c = luaZ:zgetc(z)
23 io.stdout:write("("..c..")")
24 if c == "EOZ" then break end
25 end
26 io.stdout:write("\n")
27end
28
29-- luaZ:make_getS or luaZ:make_getF creates a chunk reader
30-- luaZ:init makes a zio stream
31
32-- [[
33z = luaZ:init(luaZ:make_getS("hello, world!"), nil, "=string")
34dump(z)
35z = luaZ:init(luaZ:make_getS(", world!"), "hello", "=string")
36dump(z)
37z = luaZ:init(luaZ:make_getS("line1\nline2\n"), "", "=string")
38dump(z)
39z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string")
40dump(z)
41--]]
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua
new file mode 100644
index 0000000..2c94f40
--- /dev/null
+++ b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/test/test_number.lua
@@ -0,0 +1,174 @@
1--[[--------------------------------------------------------------------
2
3 test_number.lua
4 Test for Lua-based number conversion functions in ldump.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2006 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * luaU:from_int(value) does not have overflow checks, but this
18-- can presumably be put in for debugging purposes.
19-- * TODO: double conversion does not support denormals or NaNs
20-- * apparently 0/0 == 0/0 is false (Lua 5.0.2 on Win32/Mingw), so
21-- can't use to check for NaNs
22----------------------------------------------------------------------]]
23
24dofile("../ldump.lua")
25
26------------------------------------------------------------------------
27-- convert hex string representation to a byte string
28-- * must have an even number of hex digits
29------------------------------------------------------------------------
30local function from_hexstring(s)
31 local bs = ""
32 for i = 1, string.len(s), 2 do
33 local asc = tonumber(string.sub(s, i, i + 1), 16)
34 bs = bs..string.char(asc)
35 end
36 return bs
37end
38
39------------------------------------------------------------------------
40-- convert a byte string to a hex string representation
41-- * big-endian, easier to grok
42------------------------------------------------------------------------
43local function to_hexstring(s)
44 local hs = ""
45 for i = string.len(s), 1, -1 do
46 local c = string.byte(string.sub(s, i, i))
47 hs = hs..string.format("%02X", c)
48 end
49 return hs
50end
51
52------------------------------------------------------------------------
53-- tests for 32-bit signed/unsigned integer
54------------------------------------------------------------------------
55local function test_int(value, expected)
56 local actual = to_hexstring(luaU:from_int(value))
57 if not expected or expected == "" then
58 print(value..": "..actual)
59 elseif actual ~= expected then
60 print(value..": FAILED!\n"..
61 "Converted: "..actual.."\n"..
62 "Expected: "..expected)
63 return true
64 end
65 return false
66end
67
68local table_int = {
69 ["0"] = "00000000",
70 ["1"] = "00000001",
71 ["256"] = "00000100",
72 ["-256"] = "FFFFFF00",
73 ["-1"] = "FFFFFFFF",
74 ["2147483647"] = "7FFFFFFF", -- LONG_MAX
75 ["-2147483648"] = "80000000", -- LONG_MIN
76 ["4294967295"] = "FFFFFFFF", -- ULONG_MAX
77 --[""] = "",
78}
79
80local success = true
81print("Testing luaU:from_int():")
82for i, v in pairs(table_int) do
83 local test_value = tonumber(i)
84 local expected = v
85 if test_int(test_value, expected) then
86 success = false
87 end
88end
89if success then
90 print("All test numbers passed okay.\n")
91else
92 print("There were one or more failures.\n")
93end
94
95------------------------------------------------------------------------
96-- tests for IEEE 754 64-bit double
97------------------------------------------------------------------------
98
99local function test_double(value, expected)
100 local actual = to_hexstring(luaU:from_double(value))
101 if not expected or expected == "" then
102 print(value..": "..actual)
103 elseif actual ~= expected then
104 print(value..": FAILED!\n"..
105 "Converted: "..actual.."\n"..
106 "Expected: "..expected)
107 return true
108 end
109 return false
110end
111
112-- special values, see testing loop for actual lookup
113Infinity = 1/0
114Infinity_neg = -1/0
115
116-- can't seem to do a comparison test with NaN, so leave them
117-- (need to check the IEEE standard on this...)
118NaN = 0/0
119NaN_neg = -0/0
120--["NaN"] = "", -- 7FF8000000000000 (djgpp)
121--["NaN_neg"] = "", -- FFF8000000000000 (djgpp)
122
123local table_double = {
124 -- 0 for exponent, 0 for mantissa
125 ["0"] = "0000000000000000",
126 -- 3FF is bias of 1023, so (-1)^0 * (1+0) * 2^0
127 ["1"] = "3FF0000000000000",
128 -- BFF has sign bit on, so (-1)^1 * (1+0) * 2^0
129 ["-1"] = "BFF0000000000000",
130 -- 3FC is bias of 1020, so (-1)^0 * (1+0) * 2^-3
131 ["0.125"] = "3FC0000000000000",
132 ["0.250"] = "3FD0000000000000",
133 ["0.500"] = "3FE0000000000000",
134 -- 40F is bias of 1039, so (-1)^0 * (1+0) * 2^16
135 ["65536"] = "40F0000000000000",
136 -- 7FF is bias of 2047, 0 for mantissa
137 ["Infinity"] = "7FF0000000000000",
138 -- FFF has sign bit on, 0 for mantissa
139 ["Infinity_neg"] = "FFF0000000000000",
140 -- DBL_MIN, exponent=001 ( 1), mantissa=0000000000000
141 ["2.2250738585072014e-308"] = "0010000000000000",
142 -- DBL_MAX, exponent=7FE (2046), mantissa=FFFFFFFFFFFFF
143 ["1.7976931348623157e+308"] = "7FEFFFFFFFFFFFFF",
144--[[
145 -- * the following is for float numbers only *
146 -- FLT_MIN, exponent=01 ( 1), mantissa=000000
147 -- altervative value for FLT_MIN: 1.17549435e-38F
148 ["1.1754943508222875081e-38"] = "00800000",
149 -- FLT_MAX, exponent=FE (254), mantissa=7FFFFF
150 -- altervative value for FLT_MAX: 3.402823466e+38F
151 ["3.4028234663852885982e+38"] = "7F7FFFFF",
152--]]
153 --[""] = "",
154}
155
156local success = true
157print("Testing luaU:from_double():")
158for i, v in pairs(table_double) do
159 local test_value
160 if not string.find(i, "%d") then
161 test_value = _G[i]
162 else
163 test_value = tonumber(i)
164 end
165 local expected = v
166 if test_double(test_value, expected) then
167 success = false
168 end
169end
170if success then
171 print("All test numbers passed okay.\n")
172else
173 print("There were one or more failures.\n")
174end