aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/testLua/yueliang-0.4.1/orig-5.0.3')
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README51
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua902
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua362
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua531
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua349
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua1706
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua71
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua120
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua99
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua3
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua98
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua504
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua60
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua202
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua55
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua174
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua254
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log152
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua195
19 files changed, 0 insertions, 5888 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README
deleted file mode 100644
index e64bf50..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/README
+++ /dev/null
@@ -1,51 +0,0 @@
1orig-5.0.3
2
3This is a straightforward port of the Lua 5.0.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.0.3's luac.lua, except that it generates a
23binary chunk using Yueliang's front end implementation.
24
25Note that performance is not a consideration. The code tries to stay
26faithful to its C roots, so that if you were to do anything using this
27codebase, backporting the changes to C will be easy. As such, this
28codebase is meant for learning or prototyping purposes.
29
30Many parameters are unused, because call arguments are retained as far
31as possible. Changes and deletions are described wherever possible, but
32documentation of changes is not comprehensive.
33
34These files will stay faithful to the equivalent C files or modules in
35Lua 5.0.3. For rewrites or new features, a new directory will be created
36and a different set of files maintained. For Lua 5.1, a new directory
37will be created.
38
39The test directory has several primitive test scripts. Much better
40testing is planned. Eventually, the codebase will be validated using
41automated tests, so that any changes that breaks the system can be
42caught easily.
43
44The tools directory has a call graph generator, showing what gets
45called. Specific modules and functions can be monitored, and some
46parameters and return values are shown. This is a demonstration of the
47flexibility and ease of manipulation of using a relatively inefficient
48global table scheme.
49
50For Lua 5.0.2, see Yueliang 0.1.3, which was the last release of Lua
515.0.2 material.
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua
deleted file mode 100644
index c18dc08..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua
+++ /dev/null
@@ -1,902 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 lcode.lua
4 Lua 5 code generator 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-- * 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-- * some function parameters changed to boolean, additional code
21-- translates boolean back to 1/0 for instruction fields
22-- * Added:
23-- luaK:ttisnumber(o) (from lobject.h)
24-- luaK:nvalue(o) (from lobject.h)
25-- luaK:setnilvalue(o) (from lobject.h)
26-- luaK:setsvalue(o, x) (from lobject.h)
27-- luaK:setnvalue(o, x) (from lobject.h)
28-- luaK:sethvalue(o, x) (from lobject.h)
29----------------------------------------------------------------------]]
30
31-- requires luaP, luaX, luaY
32luaK = {}
33
34------------------------------------------------------------------------
35-- Marks the end of a patch list. It is an invalid value both as an absolute
36-- address, and as a list link (would link an element to itself).
37------------------------------------------------------------------------
38luaK.NO_JUMP = -1
39
40------------------------------------------------------------------------
41-- grep "ORDER OPR" if you change these enums
42------------------------------------------------------------------------
43luaK.BinOpr = {
44 OPR_ADD = 0, OPR_SUB = 1, OPR_MULT = 2, OPR_DIV = 3, OPR_POW = 4,
45 OPR_CONCAT = 5,
46 OPR_NE = 6, OPR_EQ = 7,
47 OPR_LT = 8, OPR_LE = 9, OPR_GT = 10, OPR_GE = 11,
48 OPR_AND = 12, OPR_OR = 13,
49 OPR_NOBINOPR = 14,
50}
51
52------------------------------------------------------------------------
53-- emulation of TObject macros (these are from lobject.h)
54-- * TObject is a table since lcode passes references around
55-- * tt member field removed, using Lua's type() instead
56------------------------------------------------------------------------
57function luaK:ttisnumber(o)
58 if o then return type(o.value) == "number" else return false end
59end
60function luaK:nvalue(o) return o.value end
61function luaK:setnilvalue(o) o.value = nil end
62function luaK:setsvalue(o, x) o.value = x end
63luaK.setnvalue = luaK.setsvalue
64luaK.sethvalue = luaK.setsvalue
65
66------------------------------------------------------------------------
67-- * binopistest appears to be unused
68-- * UnOpr is used by luaK:prefix's op argument
69------------------------------------------------------------------------
70function luaK:binopistest(op)
71 return self.BinOpr[op] >= self.BinOpr["OPR_NE"]
72end
73
74luaK.UnOpr = {
75 OPR_MINUS = 0, OPR_NOT = 1, OPR_NOUNOPR = 2
76}
77
78------------------------------------------------------------------------
79-- returns the instruction object for given e (expdesc)
80------------------------------------------------------------------------
81function luaK:getcode(fs, e)
82 return fs.f.code[e.info]
83end
84
85------------------------------------------------------------------------
86-- codes an instruction with a signed Bx (sBx) field
87------------------------------------------------------------------------
88function luaK:codeAsBx(fs, o, A, sBx)
89 return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
90end
91
92------------------------------------------------------------------------
93-- there is a jump if patch lists are not identical
94-- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
95------------------------------------------------------------------------
96function luaK:hasjumps(e)
97 return e.t ~= e.f
98end
99
100------------------------------------------------------------------------
101-- codes loading of nil, optimization done if consecutive locations
102-- * used only in discharge2reg()
103------------------------------------------------------------------------
104function luaK:_nil(fs, from, n)
105 if fs.pc > fs.lasttarget then -- no jumps to current position?
106 local previous = fs.f.code[fs.pc - 1]
107 if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
108 local pfrom = luaP:GETARG_A(previous)
109 local pto = luaP:GETARG_B(previous)
110 if pfrom <= from and from <= pto + 1 then -- can connect both?
111 if from + n - 1 > pto then
112 luaP:SETARG_B(previous, from + n - 1)
113 end
114 return
115 end
116 end
117 end
118 self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
119end
120
121------------------------------------------------------------------------
122--
123-- * used in multiple locations
124------------------------------------------------------------------------
125function luaK:jump(fs)
126 local jpc = fs.jpc -- save list of jumps to here
127 fs.jpc = self.NO_JUMP
128 local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
129 return self:concat(fs, j, jpc) -- keep them on hold
130end
131
132------------------------------------------------------------------------
133--
134-- * used in luaK:jumponcond(), luaK:codebinop()
135------------------------------------------------------------------------
136function luaK:condjump(fs, op, A, B, C)
137 self:codeABC(fs, op, A, B, C)
138 return self:jump(fs)
139end
140
141------------------------------------------------------------------------
142--
143-- * used in luaK:patchlistaux(), luaK:concat()
144------------------------------------------------------------------------
145function luaK:fixjump(fs, pc, dest)
146 local jmp = fs.f.code[pc]
147 local offset = dest - (pc + 1)
148 lua_assert(dest ~= self.NO_JUMP)
149 if math.abs(offset) > luaP.MAXARG_sBx then
150 luaX:syntaxerror(fs.ls, "control structure too long")
151 end
152 luaP:SETARG_sBx(jmp, offset)
153end
154
155------------------------------------------------------------------------
156-- returns current 'pc' and marks it as a jump target (to avoid wrong
157-- optimizations with consecutive instructions not in the same basic block).
158-- * used in multiple locations
159-- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
160------------------------------------------------------------------------
161function luaK:getlabel(fs)
162 fs.lasttarget = fs.pc
163 return fs.pc
164end
165
166------------------------------------------------------------------------
167--
168-- * used in luaK:need_value(), luaK:patchlistaux(), luaK:concat()
169------------------------------------------------------------------------
170function luaK:getjump(fs, pc)
171 local offset = luaP:GETARG_sBx(fs.f.code[pc])
172 if offset == self.NO_JUMP then -- point to itself represents end of list
173 return self.NO_JUMP -- end of list
174 else
175 return (pc + 1) + offset -- turn offset into absolute position
176 end
177end
178
179------------------------------------------------------------------------
180--
181-- * used in luaK:need_value(), luaK:patchlistaux(), luaK:invertjump()
182------------------------------------------------------------------------
183function luaK:getjumpcontrol(fs, pc)
184 local pi = fs.f.code[pc]
185 local ppi = fs.f.code[pc - 1]
186 if pc >= 1 and luaP:testOpMode(luaP:GET_OPCODE(ppi), "OpModeT") then
187 return ppi
188 else
189 return pi
190 end
191end
192
193------------------------------------------------------------------------
194-- check whether list has any jump that do not produce a value
195-- (or produce an inverted value)
196-- * used only in luaK:exp2reg()
197------------------------------------------------------------------------
198function luaK:need_value(fs, list, cond)
199 while list ~= self.NO_JUMP do
200 local i = self:getjumpcontrol(fs, list)
201 if luaP:GET_OPCODE(i) ~= "OP_TEST" or
202 luaP:GETARG_A(i) ~= luaP.NO_REG or
203 luaP:GETARG_C(i) ~= cond then
204 return true
205 end
206 list = self:getjump(fs, list)
207 end
208 return false -- not found
209end
210
211------------------------------------------------------------------------
212--
213-- * used only in luaK:patchlistaux()
214------------------------------------------------------------------------
215function luaK:patchtestreg(i, reg)
216 if reg == luaP.NO_REG then reg = luaP:GETARG_B(i) end
217 luaP:SETARG_A(i, reg)
218end
219
220------------------------------------------------------------------------
221--
222-- * used only in luaK:codenot()
223------------------------------------------------------------------------
224
225function luaK:removevalues(fs, list)
226 while list ~= self.NO_JUMP do
227 local i = self:getjumpcontrol(fs, list)
228 if luaP:GET_OPCODE(i) == "OP_TEST" then
229 self:patchtestreg(i, luaP.NO_REG)
230 end
231 list = self:getjump(fs, list)
232 end
233end
234
235------------------------------------------------------------------------
236--
237-- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
238------------------------------------------------------------------------
239function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
240 while list ~= self.NO_JUMP do
241 local _next = self:getjump(fs, list)
242 local i = self:getjumpcontrol(fs, list)
243 if luaP:GET_OPCODE(i) == "OP_TEST" and luaP:GETARG_A(i) == luaP.NO_REG then
244 self:patchtestreg(i, reg)
245 self:fixjump(fs, list, vtarget)
246 else
247 self:fixjump(fs, list, dtarget) -- jump to default target
248 end
249 list = _next
250 end
251end
252
253------------------------------------------------------------------------
254--
255-- * used only in luaK:code()
256------------------------------------------------------------------------
257function luaK:dischargejpc(fs)
258 self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
259 fs.jpc = self.NO_JUMP
260end
261
262------------------------------------------------------------------------
263--
264-- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
265------------------------------------------------------------------------
266function luaK:patchlist(fs, list, target)
267 if target == fs.pc then
268 self:patchtohere(fs, list)
269 else
270 lua_assert(target < fs.pc)
271 self:patchlistaux(fs, list, target, luaP.NO_REG, target)
272 end
273end
274
275------------------------------------------------------------------------
276--
277-- * used in multiple locations
278------------------------------------------------------------------------
279function luaK:patchtohere(fs, list)
280 self:getlabel(fs)
281 fs.jpc = self:concat(fs, fs.jpc, list)
282end
283
284------------------------------------------------------------------------
285-- * l1 was a pointer, now l1 is returned and callee assigns the value
286-- * used in multiple locations
287------------------------------------------------------------------------
288function luaK:concat(fs, l1, l2)
289 if l2 == self.NO_JUMP then return l1 -- unchanged
290 elseif l1 == self.NO_JUMP then
291 return l2 -- changed
292 else
293 local list = l1
294 local _next = self:getjump(fs, list)
295 while _next ~= self.NO_JUMP do -- find last element
296 list = _next
297 _next = self:getjump(fs, list)
298 end
299 self:fixjump(fs, list, l2)
300 end
301 return l1 -- unchanged
302end
303
304------------------------------------------------------------------------
305--
306-- * used in luaK:reserveregs(), (lparser) luaY:forlist()
307------------------------------------------------------------------------
308function luaK:checkstack(fs, n)
309 local newstack = fs.freereg + n
310 if newstack > fs.f.maxstacksize then
311 if newstack >= luaY.MAXSTACK then
312 luaX:syntaxerror(fs.ls, "function or expression too complex")
313 end
314 fs.f.maxstacksize = newstack
315 end
316end
317
318------------------------------------------------------------------------
319--
320-- * used in multiple locations
321------------------------------------------------------------------------
322function luaK:reserveregs(fs, n)
323 self:checkstack(fs, n)
324 fs.freereg = fs.freereg + n
325end
326
327------------------------------------------------------------------------
328--
329-- * used in luaK:freeexp(), luaK:dischargevars()
330------------------------------------------------------------------------
331function luaK:freereg(fs, reg)
332 if reg >= fs.nactvar and reg < luaY.MAXSTACK then
333 fs.freereg = fs.freereg - 1
334 lua_assert(reg == fs.freereg)
335 end
336end
337
338------------------------------------------------------------------------
339--
340-- * used in multiple locations
341------------------------------------------------------------------------
342function luaK:freeexp(fs, e)
343 if e.k == "VNONRELOC" then
344 self:freereg(fs, e.info)
345 end
346end
347
348------------------------------------------------------------------------
349-- * luaH_get, luaH_set deleted; direct table access used instead
350-- * luaO_rawequalObj deleted in first assert
351-- * setobj2n deleted in assignment of v to f.k table
352-- * used in luaK:stringK(), luaK:numberK(), luaK:nil_constant()
353------------------------------------------------------------------------
354function luaK:addk(fs, k, v)
355 local idx = fs.h[k.value]
356 if self:ttisnumber(idx) then
357 --TODO this assert currently FAILS, probably something wrong...
358 --lua_assert(fs.f.k[self:nvalue(idx)] == v)
359 return self:nvalue(idx)
360 else -- constant not found; create a new entry
361 local f = fs.f
362 luaY:growvector(fs.L, f.k, fs.nk, f.sizek, nil,
363 luaP.MAXARG_Bx, "constant table overflow")
364 f.k[fs.nk] = v -- setobj2n deleted
365 fs.h[k.value] = {}
366 self:setnvalue(fs.h[k.value], fs.nk)
367 local nk = fs.nk
368 fs.nk = fs.nk + 1
369 return nk
370 end
371end
372
373------------------------------------------------------------------------
374-- creates and sets a string object
375-- * used in (lparser) luaY:codestring(), luaY:singlevaraux()
376------------------------------------------------------------------------
377function luaK:stringK(fs, s)
378 local o = {} -- TObject
379 self:setsvalue(o, s)
380 return self:addk(fs, o, o)
381end
382
383------------------------------------------------------------------------
384-- creates and sets a number object
385-- * used in luaK:prefix() for negative (or negation of) numbers
386-- * used in (lparser) luaY:simpleexp(), luaY:fornum()
387------------------------------------------------------------------------
388function luaK:numberK(fs, r)
389 local o = {} -- TObject
390 self:setnvalue(o, r)
391 return self:addk(fs, o, o)
392end
393
394------------------------------------------------------------------------
395--
396-- * used only in luaK:exp2RK()
397------------------------------------------------------------------------
398function luaK:nil_constant(fs)
399 local k, v = {}, {} -- TObject
400 self:setnilvalue(v)
401 self:sethvalue(k, fs.h) -- cannot use nil as key; instead use table itself
402 return self:addk(fs, k, v)
403end
404
405------------------------------------------------------------------------
406--
407-- * used in luaK:dischargevars()
408-- * used in (lparser) luaY:adjust_assign(), luaY:lastlistfield(),
409-- luaY:funcargs(), luaY:assignment(), luaY:exprstat(), luaY:retstat()
410------------------------------------------------------------------------
411function luaK:setcallreturns(fs, e, nresults)
412 if e.k == "VCALL" then -- expression is an open function call?
413 luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
414 if nresults == 1 then -- 'regular' expression?
415 e.k = "VNONRELOC"
416 e.info = luaP:GETARG_A(self:getcode(fs, e))
417 end
418 end
419end
420
421------------------------------------------------------------------------
422--
423-- * used in multiple locations
424------------------------------------------------------------------------
425function luaK:dischargevars(fs, e)
426 local k = e.k
427 if k == "VLOCAL" then
428 e.k = "VNONRELOC"
429 elseif k == "VUPVAL" then
430 e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
431 e.k = "VRELOCABLE"
432 elseif k == "VGLOBAL" then
433 e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
434 e.k = "VRELOCABLE"
435 elseif k == "VINDEXED" then
436 self:freereg(fs, e.aux)
437 self:freereg(fs, e.info)
438 e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
439 e.k = "VRELOCABLE"
440 elseif k == "VCALL" then
441 self:setcallreturns(fs, e, 1)
442 else
443 -- there is one value available (somewhere)
444 end
445end
446
447------------------------------------------------------------------------
448--
449-- * used only in luaK:exp2reg()
450------------------------------------------------------------------------
451function luaK:code_label(fs, A, b, jump)
452 self:getlabel(fs) -- those instructions may be jump targets
453 return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
454end
455
456------------------------------------------------------------------------
457--
458-- * used in luaK:discharge2anyreg(), luaK:exp2reg()
459------------------------------------------------------------------------
460function luaK:discharge2reg(fs, e, reg)
461 self:dischargevars(fs, e)
462 local k = e.k
463 if k == "VNIL" then
464 self:_nil(fs, reg, 1)
465 elseif k == "VFALSE" or k == "VTRUE" then
466 self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
467 elseif k == "VK" then
468 self:codeABx(fs, "OP_LOADK", reg, e.info)
469 elseif k == "VRELOCABLE" then
470 local pc = self:getcode(fs, e)
471 luaP:SETARG_A(pc, reg)
472 elseif k == "VNONRELOC" then
473 if reg ~= e.info then
474 self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
475 end
476 else
477 lua_assert(e.k == "VVOID" or e.k == "VJMP")
478 return -- nothing to do...
479 end
480 e.info = reg
481 e.k = "VNONRELOC"
482end
483
484------------------------------------------------------------------------
485--
486-- * used in luaK:jumponcond(), luaK:codenot()
487------------------------------------------------------------------------
488function luaK:discharge2anyreg(fs, e)
489 if e.k ~= "VNONRELOC" then
490 self:reserveregs(fs, 1)
491 self:discharge2reg(fs, e, fs.freereg - 1)
492 end
493end
494
495------------------------------------------------------------------------
496--
497-- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
498------------------------------------------------------------------------
499function luaK:exp2reg(fs, e, reg)
500 self:discharge2reg(fs, e, reg)
501 if e.k == "VJMP" then
502 e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
503 end
504 if self:hasjumps(e) then
505 local final -- position after whole expression
506 local p_f = self.NO_JUMP -- position of an eventual LOAD false
507 local p_t = self.NO_JUMP -- position of an eventual LOAD true
508 if self:need_value(fs, e.t, 1) or self:need_value(fs, e.f, 0) then
509 local fj = self.NO_JUMP -- first jump (over LOAD ops.)
510 if e.k ~= "VJMP" then
511 fj = self:jump(fs)
512 end
513 p_f = self:code_label(fs, reg, 0, 1)
514 p_t = self:code_label(fs, reg, 1, 0)
515 self:patchtohere(fs, fj)
516 end
517 final = self:getlabel(fs)
518 self:patchlistaux(fs, e.f, final, reg, p_f)
519 self:patchlistaux(fs, e.t, final, reg, p_t)
520 end
521 e.f, e.t = self.NO_JUMP, self.NO_JUMP
522 e.info = reg
523 e.k = "VNONRELOC"
524end
525
526------------------------------------------------------------------------
527--
528-- * used in multiple locations
529------------------------------------------------------------------------
530function luaK:exp2nextreg(fs, e)
531 self:dischargevars(fs, e)
532 self:freeexp(fs, e)
533 self:reserveregs(fs, 1)
534 self:exp2reg(fs, e, fs.freereg - 1)
535end
536
537------------------------------------------------------------------------
538--
539-- * used in multiple locations
540------------------------------------------------------------------------
541function luaK:exp2anyreg(fs, e)
542 self:dischargevars(fs, e)
543 if e.k == "VNONRELOC" then
544 if not self:hasjumps(e) then -- exp is already in a register
545 return e.info
546 end
547 if e.info >= fs.nactvar then -- reg. is not a local?
548 self:exp2reg(fs, e, e.info) -- put value on it
549 return e.info
550 end
551 end
552 self:exp2nextreg(fs, e) -- default
553 return e.info
554end
555
556------------------------------------------------------------------------
557--
558-- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
559-- * used in (lparser) luaY:index()
560------------------------------------------------------------------------
561function luaK:exp2val(fs, e)
562 if self:hasjumps(e) then
563 self:exp2anyreg(fs, e)
564 else
565 self:dischargevars(fs, e)
566 end
567end
568
569------------------------------------------------------------------------
570--
571-- * used in multiple locations
572------------------------------------------------------------------------
573function luaK:exp2RK(fs, e)
574 self:exp2val(fs, e)
575 local k = e.k
576 if k == "VNIL" then
577 if fs.nk + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC?
578 e.info = self:nil_constant(fs)
579 e.k = "VK"
580 return e.info + luaY.MAXSTACK
581 end
582 elseif k == "VK" then
583 if e.info + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC?
584 return e.info + luaY.MAXSTACK
585 end
586 end
587 -- not a constant in the right range: put it in a register
588 return self:exp2anyreg(fs, e)
589end
590
591------------------------------------------------------------------------
592--
593-- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
594------------------------------------------------------------------------
595function luaK:storevar(fs, var, exp)
596 local k = var.k
597 if k == "VLOCAL" then
598 self:freeexp(fs, exp)
599 self:exp2reg(fs, exp, var.info)
600 return
601 elseif k == "VUPVAL" then
602 local e = self:exp2anyreg(fs, exp)
603 self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
604 elseif k == "VGLOBAL" then
605 local e = self:exp2anyreg(fs, exp)
606 self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
607 elseif k == "VINDEXED" then
608 local e = self:exp2RK(fs, exp)
609 self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
610 else
611 lua_assert(0) -- invalid var kind to store
612 end
613 self:freeexp(fs, exp)
614end
615
616------------------------------------------------------------------------
617--
618-- * used only in (lparser) luaY:primaryexp()
619------------------------------------------------------------------------
620function luaK:_self(fs, e, key)
621 self:exp2anyreg(fs, e)
622 self:freeexp(fs, e)
623 local func = fs.freereg
624 self:reserveregs(fs, 2)
625 self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
626 self:freeexp(fs, key)
627 e.info = func
628 e.k = "VNONRELOC"
629end
630
631------------------------------------------------------------------------
632--
633-- * used in luaK:goiftrue(), luaK:codenot()
634------------------------------------------------------------------------
635function luaK:invertjump(fs, e)
636 local pc = self:getjumpcontrol(fs, e.info)
637 lua_assert(luaP:testOpMode(luaP:GET_OPCODE(pc), "OpModeT") and
638 luaP:GET_OPCODE(pc) ~= "OP_TEST")
639 luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
640end
641
642------------------------------------------------------------------------
643--
644-- * used in luaK:goiftrue(), luaK:goiffalse()
645------------------------------------------------------------------------
646function luaK:jumponcond(fs, e, cond)
647 if e.k == "VRELOCABLE" then
648 local ie = self:getcode(fs, e)
649 if luaP:GET_OPCODE(ie) == "OP_NOT" then
650 fs.pc = fs.pc - 1 -- remove previous OP_NOT
651 return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), luaP:GETARG_B(ie),
652 cond and 0 or 1)
653 end
654 -- else go through
655 end
656 self:discharge2anyreg(fs, e)
657 self:freeexp(fs, e)
658 return self:condjump(fs, "OP_TEST", luaP.NO_REG, e.info, cond and 1 or 0)
659end
660
661------------------------------------------------------------------------
662--
663-- * used in luaK:infix(), (lparser) luaY:cond()
664------------------------------------------------------------------------
665function luaK:goiftrue(fs, e)
666 local pc -- pc of last jump
667 self:dischargevars(fs, e)
668 local k = e.k
669 if k == "VK" or k == "VTRUE" then
670 pc = self.NO_JUMP -- always true; do nothing
671 elseif k == "VFALSE" then
672 pc = self:jump(fs) -- always jump
673 elseif k == "VJMP" then
674 self:invertjump(fs, e)
675 pc = e.info
676 else
677 pc = self:jumponcond(fs, e, false)
678 end
679 e.f = self:concat(fs, e.f, pc) -- insert last jump in 'f' list
680end
681
682------------------------------------------------------------------------
683--
684-- * used in luaK:infix(), (lparser) luaY:whilestat()
685------------------------------------------------------------------------
686function luaK:goiffalse(fs, e)
687 local pc -- pc of last jump
688 self:dischargevars(fs, e)
689 local k = e.k
690 if k == "VNIL" or k == "VFALSE"then
691 pc = self.NO_JUMP -- always false; do nothing
692 elseif k == "VTRUE" then
693 pc = self:jump(fs) -- always jump
694 elseif k == "VJMP" then
695 pc = e.info
696 else
697 pc = self:jumponcond(fs, e, true)
698 end
699 e.t = self:concat(fs, e.t, pc) -- insert last jump in 't' list
700end
701
702------------------------------------------------------------------------
703--
704-- * used only in luaK:prefix()
705------------------------------------------------------------------------
706function luaK:codenot(fs, e)
707 self:dischargevars(fs, e)
708 local k = e.k
709 if k == "VNIL" or k == "VFALSE" then
710 e.k = "VTRUE"
711 elseif k == "VK" or k == "VTRUE" then
712 e.k = "VFALSE"
713 elseif k == "VJMP" then
714 self:invertjump(fs, e)
715 elseif k == "VRELOCABLE" or k == "VNONRELOC" then
716 self:discharge2anyreg(fs, e)
717 self:freeexp(fs, e)
718 e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
719 e.k = "VRELOCABLE"
720 else
721 lua_assert(0) -- cannot happen
722 end
723 -- interchange true and false lists
724 e.f, e.t = e.t, e.f
725 self:removevalues(fs, e.f)
726 self:removevalues(fs, e.t)
727end
728
729------------------------------------------------------------------------
730--
731-- * used in (lparser) luaY:field(), luaY:primaryexp()
732------------------------------------------------------------------------
733function luaK:indexed(fs, t, k)
734 t.aux = self:exp2RK(fs, k)
735 t.k = "VINDEXED"
736end
737
738------------------------------------------------------------------------
739--
740-- * used only in (lparser) luaY:subexpr()
741------------------------------------------------------------------------
742function luaK:prefix(fs, op, e)
743 if op == "OPR_MINUS" then
744 self:exp2val(fs, e)
745 if e.k == "VK" and self:ttisnumber(fs.f.k[e.info]) then
746 e.info = self:numberK(fs, -self:nvalue(fs.f.k[e.info]))
747 else
748 self:exp2anyreg(fs, e)
749 self:freeexp(fs, e)
750 e.info = self:codeABC(fs, "OP_UNM", 0, e.info, 0)
751 e.k = "VRELOCABLE"
752 end
753 else -- op == NOT
754 self:codenot(fs, e)
755 end
756end
757
758------------------------------------------------------------------------
759--
760-- * used only in (lparser) luaY:subexpr()
761------------------------------------------------------------------------
762function luaK:infix(fs, op, v)
763 if op == "OPR_AND" then
764 self:goiftrue(fs, v)
765 self:patchtohere(fs, v.t)
766 v.t = self.NO_JUMP
767 elseif op == "OPR_OR" then
768 self:goiffalse(fs, v)
769 self:patchtohere(fs, v.f)
770 v.f = self.NO_JUMP
771 elseif op == "OPR_CONCAT" then
772 self:exp2nextreg(fs, v) -- operand must be on the 'stack'
773 else
774 self:exp2RK(fs, v)
775 end
776end
777
778------------------------------------------------------------------------
779--
780-- grep "ORDER OPR" if you change these enums
781-- * used only in luaK:posfix()
782------------------------------------------------------------------------
783luaK.arith_opc = { -- done as a table lookup instead of a calc
784 OPR_ADD = "OP_ADD",
785 OPR_SUB = "OP_SUB",
786 OPR_MULT = "OP_MUL",
787 OPR_DIV = "OP_DIV",
788 OPR_POW = "OP_POW",
789}
790luaK.test_opc = { -- was ops[] in the codebinop function
791 OPR_NE = "OP_EQ",
792 OPR_EQ = "OP_EQ",
793 OPR_LT = "OP_LT",
794 OPR_LE = "OP_LE",
795 OPR_GT = "OP_LT",
796 OPR_GE = "OP_LE",
797}
798function luaK:codebinop(fs, res, op, o1, o2)
799 if self.BinOpr[op] <= self.BinOpr["OPR_POW"] then -- arithmetic operator?
800 local opc = self.arith_opc[op] -- ORDER OP
801 res.info = self:codeABC(fs, opc, 0, o1, o2)
802 res.k = "VRELOCABLE"
803 else -- test operator
804 local cond = true
805 if self.BinOpr[op] >= self.BinOpr["OPR_GT"] then -- '>' or '>='?
806 -- exchange args and replace by '<' or '<='
807 o1, o2 = o2, o1 -- o1 <==> o2
808 elseif op == "OPR_NE" then
809 cond = false
810 end
811 res.info = self:condjump(fs, self.test_opc[op], cond and 1 or 0, o1, o2)
812 res.k = "VJMP"
813 end
814end
815
816------------------------------------------------------------------------
817--
818-- * used only in (lparser) luaY:subexpr()
819------------------------------------------------------------------------
820function luaK:posfix(fs, op, e1, e2)
821 if op == "OPR_AND" then
822 lua_assert(e1.t == self.NO_JUMP) -- list must be closed
823 self:dischargevars(fs, e2)
824 e1.f = self:concat(fs, e1.f, e2.f)
825 e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.t = e2.t
826 elseif op == "OPR_OR" then
827 lua_assert(e1.f == self.NO_JUMP) -- list must be closed
828 self:dischargevars(fs, e2)
829 e1.t = self:concat(fs, e1.t, e2.t)
830 e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.f = e2.f
831 elseif op == "OPR_CONCAT" then
832 self:exp2val(fs, e2)
833 if e2.k == "VRELOCABLE"
834 and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
835 lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
836 self:freeexp(fs, e1)
837 luaP:SETARG_B(self:getcode(fs, e2), e1.info)
838 e1.k = e2.k; e1.info = e2.info
839 else
840 self:exp2nextreg(fs, e2)
841 self:freeexp(fs, e2)
842 self:freeexp(fs, e1)
843 e1.info = self:codeABC(fs, "OP_CONCAT", 0, e1.info, e2.info)
844 e1.k = "VRELOCABLE"
845 end
846 else
847 local o1 = self:exp2RK(fs, e1)
848 local o2 = self:exp2RK(fs, e2)
849 self:freeexp(fs, e2)
850 self:freeexp(fs, e1)
851 self:codebinop(fs, e1, op, o1, o2)
852 end
853end
854
855------------------------------------------------------------------------
856-- adjusts debug information for last instruction written, in order to
857-- change the line where item comes into existence
858-- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
859------------------------------------------------------------------------
860function luaK:fixline(fs, line)
861 fs.f.lineinfo[fs.pc - 1] = line
862end
863
864------------------------------------------------------------------------
865-- general function to write an instruction into the instruction buffer,
866-- sets debug information too
867-- * used in luaK:codeABC(), luaK:codeABx()
868-- * called directly by (lparser) luaY:whilestat()
869------------------------------------------------------------------------
870function luaK:code(fs, i, line)
871 local f = fs.f
872 self:dischargejpc(fs) -- 'pc' will change
873 -- put new instruction in code array
874 luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
875 luaY.MAX_INT, "code size overflow")
876 f.code[fs.pc] = i
877 -- save corresponding line information
878 luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
879 luaY.MAX_INT, "code size overflow")
880 f.lineinfo[fs.pc] = line
881 local pc = fs.pc
882 fs.pc = fs.pc + 1
883 return pc
884end
885
886------------------------------------------------------------------------
887-- writes an instruction of type ABC
888-- * calls luaK:code()
889------------------------------------------------------------------------
890function luaK:codeABC(fs, o, a, b, c)
891 lua_assert(luaP:getOpMode(o) == "iABC")
892 return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
893end
894
895------------------------------------------------------------------------
896-- writes an instruction of type ABx
897-- * calls luaK:code(), called by luaK:codeAsBx()
898------------------------------------------------------------------------
899function luaK:codeABx(fs, o, a, bc)
900 lua_assert(luaP:getOpMode(o) == "iABx" or luaP:getOpMode(o) == "iAsBx")
901 return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
902end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua
deleted file mode 100644
index 1b3c608..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/ldump.lua
+++ /dev/null
@@ -1,362 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 ldump.lua
4 Save bytecodes in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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-- * LUA_NUMBER (double), byte order (little endian) and some other
18-- header values hard-coded; see other notes below...
19-- * One significant difference is that instructions are still in table
20-- form (with OP/A/B/C/Bx fields) and luaP:Instruction() is needed to
21-- convert them into 4-char strings
22-- * Deleted:
23-- luaU:DumpVector: folded into DumpLines, DumpCode
24-- * Added:
25-- luaU:endianness() (from lundump.c)
26-- luaU:make_setS: create a chunk writer that writes to a string
27-- luaU:make_setF: create a chunk writer that writes to a file
28-- (lua.h contains a typedef for a Chunkwriter pointer, and
29-- a Lua-based implementation exists, writer() in lstrlib.c)
30-- luaU:from_double(x): encode double value for writing
31-- luaU:from_int(x): encode integer value for writing
32-- (error checking is limited for these conversion functions)
33-- (double conversion does not support denormals or NaNs)
34-- luaU:ttype(o) (from lobject.h)
35----------------------------------------------------------------------]]
36
37--requires luaP
38luaU = {}
39
40-- constants used by dumper
41luaU.LUA_TNUMBER = 3 -- (all in lua.h)
42luaU.LUA_TSTRING = 4
43luaU.LUA_TNIL = 0
44luaU.LUA_TNONE = -1
45
46-- definitions for headers of binary files
47luaU.LUA_SIGNATURE = "\27Lua" -- binary files start with "<esc>Lua"
48luaU.VERSION = 80 -- 0x50; last format change was in 5.0
49luaU.VERSION0 = 80 -- 0x50; last major change was in 5.0
50
51-- a multiple of PI for testing native format
52-- multiplying by 1E7 gives non-trivial integer values
53luaU.TEST_NUMBER = 3.14159265358979323846E7
54
55--[[--------------------------------------------------------------------
56-- Additional functions to handle chunk writing
57-- * to use make_setS and make_setF, see test_ldump.lua elsewhere
58----------------------------------------------------------------------]]
59
60------------------------------------------------------------------------
61-- works like the lobject.h version except that TObject used in these
62-- scripts only has a 'value' field, no 'tt' field (native types used)
63------------------------------------------------------------------------
64function luaU:ttype(o)
65 local tt = type(o.value)
66 if tt == "number" then return self.LUA_TNUMBER
67 elseif tt == "string" then return self.LUA_TSTRING
68 elseif tt == "nil" then return self.LUA_TNIL
69 else
70 return self.LUA_TNONE -- the rest should not appear
71 end
72end
73
74------------------------------------------------------------------------
75-- create a chunk writer that writes to a string
76-- * returns the writer function and a table containing the string
77-- * to get the final result, look in buff.data
78------------------------------------------------------------------------
79function luaU:make_setS()
80 local buff = {}
81 buff.data = ""
82 local writer =
83 function(s, buff) -- chunk writer
84 if not s then return end
85 buff.data = buff.data..s
86 end
87 return writer, buff
88end
89
90------------------------------------------------------------------------
91-- create a chunk writer that writes to a file
92-- * returns the writer function and a table containing the file handle
93-- * if a nil is passed, then writer should close the open file
94------------------------------------------------------------------------
95function luaU:make_setF(filename)
96 local buff = {}
97 buff.h = io.open(filename, "wb")
98 if not buff.h then return nil end
99 local writer =
100 function(s, buff) -- chunk writer
101 if not buff.h then return end
102 if not s then buff.h:close(); return end
103 buff.h:write(s)
104 end
105 return writer, buff
106end
107
108-----------------------------------------------------------------------
109-- converts a IEEE754 double number to an 8-byte little-endian string
110-- * luaU:from_double() and luaU:from_int() are from ChunkBake project
111-- * supports +/- Infinity, but not denormals or NaNs
112-----------------------------------------------------------------------
113function luaU:from_double(x)
114 local function grab_byte(v)
115 return math.floor(v / 256),
116 string.char(math.mod(math.floor(v), 256))
117 end
118 local sign = 0
119 if x < 0 then sign = 1; x = -x end
120 local mantissa, exponent = math.frexp(x)
121 if x == 0 then -- zero
122 mantissa, exponent = 0, 0
123 elseif x == 1/0 then
124 mantissa, exponent = 0, 2047
125 else
126 mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53)
127 exponent = exponent + 1022
128 end
129 local v, byte = "" -- convert to bytes
130 x = mantissa
131 for i = 1,6 do
132 x, byte = grab_byte(x); v = v..byte -- 47:0
133 end
134 x, byte = grab_byte(exponent * 16 + x); v = v..byte -- 55:48
135 x, byte = grab_byte(sign * 128 + x); v = v..byte -- 63:56
136 return v
137end
138
139-----------------------------------------------------------------------
140-- converts a number to a little-endian 32-bit integer string
141-- * input value assumed to not overflow, can be signed/unsigned
142-----------------------------------------------------------------------
143function luaU:from_int(x)
144 local v = ""
145 x = math.floor(x)
146 if x >= 0 then
147 for i = 1, 4 do
148 v = v..string.char(math.mod(x, 256)); x = math.floor(x / 256)
149 end
150 else-- x < 0
151 x = -x
152 local carry = 1
153 for i = 1, 4 do
154 local c = 255 - math.mod(x, 256) + carry
155 if c == 256 then c = 0; carry = 1 else carry = 0 end
156 v = v..string.char(c); x = math.floor(x / 256)
157 end
158 end
159 return v
160end
161
162--[[--------------------------------------------------------------------
163-- Functions to make a binary chunk
164-- * many functions have the size parameter removed, since output is
165-- in the form of a string and some sizes are implicit or hard-coded
166-- * luaU:DumpVector has been deleted (used in DumpCode & DumpLines)
167----------------------------------------------------------------------]]
168
169------------------------------------------------------------------------
170-- dump a block of literal bytes
171------------------------------------------------------------------------
172function luaU:DumpLiteral(s, D) self:DumpBlock(s, D) end
173
174--[[--------------------------------------------------------------------
175-- struct DumpState:
176-- L -- lua_State (not used in this script)
177-- write -- lua_Chunkwriter (chunk writer function)
178-- data -- void* (chunk writer context or data already written)
179----------------------------------------------------------------------]]
180
181------------------------------------------------------------------------
182-- dumps a block of bytes
183-- * lua_unlock(D.L), lua_lock(D.L) deleted
184------------------------------------------------------------------------
185function luaU:DumpBlock(b, D) D.write(b, D.data) end
186
187------------------------------------------------------------------------
188-- dumps a single byte
189------------------------------------------------------------------------
190function luaU:DumpByte(y, D)
191 self:DumpBlock(string.char(y), D)
192end
193
194------------------------------------------------------------------------
195-- dumps a 32-bit signed integer (for int)
196------------------------------------------------------------------------
197function luaU:DumpInt(x, D)
198 self:DumpBlock(self:from_int(x), D)
199end
200
201------------------------------------------------------------------------
202-- dumps a 32-bit unsigned integer (for size_t)
203------------------------------------------------------------------------
204function luaU:DumpSize(x, D)
205 self:DumpBlock(self:from_int(x), D)
206end
207
208------------------------------------------------------------------------
209-- dumps a LUA_NUMBER (hard-coded as a double)
210------------------------------------------------------------------------
211function luaU:DumpNumber(x, D)
212 self:DumpBlock(self:from_double(x), D)
213end
214
215------------------------------------------------------------------------
216-- dumps a Lua string
217------------------------------------------------------------------------
218function luaU:DumpString(s, D)
219 if s == nil then
220 self:DumpSize(0, D)
221 else
222 s = s.."\0" -- include trailing '\0'
223 self:DumpSize(string.len(s), D)
224 self:DumpBlock(s, D)
225 end
226end
227
228------------------------------------------------------------------------
229-- dumps instruction block from function prototype
230------------------------------------------------------------------------
231function luaU:DumpCode(f, D)
232 local n = f.sizecode
233 self:DumpInt(n, D)
234 --was DumpVector
235 for i = 0, n - 1 do
236 self:DumpBlock(luaP:Instruction(f.code[i]), D)
237 end
238end
239
240------------------------------------------------------------------------
241-- dumps local variable names from function prototype
242------------------------------------------------------------------------
243function luaU:DumpLocals(f, D)
244 local n = f.sizelocvars
245 self:DumpInt(n, D)
246 for i = 0, n - 1 do
247 self:DumpString(f.locvars[i].varname, D)
248 self:DumpInt(f.locvars[i].startpc, D)
249 self:DumpInt(f.locvars[i].endpc, D)
250 end
251end
252
253------------------------------------------------------------------------
254-- dumps line information from function prototype
255------------------------------------------------------------------------
256function luaU:DumpLines(f, D)
257 local n = f.sizelineinfo
258 self:DumpInt(n, D)
259 --was DumpVector
260 for i = 0, n - 1 do
261 self:DumpInt(f.lineinfo[i], D) -- was DumpBlock
262 end
263end
264
265------------------------------------------------------------------------
266-- dump upvalue names from function prototype
267------------------------------------------------------------------------
268function luaU:DumpUpvalues(f, D)
269 local n = f.sizeupvalues
270 self:DumpInt(n, D)
271 for i = 0, n - 1 do
272 self:DumpString(f.upvalues[i], D)
273 end
274end
275
276------------------------------------------------------------------------
277-- dump constant pool from function prototype
278-- * nvalue(o) and tsvalue(o) macros removed
279------------------------------------------------------------------------
280function luaU:DumpConstants(f, D)
281 local n = f.sizek
282 self:DumpInt(n, D)
283 for i = 0, n - 1 do
284 local o = f.k[i] -- TObject
285 local tt = self:ttype(o)
286 self:DumpByte(tt, D)
287 if tt == self.LUA_TNUMBER then
288 self:DumpNumber(o.value, D)
289 elseif tt == self.LUA_TSTRING then
290 self:DumpString(o.value, D)
291 elseif tt == self.LUA_TNIL then
292 else
293 --lua_assert(0) -- cannot happen
294 end
295 end
296 n = f.sizep
297 self:DumpInt(n, D)
298 for i = 0, n - 1 do
299 self:DumpFunction(f.p[i], f.source, D)
300 end
301end
302
303------------------------------------------------------------------------
304-- dump child function prototypes from function prototype
305------------------------------------------------------------------------
306function luaU:DumpFunction(f, p, D)
307 local source = f.source
308 if source == p then source = nil end
309 self:DumpString(source, D)
310 self:DumpInt(f.lineDefined, D)
311 self:DumpByte(f.nups, D)
312 self:DumpByte(f.numparams, D)
313 self:DumpByte(f.is_vararg, D)
314 self:DumpByte(f.maxstacksize, D)
315 self:DumpLines(f, D)
316 self:DumpLocals(f, D)
317 self:DumpUpvalues(f, D)
318 self:DumpConstants(f, D)
319 self:DumpCode(f, D)
320end
321
322------------------------------------------------------------------------
323-- dump Lua header section (some sizes hard-coded)
324------------------------------------------------------------------------
325function luaU:DumpHeader(D)
326 self:DumpLiteral(self.LUA_SIGNATURE, D)
327 self:DumpByte(self.VERSION, D)
328 self:DumpByte(self:endianness(), D)
329 self:DumpByte(4, D) -- sizeof(int)
330 self:DumpByte(4, D) -- sizeof(size_t)
331 self:DumpByte(4, D) -- sizeof(Instruction)
332 self:DumpByte(luaP.SIZE_OP, D)
333 self:DumpByte(luaP.SIZE_A, D)
334 self:DumpByte(luaP.SIZE_B, D)
335 self:DumpByte(luaP.SIZE_C, D)
336 self:DumpByte(8, D) -- sizeof(lua_Number)
337 self:DumpNumber(self.TEST_NUMBER, D)
338end
339
340------------------------------------------------------------------------
341-- dump function as precompiled chunk
342-- * w, data are created from make_setS, make_setF
343------------------------------------------------------------------------
344function luaU:dump(L, Main, w, data)
345 local D = {} -- DumpState
346 D.L = L
347 D.write = w
348 D.data = data
349 self:DumpHeader(D)
350 self:DumpFunction(Main, nil, D)
351 -- added: for a chunk writer writing to a file, this final call with
352 -- nil data is to indicate to the writer to close the file
353 D.write(nil, D.data)
354end
355
356------------------------------------------------------------------------
357-- find byte order (from lundump.c)
358-- * hard-coded to little-endian
359------------------------------------------------------------------------
360function luaU:endianness()
361 return 1
362end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua
deleted file mode 100644
index 077f1aa..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/llex.lua
+++ /dev/null
@@ -1,531 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 llex.lua
4 Lua 5 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-- * Added:
21-- luaX:chunkid (from lobject.c)
22-- * To use the lexer:
23-- (1) luaX:init() to initialize the lexer
24-- (2) luaX:setinput() to set the input stream to lex, get LS
25-- (3) call luaX:lex() to get tokens, until "TK_EOS":
26-- LS.t.token = luaX:lex(LS, LS.t)
27-- * since EOZ is returned as a string, be careful when regexp testing
28----------------------------------------------------------------------]]
29
30luaX = {}
31
32-- FIRST_RESERVED is not required as tokens are manipulated as strings
33-- TOKEN_LEN deleted; maximum length of a reserved word
34
35------------------------------------------------------------------------
36-- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
37------------------------------------------------------------------------
38
39-- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
40-- other terminal symbols: TK_NAME to TK_EOS
41luaX.RESERVED = [[
42TK_AND and
43TK_BREAK break
44TK_DO do
45TK_ELSE else
46TK_ELSEIF elseif
47TK_END end
48TK_FALSE false
49TK_FOR for
50TK_FUNCTION function
51TK_IF if
52TK_IN in
53TK_LOCAL local
54TK_NIL nil
55TK_NOT not
56TK_OR or
57TK_REPEAT repeat
58TK_RETURN return
59TK_THEN then
60TK_TRUE true
61TK_UNTIL until
62TK_WHILE while
63TK_NAME *name
64TK_CONCAT ..
65TK_DOTS ...
66TK_EQ ==
67TK_GE >=
68TK_LE <=
69TK_NE ~=
70TK_NUMBER *number
71TK_STRING *string
72TK_EOS <eof>]]
73
74-- NUM_RESERVED is not required; number of reserved words
75
76--[[--------------------------------------------------------------------
77-- Instead of passing seminfo, the Token struct (e.g. LS.t) is passed
78-- so that lexer functions can use its table element, LS.t.seminfo
79--
80-- Token (struct of LS.t and LS.lookahead):
81-- token -- token symbol
82-- seminfo -- semantics information
83--
84-- LexState (struct of LS; LS is initialized by luaX:setinput):
85-- current -- current character
86-- linenumber -- input line counter
87-- lastline -- line of last token 'consumed'
88-- t -- current token (table: struct Token)
89-- lookahead -- look ahead token (table: struct Token)
90-- fs -- 'FuncState' is private to the parser
91-- L -- LuaState
92-- z -- input stream
93-- buff -- buffer for tokens
94-- source -- current source name
95-- nestlevel -- level of nested non-terminals
96----------------------------------------------------------------------]]
97
98-- token2string is now a hash; see luaX:init
99
100------------------------------------------------------------------------
101-- initialize lexer
102------------------------------------------------------------------------
103function luaX:init()
104 self.token2string = {}
105 self.string2token = {}
106 for v in string.gfind(self.RESERVED, "[^\n]+") do
107 local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
108 self.token2string[tok] = str
109 self.string2token[str] = tok
110 end
111end
112
113luaX.MAXSRC = 80
114
115------------------------------------------------------------------------
116-- returns a suitably-formatted chunk name or id
117-- * from lobject.c, used in llex.c and ldebug.c
118-- * the result, out, is returned (was first argument)
119------------------------------------------------------------------------
120function luaX:chunkid(source, bufflen)
121 local out
122 local first = string.sub(source, 1, 1)
123 if first == "=" then
124 out = string.sub(source, 2, bufflen) -- remove first char
125 else -- out = "source", or "...source"
126 if first == "@" then
127 source = string.sub(source, 2) -- skip the '@'
128 bufflen = bufflen - string.len(" `...' ")
129 local l = string.len(source)
130 out = ""
131 if l > bufflen then
132 source = string.sub(source, 1 + l - bufflen) -- get last part of file name
133 out = out.."..."
134 end
135 out = out..source
136 else -- out = [string "string"]
137 local len = string.find(source, "\n", 1, 1) -- stop at first newline
138 len = len and (len - 1) or string.len(source)
139 bufflen = bufflen - string.len(" [string \"...\"] ")
140 if len > bufflen then len = bufflen end
141 out = "[string \""
142 if len < string.len(source) then -- must truncate?
143 out = out..string.sub(source, 1, len).."..."
144 else
145 out = out..source
146 end
147 out = out.."\"]"
148 end
149 end
150 return out
151end
152
153--[[--------------------------------------------------------------------
154-- Support functions for lexer
155-- * all lexer errors eventually reaches errorline:
156 checklimit -> syntaxerror -> error -> errorline
157 lexerror -> error -> errorline
158----------------------------------------------------------------------]]
159
160------------------------------------------------------------------------
161-- limit check, syntax error if fails (also called by parser)
162------------------------------------------------------------------------
163function luaX:checklimit(ls, val, limit, msg)
164 if val > limit then
165 msg = string.format("too many %s (limit=%d)", msg, limit)
166 self:syntaxerror(ls, msg)
167 end
168end
169
170------------------------------------------------------------------------
171-- formats error message and throws error (also called by parser)
172------------------------------------------------------------------------
173function luaX:errorline(ls, s, token, line)
174 local buff = self:chunkid(ls.source, self.MAXSRC)
175 error(string.format("%s:%d: %s near `%s'", buff, line, s, token))
176end
177
178------------------------------------------------------------------------
179-- throws an error, adds line number
180------------------------------------------------------------------------
181function luaX:error(ls, s, token)
182 self:errorline(ls, s, token, ls.linenumber)
183end
184
185------------------------------------------------------------------------
186-- throws a syntax error (mainly called by parser)
187-- * ls.t.token has to be set by the function calling luaX:lex
188-- (see next() and lookahead() in lparser.c)
189------------------------------------------------------------------------
190function luaX:syntaxerror(ls, msg)
191 local lasttoken
192 local tok = ls.t.token
193 if tok == "TK_NAME" then
194 lasttoken = ls.t.seminfo
195 elseif tok == "TK_STRING" or tok == "TK_NUMBER" then
196 lasttoken = ls.buff
197 else
198 lasttoken = self:token2str(ls.t.token)
199 end
200 self:error(ls, msg, lasttoken)
201end
202
203------------------------------------------------------------------------
204-- look up token and return keyword if found (also called by parser)
205------------------------------------------------------------------------
206function luaX:token2str(ls, token)
207 if string.sub(token, 1, 3) ~= "TK_" then
208 return token
209 else
210 --lua_assert(string.len(token) == 1)
211 return self.token2string[token]
212 end
213end
214
215------------------------------------------------------------------------
216-- throws a lexer error
217------------------------------------------------------------------------
218function luaX:lexerror(ls, s, token)
219 if token == "TK_EOS" then
220 self:error(ls, s, self:token2str(ls, token))
221 else
222 self:error(ls, s, ls.buff)
223 end
224end
225
226------------------------------------------------------------------------
227-- move on to next line
228------------------------------------------------------------------------
229function luaX:inclinenumber(LS)
230 self:next(LS) -- skip '\n'
231 LS.linenumber = LS.linenumber + 1
232 self:checklimit(LS, LS.linenumber, self.MAX_INT, "lines in a chunk")
233end
234
235luaX.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h)
236
237------------------------------------------------------------------------
238-- initializes an input stream for lexing
239-- * if LS (the lexer state) is passed as a table, then it is filled in,
240-- otherwise it has to be retrieved as a return value
241------------------------------------------------------------------------
242function luaX:setinput(L, LS, z, source)
243 if not LS then LS = {} end -- create struct
244 if not LS.lookahead then LS.lookahead = {} end
245 if not LS.t then LS.t = {} end
246 LS.L = L
247 LS.lookahead.token = "TK_EOS" -- no look-ahead token
248 LS.z = z
249 LS.fs = nil
250 LS.linenumber = 1
251 LS.lastline = 1
252 LS.source = source
253 self:next(LS) -- read first char
254 if LS.current == "#" then
255 repeat -- skip first line
256 self:next(LS)
257 until LS.current == "\n" or LS.current == "EOZ"
258 end
259 return LS
260end
261
262--[[--------------------------------------------------------------------
263-- LEXICAL ANALYZER
264----------------------------------------------------------------------]]
265
266-- NOTE the following buffer handling stuff are no longer required:
267-- use buffer to store names, literal strings and numbers
268-- EXTRABUFF deleted; extra space to allocate when growing buffer
269-- MAXNOCHECK deleted; maximum number of chars that can be read without checking buffer size
270-- checkbuffer(LS, len) deleted
271
272------------------------------------------------------------------------
273-- gets the next character and returns it
274------------------------------------------------------------------------
275function luaX:next(LS)
276 local c = luaZ:zgetc(LS.z)
277 LS.current = c
278 return c
279end
280
281------------------------------------------------------------------------
282-- saves the given character into the token buffer
283------------------------------------------------------------------------
284function luaX:save(LS, c)
285 LS.buff = LS.buff..c
286end
287
288------------------------------------------------------------------------
289-- save current character into token buffer, grabs next character
290------------------------------------------------------------------------
291function luaX:save_and_next(LS)
292 self:save(LS, LS.current)
293 return self:next(LS)
294end
295
296------------------------------------------------------------------------
297-- reads a name
298-- * originally returns the string length
299------------------------------------------------------------------------
300function luaX:readname(LS)
301 LS.buff = ""
302 repeat
303 self:save_and_next(LS)
304 until LS.current == "EOZ" or not string.find(LS.current, "[_%w]")
305 return LS.buff
306end
307
308------------------------------------------------------------------------
309-- reads a number (LUA_NUMBER)
310------------------------------------------------------------------------
311function luaX:read_numeral(LS, comma, Token)
312 LS.buff = ""
313 if comma then self:save(LS, '.') end
314 while string.find(LS.current, "%d") do
315 self:save_and_next(LS)
316 end
317 if LS.current == "." then
318 self:save_and_next(LS)
319 if LS.current == "." then
320 self:save_and_next(LS)
321 self:lexerror(LS,
322 "ambiguous syntax (decimal point x string concatenation)",
323 "TK_NUMBER")
324 end
325 end
326 while string.find(LS.current, "%d") do
327 self:save_and_next(LS)
328 end
329 if LS.current == "e" or LS.current == "E" then
330 self:save_and_next(LS) -- read 'E'
331 if LS.current == "+" or LS.current == "-" then
332 self:save_and_next(LS) -- optional exponent sign
333 end
334 while string.find(LS.current, "%d") do
335 self:save_and_next(LS)
336 end
337 end
338 local seminfo = tonumber(LS.buff)
339 if not seminfo then
340 self:lexerror(LS, "malformed number", "TK_NUMBER")
341 end
342 Token.seminfo = seminfo
343end
344
345------------------------------------------------------------------------
346-- reads a long string or long comment
347------------------------------------------------------------------------
348function luaX:read_long_string(LS, Token)
349 local cont = 0
350 LS.buff = ""
351 self:save(LS, "[") -- save first '['
352 self:save_and_next(LS) -- pass the second '['
353 if LS.current == "\n" then -- string starts with a newline?
354 self:inclinenumber(LS) -- skip it
355 end
356 while true do
357 local c = LS.current
358 if c == "EOZ" then
359 self:lexerror(LS, Token and "unfinished long string" or
360 "unfinished long comment", "TK_EOS")
361 elseif c == "[" then
362 self:save_and_next(LS)
363 if LS.current == "[" then
364 cont = cont + 1
365 self:save_and_next(LS)
366 end
367 elseif c == "]" then
368 self:save_and_next(LS)
369 if LS.current == "]" then
370 if cont == 0 then break end
371 cont = cont - 1
372 self:save_and_next(LS)
373 end
374 elseif c == "\n" then
375 self:save(LS, "\n")
376 self:inclinenumber(LS)
377 if not Token then LS.buff = "" end -- reset buffer to avoid wasting space
378 else
379 self:save_and_next(LS)
380 end--if c
381 end--while
382 self:save_and_next(LS) -- skip the second ']'
383 if Token then
384 Token.seminfo = string.sub(LS.buff, 3, -3)
385 end
386end
387
388------------------------------------------------------------------------
389-- reads a string
390------------------------------------------------------------------------
391function luaX:read_string(LS, del, Token)
392 LS.buff = ""
393 self:save_and_next(LS)
394 while LS.current ~= del do
395 local c = LS.current
396 if c == "EOZ" then
397 self:lexerror(LS, "unfinished string", "TK_EOS")
398 elseif c == "\n" then
399 self:lexerror(LS, "unfinished string", "TK_STRING")
400 elseif c == "\\" then
401 c = self:next(LS) -- do not save the '\'
402 if c ~= "EOZ" then -- will raise an error next loop
403 -- escapes handling greatly simplified here:
404 local i = string.find("abfnrtv\n", c, 1, 1)
405 if i then
406 self:save(LS, string.sub("\a\b\f\n\r\t\v\n", i, i))
407 if i == 8 then self:inclinenumber(LS) else self:next(LS) end
408 elseif not string.find(c, "%d") then
409 self:save_and_next(LS) -- handles \\, \", \', and \?
410 else -- \xxx
411 c, i = 0, 0
412 repeat
413 c = 10 * c + LS.current
414 self:next(LS)
415 i = i + 1
416 until i >= 3 or not string.find(LS.current, "%d")
417 if c > 255 then -- UCHAR_MAX
418 self:lexerror(LS, "escape sequence too large", "TK_STRING")
419 end
420 self:save(LS, string.char(c))
421 end
422 end
423 else
424 self:save_and_next(LS)
425 end--if c
426 end--while
427 self:save_and_next(LS) -- skip delimiter
428 Token.seminfo = string.sub(LS.buff, 2, -2)
429end
430
431------------------------------------------------------------------------
432-- main lexer function
433------------------------------------------------------------------------
434function luaX:lex(LS, Token)
435 while true do
436 local c = LS.current
437 ----------------------------------------------------------------
438 if c == "\n" then
439 self:inclinenumber(LS)
440 ----------------------------------------------------------------
441 elseif c == "-" then
442 c = self:next(LS)
443 if c ~= "-" then return "-" end
444 -- else is a comment
445 c = self:next(LS)
446 if c == "[" and self:next(LS) == "[" then
447 self:read_long_string(LS) -- long comment
448 else -- short comment
449 c = LS.current
450 while c ~= "\n" and c ~= "EOZ" do
451 c = self:next(LS)
452 end
453 end
454 ----------------------------------------------------------------
455 elseif c == "[" then
456 c = self:next(LS)
457 if c ~= "[" then return "["
458 else
459 self:read_long_string(LS, Token)
460 return "TK_STRING"
461 end
462 ----------------------------------------------------------------
463 elseif c == "=" then
464 c = self:next(LS)
465 if c ~= "=" then return "="
466 else self:next(LS); return "TK_EQ" end
467 ----------------------------------------------------------------
468 elseif c == "<" then
469 c = self:next(LS)
470 if c ~= "=" then return "<"
471 else self:next(LS); return "TK_LE" end
472 ----------------------------------------------------------------
473 elseif c == ">" then
474 c = self:next(LS)
475 if c ~= "=" then return ">"
476 else self:next(LS); return "TK_GE" end
477 ----------------------------------------------------------------
478 elseif c == "~" then
479 c = self:next(LS)
480 if c ~= "=" then return "~"
481 else self:next(LS); return "TK_NE" end
482 ----------------------------------------------------------------
483 elseif c == "\"" or c == "'" then
484 self:read_string(LS, c, Token)
485 return "TK_STRING"
486 ----------------------------------------------------------------
487 elseif c == "." then
488 c = self:next(LS)
489 if c == "." then
490 c = self:next(LS)
491 if c == "." then
492 self:next(LS)
493 return "TK_DOTS" -- ...
494 else
495 return "TK_CONCAT" -- ..
496 end
497 elseif not string.find(c, "%d") then
498 return '.'
499 else
500 self:read_numeral(LS, true, Token)
501 return "TK_NUMBER"
502 end
503 ----------------------------------------------------------------
504 elseif c == "EOZ" then
505 return "TK_EOS"
506 ----------------------------------------------------------------
507 else -- default
508 if string.find(c, "%s") then
509 self:next(LS)
510 elseif string.find(c, "%d") then
511 self:read_numeral(LS, false, Token)
512 return "TK_NUMBER"
513 elseif string.find(c, "[_%a]") then
514 -- identifier or reserved word
515 local l = self:readname(LS)
516 local tok = self.string2token[l]
517 if tok then return tok end -- reserved word?
518 Token.seminfo = l
519 return "TK_NAME"
520 else
521 if string.find(c, "%c") then
522 self:error(LS, "invalid control char",
523 string.format("char(%d)", string.byte(c)))
524 end
525 self:next(LS)
526 return c -- single-char tokens (+ - / ...)
527 end
528 ----------------------------------------------------------------
529 end--if c
530 end--while
531end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua
deleted file mode 100644
index 0c4eebd..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lopcodes.lua
+++ /dev/null
@@ -1,349 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 lopcodes.lua
4 Lua 5 virtual machine opcodes 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-- * an Instruction is a table with OP, A, B, C, Bx elements; this
18-- should allow instruction handling to work with doubles and ints
19-- * Added:
20-- luaP:Instruction(i): convert field elements to a 4-char string
21-- luaP:DecodeInst(x): convert 4-char string into field elements
22-- * WARNING luaP:Instruction outputs instructions encoded in little-
23-- endian form and field size and positions are hard-coded
24----------------------------------------------------------------------]]
25
26luaP = {}
27
28--[[
29===========================================================================
30 We assume that instructions are unsigned numbers.
31 All instructions have an opcode in the first 6 bits.
32 Instructions can have the following fields:
33 'A' : 8 bits
34 'B' : 9 bits
35 'C' : 9 bits
36 'Bx' : 18 bits ('B' and 'C' together)
37 'sBx' : signed Bx
38
39 A signed argument is represented in excess K; that is, the number
40 value is the unsigned value minus K. K is exactly the maximum value
41 for that argument (so that -max is represented by 0, and +max is
42 represented by 2*max), which is half the maximum for the corresponding
43 unsigned argument.
44===========================================================================
45--]]
46
47luaP.OpMode = {"iABC", "iABx", "iAsBx"} -- basic instruction format
48
49------------------------------------------------------------------------
50-- size and position of opcode arguments.
51-- * WARNING size and position is hard-coded elsewhere in this script
52------------------------------------------------------------------------
53luaP.SIZE_C = 9
54luaP.SIZE_B = 9
55luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B
56luaP.SIZE_A = 8
57
58luaP.SIZE_OP = 6
59
60luaP.POS_C = luaP.SIZE_OP
61luaP.POS_B = luaP.POS_C + luaP.SIZE_C
62luaP.POS_Bx = luaP.POS_C
63luaP.POS_A = luaP.POS_B + luaP.SIZE_B
64
65------------------------------------------------------------------------
66-- limits for opcode arguments.
67-- we use (signed) int to manipulate most arguments,
68-- so they must fit in BITS_INT-1 bits (-1 for sign)
69------------------------------------------------------------------------
70-- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is
71-- running on a Lua VM with double or int as LUA_NUMBER
72
73luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1
74luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed
75
76luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1
77luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1
78luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1
79
80-- creates a mask with 'n' 1 bits at position 'p'
81-- MASK1(n,p) deleted
82-- creates a mask with 'n' 0 bits at position 'p'
83-- MASK0(n,p) deleted
84
85--[[--------------------------------------------------------------------
86 Visual representation for reference:
87
88 31 | | | 0 bit position
89 +-----+-----+-----+----------+
90 | A | B | C | Opcode | iABC format
91 +-----+-----+-----+----------+
92 - 8 - 9 - 9 - 6 - field sizes
93 +-----+-----+-----+----------+
94 | A | [s]Bx | Opcode | iABx | iAsBx format
95 +-----+-----+-----+----------+
96----------------------------------------------------------------------]]
97
98------------------------------------------------------------------------
99-- the following macros help to manipulate instructions
100-- * changed to a table object representation, very clean compared to
101-- the [nightmare] alternatives of using a number or a string
102------------------------------------------------------------------------
103
104-- these accept or return opcodes in the form of string names
105function luaP:GET_OPCODE(i) return self.ROpCode[i.OP] end
106function luaP:SET_OPCODE(i, o) i.OP = self.OpCode[o] end
107
108function luaP:GETARG_A(i) return i.A end
109function luaP:SETARG_A(i, u) i.A = u end
110
111function luaP:GETARG_B(i) return i.B end
112function luaP:SETARG_B(i, b) i.B = b end
113
114function luaP:GETARG_C(i) return i.C end
115function luaP:SETARG_C(i, b) i.C = b end
116
117function luaP:GETARG_Bx(i) return i.Bx end
118function luaP:SETARG_Bx(i, b) i.Bx = b end
119
120function luaP:GETARG_sBx(i) return i.Bx - self.MAXARG_sBx end
121function luaP:SETARG_sBx(i, b) i.Bx = b + self.MAXARG_sBx end
122
123function luaP:CREATE_ABC(o,a,b,c)
124 return {OP = self.OpCode[o], A = a, B = b, C = c}
125end
126
127function luaP:CREATE_ABx(o,a,bc)
128 return {OP = self.OpCode[o], A = a, Bx = bc}
129end
130
131------------------------------------------------------------------------
132-- returns a 4-char string little-endian encoded form of an instruction
133------------------------------------------------------------------------
134function luaP:Instruction(i)
135 local I, c0, c1, c2, c3
136 if i.Bx then
137 -- change to OP/A/B/C format
138 i.C = math.mod(i.Bx, 512)
139 i.B = math.floor(i.Bx / 512)
140 end
141 I = i.C * 64 + i.OP
142 c0 = math.mod(I, 256)
143 I = i.B * 128 + math.floor(I / 256) -- 7 bits of C left
144 c1 = math.mod(I, 256)
145 I = math.floor(I / 256) -- 8 bits of B left
146 c2 = math.mod(I, 256)
147 c3 = math.mod(i.A, 256)
148 return string.char(c0, c1, c2, c3)
149end
150
151------------------------------------------------------------------------
152-- decodes a 4-char little-endian string into an instruction struct
153------------------------------------------------------------------------
154function luaP:DecodeInst(x)
155 local i = {}
156 local I = string.byte(x, 1)
157 local op = math.mod(I, 64)
158 i.OP = op
159 I = string.byte(x, 2) * 4 + math.floor(I / 64) -- 2 bits of c0 left
160 i.C = math.mod(I, 512)
161 i.B = string.byte(x, 3) * 2 + math.floor(I / 128) -- 1 bit of c2 left
162 i.A = string.byte(x, 4)
163 local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))]
164 if opmode ~= "iABC" then
165 i.Bx = i.B * 512 + i.C
166 end
167 return i
168end
169
170------------------------------------------------------------------------
171-- invalid register that fits in 8 bits
172------------------------------------------------------------------------
173luaP.NO_REG = luaP.MAXARG_A
174
175------------------------------------------------------------------------
176-- R(x) - register
177-- Kst(x) - constant (in constant table)
178-- RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
179------------------------------------------------------------------------
180
181------------------------------------------------------------------------
182-- grep "ORDER OP" if you change these enums
183------------------------------------------------------------------------
184
185--[[--------------------------------------------------------------------
186Lua virtual machine opcodes (enum OpCode):
187------------------------------------------------------------------------
188name args description
189------------------------------------------------------------------------
190OP_MOVE A B R(A) := R(B)
191OP_LOADK A Bx R(A) := Kst(Bx)
192OP_LOADBOOL A B C R(A) := (Bool)B; if (C) PC++
193OP_LOADNIL A B R(A) := ... := R(B) := nil
194OP_GETUPVAL A B R(A) := UpValue[B]
195OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)]
196OP_GETTABLE A B C R(A) := R(B)[RK(C)]
197OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A)
198OP_SETUPVAL A B UpValue[B] := R(A)
199OP_SETTABLE A B C R(A)[RK(B)] := RK(C)
200OP_NEWTABLE A B C R(A) := {} (size = B,C)
201OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)]
202OP_ADD A B C R(A) := RK(B) + RK(C)
203OP_SUB A B C R(A) := RK(B) - RK(C)
204OP_MUL A B C R(A) := RK(B) * RK(C)
205OP_DIV A B C R(A) := RK(B) / RK(C)
206OP_POW A B C R(A) := RK(B) ^ RK(C)
207OP_UNM A B R(A) := -R(B)
208OP_NOT A B R(A) := not R(B)
209OP_CONCAT A B C R(A) := R(B).. ... ..R(C)
210OP_JMP sBx PC += sBx
211OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++
212OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++
213OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++
214OP_TEST A B C if (R(B) <=> C) then R(A) := R(B) else pc++
215OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
216OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1))
217OP_RETURN A B return R(A), ... ,R(A+B-2) (see note)
218OP_FORLOOP A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx
219OP_TFORLOOP A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
220 if R(A+2) ~= nil then pc++
221OP_TFORPREP A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
222 PC += sBx
223OP_SETLIST A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1
224OP_SETLISTO A Bx (see note)
225OP_CLOSE A close all variables in the stack up to (>=) R(A)
226OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
227----------------------------------------------------------------------]]
228
229luaP.opnames = {} -- opcode names
230luaP.OpCode = {} -- lookup name -> number
231luaP.ROpCode = {} -- lookup number -> name
232
233-- ORDER OP
234local i = 0
235for v in string.gfind([[
236MOVE LOADK LOADBOOL LOADNIL GETUPVAL
237GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE
238NEWTABLE SELF ADD SUB MUL
239DIV POW UNM NOT CONCAT
240JMP EQ LT LE TEST
241CALL TAILCALL RETURN FORLOOP TFORLOOP
242TFORPREP SETLIST SETLISTO CLOSE CLOSURE
243]], "%S+") do
244 local n = "OP_"..v
245 luaP.opnames[i] = v
246 luaP.OpCode[n] = i
247 luaP.ROpCode[i] = n
248 i = i + 1
249end
250luaP.NUM_OPCODES = i
251
252--[[
253===========================================================================
254 Notes:
255 (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
256 and can be 0: OP_CALL then sets 'top' to last_result+1, so
257 next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
258
259 (2) In OP_RETURN, if (B == 0) then return up to 'top'
260
261 (3) For comparisons, B specifies what conditions the test should accept.
262
263 (4) All 'skips' (pc++) assume that next instruction is a jump
264
265 (5) OP_SETLISTO is used when the last item in a table constructor is a
266 function, so the number of elements set is up to top of stack
267===========================================================================
268--]]
269
270------------------------------------------------------------------------
271-- masks for instruction properties
272------------------------------------------------------------------------
273-- was enum OpModeMask:
274luaP.OpModeBreg = 2 -- B is a register
275luaP.OpModeBrk = 3 -- B is a register/constant
276luaP.OpModeCrk = 4 -- C is a register/constant
277luaP.OpModesetA = 5 -- instruction set register A
278luaP.OpModeK = 6 -- Bx is a constant
279luaP.OpModeT = 1 -- operator is a test
280
281------------------------------------------------------------------------
282-- get opcode mode, e.g. "iABC"
283------------------------------------------------------------------------
284function luaP:getOpMode(m)
285 return self.OpMode[tonumber(string.sub(self.opmodes[self.OpCode[m] + 1], 7, 7))]
286end
287
288------------------------------------------------------------------------
289-- test an instruction property flag
290-- * b is a string, e.g. "OpModeBreg"
291------------------------------------------------------------------------
292function luaP:testOpMode(m, b)
293 return (string.sub(self.opmodes[self.OpCode[m] + 1], self[b], self[b]) == "1")
294end
295
296-- number of list items to accumulate before a SETLIST instruction
297-- (must be a power of 2)
298-- * used in lparser, lvm, ldebug, ltests
299luaP.LFIELDS_PER_FLUSH = 32
300
301-- luaP_opnames[] is set above, as the luaP.opnames table
302-- opmode(t,b,bk,ck,sa,k,m) deleted
303
304--[[--------------------------------------------------------------------
305 Legend for luaP:opmodes:
306 T -> T B -> B mode -> m, where iABC = 1
307 Bk -> b Ck -> C iABx = 2
308 sA -> A K -> K iAsBx = 3
309----------------------------------------------------------------------]]
310
311-- ORDER OP
312luaP.opmodes = {
313-- TBbCAKm opcode
314 "0100101", -- OP_MOVE
315 "0000112", -- OP_LOADK
316 "0000101", -- OP_LOADBOOL
317 "0100101", -- OP_LOADNIL
318 "0000101", -- OP_GETUPVAL
319 "0000112", -- OP_GETGLOBAL
320 "0101101", -- OP_GETTABLE
321 "0000012", -- OP_SETGLOBAL
322 "0000001", -- OP_SETUPVAL
323 "0011001", -- OP_SETTABLE
324 "0000101", -- OP_NEWTABLE
325 "0101101", -- OP_SELF
326 "0011101", -- OP_ADD
327 "0011101", -- OP_SUB
328 "0011101", -- OP_MUL
329 "0011101", -- OP_DIV
330 "0011101", -- OP_POW
331 "0100101", -- OP_UNM
332 "0100101", -- OP_NOT
333 "0101101", -- OP_CONCAT
334 "0000003", -- OP_JMP
335 "1011001", -- OP_EQ
336 "1011001", -- OP_LT
337 "1011001", -- OP_LE
338 "1100101", -- OP_TEST
339 "0000001", -- OP_CALL
340 "0000001", -- OP_TAILCALL
341 "0000001", -- OP_RETURN
342 "0000003", -- OP_FORLOOP
343 "1000001", -- OP_TFORLOOP
344 "0000003", -- OP_TFORPREP
345 "0000002", -- OP_SETLIST
346 "0000002", -- OP_SETLISTO
347 "0000001", -- OP_CLOSE
348 "0000102", -- OP_CLOSURE
349}
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua
deleted file mode 100644
index 3180a7f..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua
+++ /dev/null
@@ -1,1706 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 lparser.lua
4 Lua 5 parser 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-- * LUA_COMPATUPSYNTAX option changed into a comment block
18-- * Added:
19-- some constants, see below
20-- luaY:newproto (from lfunc.c) -- called by lparser, lundump, luac
21-- luaY:int2fb (from lobject.c) -- called by lparser, ltests
22-- luaY:log2 (from lobject.c) -- called by lparser, ltests, ltable
23-- luaY:growvector (from lmem.h) -- skeleton only, limit checking
24-- * Unimplemented:
25-- luaG_checkcode() in lua_assert is not currently implemented
26----------------------------------------------------------------------]]
27
28--requires luaP, luaX, luaK
29luaY = {}
30
31------------------------------------------------------------------------
32-- constants used by parser
33-- * MAX_INT duplicated in luaX.MAX_INT
34------------------------------------------------------------------------
35luaY.MAX_INT = 2147483645 -- INT_MAX-2 for 32-bit systems (llimits.h)
36luaY.MAXVARS = 200 -- (llimits.h)
37luaY.MAXUPVALUES = 32 -- (llimits.h)
38luaY.MAXPARAMS = 100 -- (llimits.h)
39luaY.LUA_MAXPARSERLEVEL = 200 -- (llimits.h)
40luaY.LUA_MULTRET = -1 -- (lua.h)
41luaY.MAXSTACK = 250 -- (llimits.h, used in lcode.lua)
42
43------------------------------------------------------------------------
44-- Expression descriptor
45------------------------------------------------------------------------
46
47--[[--------------------------------------------------------------------
48-- * expkind changed to string constants; luaY:assignment was the only
49-- function to use a relational operator with this enumeration
50-- VVOID -- no value
51-- VNIL -- no value
52-- VTRUE -- no value
53-- VFALSE -- no value
54-- VK -- info = index of constant in 'k'
55-- VLOCAL -- info = local register
56-- VUPVAL, -- info = index of upvalue in 'upvalues'
57-- VGLOBAL -- info = index of table; aux = index of global name in 'k'
58-- VINDEXED -- info = table register; aux = index register (or 'k')
59-- VJMP -- info = instruction pc
60-- VRELOCABLE -- info = instruction pc
61-- VNONRELOC -- info = result register
62-- VCALL -- info = result register
63----------------------------------------------------------------------]]
64
65--[[--------------------------------------------------------------------
66-- struct expdesc:
67-- k -- (enum: expkind)
68-- info, aux
69-- t -- patch list of 'exit when true'
70-- f -- patch list of 'exit when false'
71----------------------------------------------------------------------]]
72
73--[[--------------------------------------------------------------------
74-- state needed to generate code for a given function
75-- struct FuncState:
76-- f -- current function header (table: Proto)
77-- h -- table to find (and reuse) elements in 'k' (table: Table)
78-- prev -- enclosing function (table: FuncState)
79-- ls -- lexical state (table: LexState)
80-- L -- copy of the Lua state (table: lua_State)
81-- bl -- chain of current blocks (table: BlockCnt)
82-- pc -- next position to code (equivalent to 'ncode')
83-- lasttarget -- 'pc' of last 'jump target'
84-- jpc -- list of pending jumps to 'pc'
85-- freereg -- first free register
86-- nk -- number of elements in 'k'
87-- np -- number of elements in 'p'
88-- nlocvars -- number of elements in 'locvars'
89-- nactvar -- number of active local variables
90-- upvalues[MAXUPVALUES] -- upvalues (table: expdesc)
91-- actvar[MAXVARS] -- declared-variable stack
92----------------------------------------------------------------------]]
93
94------------------------------------------------------------------------
95-- converts an integer to a "floating point byte", represented as
96-- (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
97------------------------------------------------------------------------
98
99function luaY:int2fb(x)
100 local m = 0 -- mantissa
101 while x >= 8 do
102 x = math.floor((x + 1) / 2)
103 m = m + 1
104 end
105 return m * 8 + x
106end
107
108------------------------------------------------------------------------
109-- calculates log value for encoding the hash portion's size
110-- * there are 2 implementations: the shorter one uses math.frexp
111-- while the other one is based on the original code, so pick one...
112-- * since LUA_NUMBER is assumed to be a double elsewhere, the
113-- shorter version works fine
114------------------------------------------------------------------------
115--[[
116function luaY:log2(x)
117 -- this is based on the original lua0_log2 in lobject.c
118 local log_8 = { -- index starts from 1
119 0,
120 1,1,
121 2,2,2,2,
122 3,3,3,3,3,3,3,3,
123 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
124 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
125 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
126 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
127 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
128 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
129 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
130 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
131 }
132 if x >= 65536 then
133 if x >= 16777216 then
134 return log_8[math.mod(math.floor(x / 16777216), 256)] + 24
135 else
136 return log_8[math.mod(math.floor(x / 65536), 256)] + 16
137 end
138 else
139 if x >= 256 then
140 return log_8[math.mod(math.floor(x / 256), 256)] + 8
141 elseif x > 0 then
142 return log_8[math.mod(x, 256)]
143 end
144 return -1 -- special 'log' for 0
145 end
146end
147--]]
148-- [[
149function luaY:log2(x)
150 -- math result is always one more than lua0_log2()
151 local mn, ex = math.frexp(x)
152 return ex - 1
153end
154--]]
155
156------------------------------------------------------------------------
157-- this is a stripped-down luaM_growvector (from lmem.h) which is a
158-- macro based on luaM_growaux (in lmem.c); all this function does is
159-- reproduce the size limit checking logic of the original function
160-- so that error behaviour is identical; all arguments preserved for
161-- convenience, even those which are unused
162-- * set the t field to nil, since this originally does a sizeof(t)
163-- * size (originally a pointer) is never updated, their final values
164-- are set by luaY:close_func(), so overall things should still work
165------------------------------------------------------------------------
166function luaY:growvector(L, v, nelems, size, t, limit, e)
167 local MINSIZEARRAY = 4 -- defined in lmem.c
168 -- still have at least MINSIZEARRAY free places
169 if nelems >= limit - MINSIZEARRAY then
170 luaX:syntaxerror(ls, e)
171 end
172end
173
174-- getlocvar(fs, i) has been placed with functions for locals, changed
175-- into a function
176
177------------------------------------------------------------------------
178-- tracks and limits parsing depth, assert check at end of parsing
179------------------------------------------------------------------------
180function luaY:enterlevel(ls)
181 ls.nestlevel = ls.nestlevel + 1
182 if ls.nestlevel > self.LUA_MAXPARSERLEVEL then
183 luaX:syntaxerror(ls, "too many syntax levels")
184 end
185end
186
187------------------------------------------------------------------------
188-- tracks parsing depth, a pair with luaY:enterlevel()
189------------------------------------------------------------------------
190function luaY:leavelevel(ls)
191 ls.nestlevel = ls.nestlevel - 1
192end
193
194------------------------------------------------------------------------
195-- nodes for block list (list of active blocks)
196------------------------------------------------------------------------
197--[[--------------------------------------------------------------------
198-- struct BlockCnt:
199-- previous -- chain (table: struct BlockCnt)
200-- breaklist -- list of jumps out of this loop
201-- nactvar -- # active local variables outside the breakable structure
202-- upval -- true if some variable in the block is an upvalue (boolean)
203-- isbreakable -- true if 'block' is a loop (boolean)
204----------------------------------------------------------------------]]
205
206------------------------------------------------------------------------
207-- prototypes for recursive non-terminal functions
208------------------------------------------------------------------------
209-- prototypes deleted; not required in Lua
210
211------------------------------------------------------------------------
212-- reads in next token
213-- * luaX:lex fills in ls.t.seminfo too, lookahead is handled
214------------------------------------------------------------------------
215function luaY:next(ls)
216 ls.lastline = ls.linenumber
217 if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token?
218 ls.t.token = ls.lookahead.token -- use this one
219 ls.t.seminfo = ls.lookahead.seminfo
220 ls.lookahead.token = "TK_EOS" -- and discharge it
221 else
222 ls.t.token = luaX:lex(ls, ls.t) -- read next token
223 end
224end
225
226------------------------------------------------------------------------
227-- peek at next token (single lookahead only)
228------------------------------------------------------------------------
229function luaY:lookahead(ls)
230 lua_assert(ls.lookahead.token == "TK_EOS")
231 ls.lookahead.token = luaX:lex(ls, ls.lookahead)
232end
233
234------------------------------------------------------------------------
235-- throws a syntax error if token expected is not there
236------------------------------------------------------------------------
237function luaY:error_expected(ls, token)
238 luaX:syntaxerror(ls,
239 string.format("`%s' expected", luaX:token2str(ls, token)))
240end
241
242------------------------------------------------------------------------
243-- tests for a token, returns outcome
244-- * return value changed to boolean
245------------------------------------------------------------------------
246function luaY:testnext(ls, c)
247 if ls.t.token == c then
248 self:next(ls)
249 return true
250 else
251 return false
252 end
253end
254
255------------------------------------------------------------------------
256-- check for existence of a token, throws error if not found
257------------------------------------------------------------------------
258function luaY:check(ls, c)
259 if not self:testnext(ls, c) then
260 self:error_expected(ls, c)
261 end
262end
263
264------------------------------------------------------------------------
265-- throws error if condition not matched
266------------------------------------------------------------------------
267function luaY:check_condition(ls, c, msg)
268 if not c then luaX:syntaxerror(ls, msg) end
269end
270
271------------------------------------------------------------------------
272-- verifies token conditions are met or else throw error
273------------------------------------------------------------------------
274function luaY:check_match(ls, what, who, where)
275 if not self:testnext(ls, what) then
276 if where == ls.linenumber then
277 self:error_expected(ls, what)
278 else
279 luaX:syntaxerror(ls, string.format(
280 "`%s' expected (to close `%s' at line %d)",
281 luaX:token2str(ls, what), luaX:token2str(ls, who), where))
282 end
283 end
284end
285
286------------------------------------------------------------------------
287-- expect that token is a name, return the name
288------------------------------------------------------------------------
289function luaY:str_checkname(ls)
290 self:check_condition(ls, ls.t.token == "TK_NAME", "<name> expected")
291 local ts = ls.t.seminfo
292 self:next(ls)
293 return ts
294end
295
296------------------------------------------------------------------------
297-- initialize a struct expdesc, expression description data structure
298------------------------------------------------------------------------
299function luaY:init_exp(e, k, i)
300 e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
301 e.k = k
302 e.info = i
303end
304
305------------------------------------------------------------------------
306-- adds given string s in string pool, sets e as VK
307------------------------------------------------------------------------
308function luaY:codestring(ls, e, s)
309 self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
310end
311
312------------------------------------------------------------------------
313-- consume a name token, adds it to string pool, sets e as VK
314------------------------------------------------------------------------
315function luaY:checkname(ls, e)
316 self:codestring(ls, e, self:str_checkname(ls))
317end
318
319------------------------------------------------------------------------
320-- returns local variable entry struct for a function
321------------------------------------------------------------------------
322function luaY:getlocvar(fs, i)
323 return fs.f.locvars[ fs.actvar[i] ]
324end
325
326------------------------------------------------------------------------
327-- creates struct entry for a local variable
328-- * used by new_localvar() only
329------------------------------------------------------------------------
330function luaY:registerlocalvar(ls, varname)
331 local fs = ls.fs
332 local f = fs.f
333 self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
334 nil, self.MAX_INT, "")
335 f.locvars[fs.nlocvars] = {} -- LocVar
336 f.locvars[fs.nlocvars].varname = varname
337 local nlocvars = fs.nlocvars
338 fs.nlocvars = fs.nlocvars + 1
339 return nlocvars
340end
341
342------------------------------------------------------------------------
343-- register a local variable, set in active variable list
344-- * used in new_localvarstr(), parlist(), fornum(), forlist(),
345-- localfunc(), localstat()
346------------------------------------------------------------------------
347function luaY:new_localvar(ls, name, n)
348 local fs = ls.fs
349 luaX:checklimit(ls, fs.nactvar + n + 1, self.MAXVARS, "local variables")
350 fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
351end
352
353------------------------------------------------------------------------
354-- adds nvars number of new local variables, set debug information
355-- * used in create_local(), code_params(), forbody(), localfunc(),
356-- localstat()
357------------------------------------------------------------------------
358function luaY:adjustlocalvars(ls, nvars)
359 local fs = ls.fs
360 fs.nactvar = fs.nactvar + nvars
361 for i = 1, nvars do
362 self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
363 end
364end
365
366------------------------------------------------------------------------
367-- removes a number of locals, set debug information
368-- * used in leaveblock(), close_func()
369------------------------------------------------------------------------
370function luaY:removevars(ls, tolevel)
371 local fs = ls.fs
372 while fs.nactvar > tolevel do
373 fs.nactvar = fs.nactvar - 1
374 self:getlocvar(fs, fs.nactvar).endpc = fs.pc
375 end
376end
377
378------------------------------------------------------------------------
379-- creates a new local variable given a name and an offset from nactvar
380-- * used in fornum(), forlist() for loop variables; in create_local()
381------------------------------------------------------------------------
382function luaY:new_localvarstr(ls, name, n)
383 self:new_localvar(ls, name, n)
384end
385
386------------------------------------------------------------------------
387-- creates a single local variable and activates it
388-- * used only in code_params() for "arg", body() for "self"
389------------------------------------------------------------------------
390function luaY:create_local(ls, name)
391 self:new_localvarstr(ls, name, 0)
392 self:adjustlocalvars(ls, 1)
393end
394
395------------------------------------------------------------------------
396-- returns an existing upvalue index based on the given name, or
397-- creates a new upvalue struct entry and returns the new index
398-- * used only in singlevaraux()
399------------------------------------------------------------------------
400function luaY:indexupvalue(fs, name, v)
401 local f = fs.f
402 for i = 0, f.nups - 1 do
403 if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
404 lua_assert(fs.f.upvalues[i] == name)
405 return i
406 end
407 end
408 -- new one
409 luaX:checklimit(fs.ls, f.nups + 1, self.MAXUPVALUES, "upvalues")
410 self:growvector(fs.L, fs.f.upvalues, f.nups, fs.f.sizeupvalues,
411 nil, self.MAX_INT, "")
412 fs.f.upvalues[f.nups] = name
413 -- this is a partial copy; only k & info fields used
414 fs.upvalues[f.nups] = { k = v.k, info = v.info }
415 local nups = f.nups
416 f.nups = f.nups + 1
417 return nups
418end
419
420------------------------------------------------------------------------
421-- search the local variable namespace of the given fs for a match
422-- * used only in singlevaraux()
423------------------------------------------------------------------------
424function luaY:searchvar(fs, n)
425 for i = fs.nactvar - 1, 0, -1 do
426 if n == self:getlocvar(fs, i).varname then
427 return i
428 end
429 end
430 return -1 -- not found
431end
432
433------------------------------------------------------------------------
434-- * mark upvalue flags in function states up to a given level
435-- * used only in singlevaraux()
436------------------------------------------------------------------------
437function luaY:markupval(fs, level)
438 local bl = fs.bl
439 while bl and bl.nactvar > level do bl = bl.previous end
440 if bl then bl.upval = true end
441end
442
443------------------------------------------------------------------------
444-- handle locals, globals and upvalues and related processing
445-- * search mechanism is recursive, calls itself to search parents
446-- * used only in singlevar()
447------------------------------------------------------------------------
448function luaY:singlevaraux(fs, n, var, base)
449 if fs == nil then -- no more levels?
450 self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
451 else
452 local v = self:searchvar(fs, n) -- look up at current level
453 if v >= 0 then
454 self:init_exp(var, "VLOCAL", v)
455 if base == 0 then
456 self:markupval(fs, v) -- local will be used as an upval
457 end
458 else -- not found at current level; try upper one
459 self:singlevaraux(fs.prev, n, var, 0)
460 if var.k == "VGLOBAL" then
461 if base ~= 0 then
462 var.info = luaK:stringK(fs, n) -- info points to global name
463 end
464 else -- LOCAL or UPVAL
465 var.info = self:indexupvalue(fs, n, var)
466 var.k = "VUPVAL" -- upvalue in this level
467 end
468 end--if v
469 end--if fs
470end
471
472------------------------------------------------------------------------
473-- consume a name token, creates a variable (global|local|upvalue)
474-- * used in prefixexp(), funcname()
475------------------------------------------------------------------------
476function luaY:singlevar(ls, var, base)
477 local varname = self:str_checkname(ls)
478 self:singlevaraux(ls.fs, varname, var, base)
479 return varname
480end
481
482------------------------------------------------------------------------
483-- adjust RHS to match LHS in an assignment
484-- * used in assignment(), forlist(), localstat()
485------------------------------------------------------------------------
486function luaY:adjust_assign(ls, nvars, nexps, e)
487 local fs = ls.fs
488 local extra = nvars - nexps
489 if e.k == "VCALL" then
490 extra = extra + 1 -- includes call itself
491 if extra <= 0 then extra = 0
492 else luaK:reserveregs(fs, extra - 1) end
493 luaK:setcallreturns(fs, e, extra) -- call provides the difference
494 else
495 if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression
496 if extra > 0 then
497 local reg = fs.freereg
498 luaK:reserveregs(fs, extra)
499 luaK:_nil(fs, reg, extra)
500 end
501 end
502end
503
504------------------------------------------------------------------------
505-- perform initialization for a parameter list, adds arg if needed
506-- * used only in parlist()
507------------------------------------------------------------------------
508function luaY:code_params(ls, nparams, dots)
509 local fs = ls.fs
510 self:adjustlocalvars(ls, nparams)
511 luaX:checklimit(ls, fs.nactvar, self.MAXPARAMS, "parameters")
512 fs.f.numparams = fs.nactvar
513 fs.f.is_vararg = dots and 1 or 0
514 if dots then
515 self:create_local(ls, "arg")
516 end
517 luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
518end
519
520------------------------------------------------------------------------
521-- enters a code unit, initializes elements
522------------------------------------------------------------------------
523function luaY:enterblock(fs, bl, isbreakable)
524 bl.breaklist = luaK.NO_JUMP
525 bl.isbreakable = isbreakable
526 bl.nactvar = fs.nactvar
527 bl.upval = false
528 bl.previous = fs.bl
529 fs.bl = bl
530 lua_assert(fs.freereg == fs.nactvar)
531end
532
533------------------------------------------------------------------------
534-- leaves a code unit, close any upvalues
535------------------------------------------------------------------------
536function luaY:leaveblock(fs)
537 local bl = fs.bl
538 fs.bl = bl.previous
539 self:removevars(fs.ls, bl.nactvar)
540 if bl.upval then
541 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
542 end
543 lua_assert(bl.nactvar == fs.nactvar)
544 fs.freereg = fs.nactvar -- free registers
545 luaK:patchtohere(fs, bl.breaklist)
546end
547
548------------------------------------------------------------------------
549-- implement the instantiation of a function prototype, append list of
550-- upvalues after the instantiation instruction
551-- * used only in body()
552------------------------------------------------------------------------
553function luaY:pushclosure(ls, func, v)
554 local fs = ls.fs
555 local f = fs.f
556 self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
557 luaP.MAXARG_Bx, "constant table overflow")
558 f.p[fs.np] = func.f
559 fs.np = fs.np + 1
560 self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
561 for i = 0, func.f.nups - 1 do
562 local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
563 luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
564 end
565end
566
567------------------------------------------------------------------------
568-- initialize a new function prototype structure
569------------------------------------------------------------------------
570function luaY:newproto(L)
571 local f = {} -- Proto
572 -- luaC_link deleted
573 f.k = {}
574 f.sizek = 0
575 f.p = {}
576 f.sizep = 0
577 f.code = {}
578 f.sizecode = 0
579 f.sizelineinfo = 0
580 f.sizeupvalues = 0
581 f.nups = 0
582 f.upvalues = {}
583 f.numparams = 0
584 f.is_vararg = 0
585 f.maxstacksize = 0
586 f.lineinfo = {}
587 f.sizelocvars = 0
588 f.locvars = {}
589 f.lineDefined = 0
590 f.source = nil
591 return f
592end
593
594------------------------------------------------------------------------
595-- opening of a function
596------------------------------------------------------------------------
597function luaY:open_func(ls, fs)
598 local f = self:newproto(ls.L)
599 fs.f = f
600 fs.prev = ls.fs -- linked list of funcstates
601 fs.ls = ls
602 fs.L = ls.L
603 ls.fs = fs
604 fs.pc = 0
605 fs.lasttarget = 0
606 fs.jpc = luaK.NO_JUMP
607 fs.freereg = 0
608 fs.nk = 0
609 fs.h = {} -- constant table; was luaH_new call
610 fs.np = 0
611 fs.nlocvars = 0
612 fs.nactvar = 0
613 fs.bl = nil
614 f.source = ls.source
615 f.maxstacksize = 2 -- registers 0/1 are always valid
616end
617
618------------------------------------------------------------------------
619-- closing of a function
620------------------------------------------------------------------------
621function luaY:close_func(ls)
622 local L = ls.L
623 local fs = ls.fs
624 local f = fs.f
625 self:removevars(ls, 0)
626 luaK:codeABC(fs, "OP_RETURN", 0, 1, 0) -- final return
627 -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
628 -- f->locvars, f->upvalues; not required for Lua table arrays
629 f.sizecode = fs.pc
630 f.sizelineinfo = fs.pc
631 f.sizek = fs.nk
632 f.sizep = fs.np
633 f.sizelocvars = fs.nlocvars
634 f.sizeupvalues = f.nups
635 --lua_assert(luaG_checkcode(f)) -- currently not implemented
636 lua_assert(fs.bl == nil)
637 ls.fs = fs.prev
638end
639
640------------------------------------------------------------------------
641-- parser initialization function
642-- * note additional sub-tables needed for LexState, FuncState
643------------------------------------------------------------------------
644function luaY:parser(L, z, buff)
645 local lexstate = {} -- LexState
646 lexstate.t = {}
647 lexstate.lookahead = {}
648 local funcstate = {} -- FuncState
649 funcstate.upvalues = {}
650 funcstate.actvar = {}
651 lexstate.buff = buff
652 lexstate.nestlevel = 0
653 luaX:setinput(L, lexstate, z, z.name)
654 self:open_func(lexstate, funcstate)
655 self:next(lexstate) -- read first token
656 self:chunk(lexstate)
657 self:check_condition(lexstate, lexstate.t.token == "TK_EOS", "<eof> expected")
658 self:close_func(lexstate)
659 lua_assert(funcstate.prev == nil)
660 lua_assert(funcstate.f.nups == 0)
661 lua_assert(lexstate.nestlevel == 0)
662 return funcstate.f
663end
664
665--[[--------------------------------------------------------------------
666-- GRAMMAR RULES
667----------------------------------------------------------------------]]
668
669------------------------------------------------------------------------
670-- parse a function name suffix, for function call specifications
671-- * used in primaryexp(), funcname()
672------------------------------------------------------------------------
673function luaY:field(ls, v)
674 -- field -> ['.' | ':'] NAME
675 local fs = ls.fs
676 local key = {} -- expdesc
677 luaK:exp2anyreg(fs, v)
678 self:next(ls) -- skip the dot or colon
679 self:checkname(ls, key)
680 luaK:indexed(fs, v, key)
681end
682
683------------------------------------------------------------------------
684-- parse a table indexing suffix, for constructors, expressions
685-- * used in recfield(), primaryexp()
686------------------------------------------------------------------------
687function luaY:index(ls, v)
688 -- index -> '[' expr ']'
689 self:next(ls) -- skip the '['
690 self:expr(ls, v)
691 luaK:exp2val(ls.fs, v)
692 self:check(ls, "]")
693end
694
695--[[--------------------------------------------------------------------
696-- Rules for Constructors
697----------------------------------------------------------------------]]
698
699--[[--------------------------------------------------------------------
700-- struct ConsControl:
701-- v -- last list item read (table: struct expdesc)
702-- t -- table descriptor (table: struct expdesc)
703-- nh -- total number of 'record' elements
704-- na -- total number of array elements
705-- tostore -- number of array elements pending to be stored
706----------------------------------------------------------------------]]
707
708------------------------------------------------------------------------
709-- parse a table record (hash) field
710-- * used in constructor()
711------------------------------------------------------------------------
712function luaY:recfield(ls, cc)
713 -- recfield -> (NAME | '['exp1']') = exp1
714 local fs = ls.fs
715 local reg = ls.fs.freereg
716 local key, val = {}, {} -- expdesc
717 if ls.t.token == "TK_NAME" then
718 luaX:checklimit(ls, cc.nh, self.MAX_INT, "items in a constructor")
719 cc.nh = cc.nh + 1
720 self:checkname(ls, key)
721 else -- ls->t.token == '['
722 self:index(ls, key)
723 end
724 self:check(ls, "=")
725 luaK:exp2RK(fs, key)
726 self:expr(ls, val)
727 luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, luaK:exp2RK(fs, key),
728 luaK:exp2RK(fs, val))
729 fs.freereg = reg -- free registers
730end
731
732------------------------------------------------------------------------
733-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
734-- * used in constructor()
735------------------------------------------------------------------------
736function luaY:closelistfield(fs, cc)
737 if cc.v.k == "VVOID" then return end -- there is no list item
738 luaK:exp2nextreg(fs, cc.v)
739 cc.v.k = "VVOID"
740 if cc.tostore == luaP.LFIELDS_PER_FLUSH then
741 luaK:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1) -- flush
742 cc.tostore = 0 -- no more items pending
743 fs.freereg = cc.t.info + 1 -- free registers
744 end
745end
746
747------------------------------------------------------------------------
748-- emit a set list instruction at the end of parsing list constructor
749-- * used in constructor()
750------------------------------------------------------------------------
751function luaY:lastlistfield(fs, cc)
752 if cc.tostore == 0 then return end
753 if cc.v.k == "VCALL" then
754 luaK:setcallreturns(fs, cc.v, self.LUA_MULTRET)
755 luaK:codeABx(fs, "OP_SETLISTO", cc.t.info, cc.na - 1)
756 else
757 if cc.v.k ~= "VVOID" then
758 luaK:exp2nextreg(fs, cc.v)
759 end
760 luaK:codeABx(fs, "OP_SETLIST", cc.t.info, cc.na - 1)
761 end
762 fs.freereg = cc.t.info + 1 -- free registers
763end
764
765------------------------------------------------------------------------
766-- parse a table list (array) field
767-- * used in constructor()
768------------------------------------------------------------------------
769function luaY:listfield(ls, cc)
770 self:expr(ls, cc.v)
771 luaX:checklimit(ls, cc.na, luaP.MAXARG_Bx, "items in a constructor")
772 cc.na = cc.na + 1
773 cc.tostore = cc.tostore + 1
774end
775
776------------------------------------------------------------------------
777-- parse a table constructor
778-- * used in funcargs(), simpleexp()
779------------------------------------------------------------------------
780function luaY:constructor(ls, t)
781 -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
782 -- field -> recfield | listfield
783 -- fieldsep -> ',' | ';'
784 local fs = ls.fs
785 local line = ls.linenumber
786 local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
787 local cc = {} -- ConsControl
788 cc.v = {}
789 cc.na, cc.nh, cc.tostore = 0, 0, 0
790 cc.t = t
791 self:init_exp(t, "VRELOCABLE", pc)
792 self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
793 luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
794 self:check(ls, "{")
795 repeat
796 lua_assert(cc.v.k == "VVOID" or cc.tostore > 0)
797 self:testnext(ls, ";") -- compatibility only
798 if ls.t.token == "}" then break end
799 self:closelistfield(fs, cc)
800 local c = ls.t.token
801 if c == "TK_NAME" then -- may be listfields or recfields
802 self:lookahead(ls)
803 if ls.lookahead.token ~= "=" then -- expression?
804 self:listfield(ls, cc)
805 else
806 self:recfield(ls, cc)
807 end
808 elseif c == "[" then -- constructor_item -> recfield
809 self:recfield(ls, cc)
810 else -- constructor_part -> listfield
811 self:listfield(ls, cc)
812 end
813 until not self:testnext(ls, ",") and not self:testnext(ls, ";")
814 self:check_match(ls, "}", "{", line)
815 self:lastlistfield(fs, cc)
816 luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
817 luaP:SETARG_C(fs.f.code[pc], self:log2(cc.nh) + 1) -- set initial table size
818end
819
820------------------------------------------------------------------------
821-- parse the arguments (parameters) of a function declaration
822-- * used in body()
823------------------------------------------------------------------------
824function luaY:parlist(ls)
825 -- parlist -> [ param { ',' param } ]
826 local nparams = 0
827 local dots = false
828 if ls.t.token ~= ")" then -- is 'parlist' not empty?
829 repeat
830 local c = ls.t.token
831 if c == "TK_DOTS" then
832 dots = true
833 self:next(ls)
834 elseif c == "TK_NAME" then
835 self:new_localvar(ls, self:str_checkname(ls), nparams)
836 nparams = nparams + 1
837 else
838 luaX:syntaxerror(ls, "<name> or `...' expected")
839 end
840 until dots or not self:testnext(ls, ",")
841 end
842 self:code_params(ls, nparams, dots)
843end
844
845------------------------------------------------------------------------
846-- parse function declaration body
847-- * used in simpleexp(), localfunc(), funcstat()
848------------------------------------------------------------------------
849function luaY:body(ls, e, needself, line)
850 -- body -> '(' parlist ')' chunk END
851 local new_fs = {} -- FuncState
852 new_fs.upvalues = {}
853 new_fs.actvar = {}
854 self:open_func(ls, new_fs)
855 new_fs.f.lineDefined = line
856 self:check(ls, "(")
857 if needself then
858 self:create_local(ls, "self")
859 end
860 self:parlist(ls)
861 self:check(ls, ")")
862 self:chunk(ls)
863 self:check_match(ls, "TK_END", "TK_FUNCTION", line)
864 self:close_func(ls)
865 self:pushclosure(ls, new_fs, e)
866end
867
868------------------------------------------------------------------------
869-- parse a list of comma-separated expressions
870-- * used is multiple locations
871------------------------------------------------------------------------
872function luaY:explist1(ls, v)
873 -- explist1 -> expr { ',' expr }
874 local n = 1 -- at least one expression
875 self:expr(ls, v)
876 while self:testnext(ls, ",") do
877 luaK:exp2nextreg(ls.fs, v)
878 self:expr(ls, v)
879 n = n + 1
880 end
881 return n
882end
883
884------------------------------------------------------------------------
885-- parse the parameters of a function call
886-- * contrast with parlist(), used in function declarations
887-- * used in primaryexp()
888------------------------------------------------------------------------
889function luaY:funcargs(ls, f)
890 local fs = ls.fs
891 local args = {} -- expdesc
892 local nparams
893 local line = ls.linenumber
894 local c = ls.t.token
895 if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
896 if line ~= ls.lastline then
897 luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
898 end
899 self:next(ls)
900 if ls.t.token == ")" then -- arg list is empty?
901 args.k = "VVOID"
902 else
903 self:explist1(ls, args)
904 luaK:setcallreturns(fs, args, self.LUA_MULTRET)
905 end
906 self:check_match(ls, ")", "(", line)
907 elseif c == "{" then -- funcargs -> constructor
908 self:constructor(ls, args)
909 elseif c == "TK_STRING" then -- funcargs -> STRING
910 self:codestring(ls, args, ls.t.seminfo)
911 self:next(ls) -- must use 'seminfo' before 'next'
912 else
913 luaX:syntaxerror(ls, "function arguments expected")
914 return
915 end
916 lua_assert(f.k == "VNONRELOC")
917 local base = f.info -- base register for call
918 if args.k == "VCALL" then
919 nparams = self.LUA_MULTRET -- open call
920 else
921 if args.k ~= "VVOID" then
922 luaK:exp2nextreg(fs, args) -- close last argument
923 end
924 nparams = fs.freereg - (base + 1)
925 end
926 self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
927 luaK:fixline(fs, line)
928 fs.freereg = base + 1 -- call remove function and arguments and leaves
929 -- (unless changed) one result
930end
931
932--[[--------------------------------------------------------------------
933-- Expression parsing
934----------------------------------------------------------------------]]
935
936------------------------------------------------------------------------
937-- parses an expression in parentheses or a single variable
938-- * used in primaryexp()
939------------------------------------------------------------------------
940function luaY:prefixexp(ls, v)
941 -- prefixexp -> NAME | '(' expr ')'
942 local c = ls.t.token
943 if c == "(" then
944 local line = ls.linenumber
945 self:next(ls)
946 self:expr(ls, v)
947 self:check_match(ls, ")", "(", line)
948 luaK:dischargevars(ls.fs, v)
949 elseif c == "TK_NAME" then
950 self:singlevar(ls, v, 1)
951 -- LUA_COMPATUPSYNTAX
952--[[
953 elseif c == "%" then -- for compatibility only
954 local line = ls.linenumber
955 self:next(ls) -- skip '%'
956 local varname = self:singlevar(ls, v, 1)
957 if v.k ~= "VUPVAL" then
958 luaX:errorline(ls, "global upvalues are obsolete", varname, line)
959 end
960--]]
961 else
962 luaX:syntaxerror(ls, "unexpected symbol")
963 end--if c
964 return
965end
966
967------------------------------------------------------------------------
968-- parses a prefixexp (an expression in parentheses or a single variable)
969-- or a function call specification
970-- * used in simpleexp(), assignment(), exprstat()
971------------------------------------------------------------------------
972function luaY:primaryexp(ls, v)
973 -- primaryexp ->
974 -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
975 local fs = ls.fs
976 self:prefixexp(ls, v)
977 while true do
978 local c = ls.t.token
979 if c == "." then -- field
980 self:field(ls, v)
981 elseif c == "[" then -- '[' exp1 ']'
982 local key = {} -- expdesc
983 luaK:exp2anyreg(fs, v)
984 self:index(ls, key)
985 luaK:indexed(fs, v, key)
986 elseif c == ":" then -- ':' NAME funcargs
987 local key = {} -- expdesc
988 self:next(ls)
989 self:checkname(ls, key)
990 luaK:_self(fs, v, key)
991 self:funcargs(ls, v)
992 elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
993 luaK:exp2nextreg(fs, v)
994 self:funcargs(ls, v)
995 else
996 return
997 end--if c
998 end--while
999end
1000
1001------------------------------------------------------------------------
1002-- parses general expression types, constants handled here
1003-- * used in subexpr()
1004------------------------------------------------------------------------
1005function luaY:simpleexp(ls, v)
1006 -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor
1007 -- | FUNCTION body | primaryexp
1008 local c = ls.t.token
1009 if c == "TK_NUMBER" then
1010 self:init_exp(v, "VK", luaK:numberK(ls.fs, ls.t.seminfo))
1011 self:next(ls) -- must use 'seminfo' before 'next'
1012 elseif c == "TK_STRING" then
1013 self:codestring(ls, v, ls.t.seminfo)
1014 self:next(ls) -- must use 'seminfo' before 'next'
1015 elseif c == "TK_NIL" then
1016 self:init_exp(v, "VNIL", 0)
1017 self:next(ls)
1018 elseif c == "TK_TRUE" then
1019 self:init_exp(v, "VTRUE", 0)
1020 self:next(ls)
1021 elseif c == "TK_FALSE" then
1022 self:init_exp(v, "VFALSE", 0)
1023 self:next(ls)
1024 elseif c == "{" then -- constructor
1025 self:constructor(ls, v)
1026 elseif c == "TK_FUNCTION" then
1027 self:next(ls)
1028 self:body(ls, v, false, ls.linenumber)
1029 else
1030 self:primaryexp(ls, v)
1031 end--if c
1032end
1033
1034------------------------------------------------------------------------
1035-- Translates unary operators tokens if found, otherwise returns
1036-- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
1037-- * used in subexpr()
1038------------------------------------------------------------------------
1039function luaY:getunopr(op)
1040 if op == "TK_NOT" then
1041 return "OPR_NOT"
1042 elseif op == "-" then
1043 return "OPR_MINUS"
1044 else
1045 return "OPR_NOUNOPR"
1046 end
1047end
1048
1049------------------------------------------------------------------------
1050-- Translates binary operator tokens if found, otherwise returns
1051-- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
1052-- * used in subexpr()
1053------------------------------------------------------------------------
1054luaY.getbinopr_table = {
1055 ["+"] = "OPR_ADD",
1056 ["-"] = "OPR_SUB",
1057 ["*"] = "OPR_MULT",
1058 ["/"] = "OPR_DIV",
1059 ["^"] = "OPR_POW",
1060 ["TK_CONCAT"] = "OPR_CONCAT",
1061 ["TK_NE"] = "OPR_NE",
1062 ["TK_EQ"] = "OPR_EQ",
1063 ["<"] = "OPR_LT",
1064 ["TK_LE"] = "OPR_LE",
1065 [">"] = "OPR_GT",
1066 ["TK_GE"] = "OPR_GE",
1067 ["TK_AND"] = "OPR_AND",
1068 ["TK_OR"] = "OPR_OR",
1069}
1070function luaY:getbinopr(op)
1071 local opr = self.getbinopr_table[op]
1072 if opr then return opr else return "OPR_NOBINOPR" end
1073end
1074
1075------------------------------------------------------------------------
1076-- the following priority table consists of pairs of left/right values
1077-- for binary operators (was a static const struct); grep for ORDER OPR
1078------------------------------------------------------------------------
1079luaY.priority = {
1080 {6, 6}, {6, 6}, {7, 7}, {7, 7}, -- arithmetic
1081 {10, 9}, {5, 4}, -- power and concat (right associative)
1082 {3, 3}, {3, 3}, -- equality
1083 {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order
1084 {2, 2}, {1, 1} -- logical (and/or)
1085}
1086
1087luaY.UNARY_PRIORITY = 8 -- priority for unary operators
1088
1089------------------------------------------------------------------------
1090-- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1091-- where 'binop' is any binary operator with a priority higher than 'limit'
1092------------------------------------------------------------------------
1093
1094------------------------------------------------------------------------
1095-- * for priority lookups with self.priority[], 1=left and 2=right
1096--
1097-- Parse subexpressions. Includes handling of unary operators and binary
1098-- operators. A subexpr is given the rhs priority level of the operator
1099-- immediately left of it, if any (limit is -1 if none,) and if a binop
1100-- is found, limit is compared with the lhs priority level of the binop
1101-- in order to determine which executes first.
1102--
1103-- * recursively called
1104-- * used in expr()
1105------------------------------------------------------------------------
1106function luaY:subexpr(ls, v, limit)
1107 self:enterlevel(ls)
1108 local uop = self:getunopr(ls.t.token)
1109 if uop ~= "OPR_NOUNOPR" then
1110 self:next(ls)
1111 self:subexpr(ls, v, self.UNARY_PRIORITY)
1112 luaK:prefix(ls.fs, uop, v)
1113 else
1114 self:simpleexp(ls, v)
1115 end
1116 -- expand while operators have priorities higher than 'limit'
1117 local op = self:getbinopr(ls.t.token)
1118 while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
1119 local v2 = {} -- expdesc
1120 self:next(ls)
1121 luaK:infix(ls.fs, op, v)
1122 -- read sub-expression with higher priority
1123 local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
1124 luaK:posfix(ls.fs, op, v, v2)
1125 op = nextop
1126 end
1127 self:leavelevel(ls)
1128 return op -- return first untreated operator
1129end
1130
1131------------------------------------------------------------------------
1132-- Expression parsing starts here. Function subexpr is entered with the
1133-- left operator (which is non-existent) priority of -1, which is lower
1134-- than all actual operators. Expr information is returned in parm v.
1135-- * used in multiple locations
1136------------------------------------------------------------------------
1137function luaY:expr(ls, v)
1138 self:subexpr(ls, v, -1)
1139end
1140
1141--[[--------------------------------------------------------------------
1142-- Rules for Statements
1143----------------------------------------------------------------------]]
1144
1145------------------------------------------------------------------------
1146-- checks next token, used as a look-ahead
1147-- * returns boolean instead of 0|1
1148-- * used in retstat(), chunk()
1149------------------------------------------------------------------------
1150function luaY:block_follow(token)
1151 if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
1152 or token == "TK_UNTIL" or token == "TK_EOS" then
1153 return true
1154 else
1155 return false
1156 end
1157end
1158
1159------------------------------------------------------------------------
1160-- parse a code block or unit
1161-- * used in multiple functions
1162------------------------------------------------------------------------
1163function luaY:block(ls)
1164 -- block -> chunk
1165 local fs = ls.fs
1166 local bl = {} -- BlockCnt
1167 self:enterblock(fs, bl, false)
1168 self:chunk(ls)
1169 lua_assert(bl.breaklist == luaK.NO_JUMP)
1170 self:leaveblock(fs)
1171end
1172
1173------------------------------------------------------------------------
1174-- structure to chain all variables in the left-hand side of an
1175-- assignment
1176------------------------------------------------------------------------
1177--[[--------------------------------------------------------------------
1178-- struct LHS_assign:
1179-- prev -- (table: struct LHS_assign)
1180-- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
1181----------------------------------------------------------------------]]
1182
1183------------------------------------------------------------------------
1184-- check whether, in an assignment to a local variable, the local variable
1185-- is needed in a previous assignment (to a table). If so, save original
1186-- local value in a safe place and use this safe copy in the previous
1187-- assignment.
1188-- * used in assignment()
1189------------------------------------------------------------------------
1190function luaY:check_conflict(ls, lh, v)
1191 local fs = ls.fs
1192 local extra = fs.freereg -- eventual position to save local variable
1193 local conflict = false
1194 while lh do
1195 if lh.v.k == "VINDEXED" then
1196 if lh.v.info == v.info then -- conflict?
1197 conflict = true
1198 lh.v.info = extra -- previous assignment will use safe copy
1199 end
1200 if lh.v.aux == v.info then -- conflict?
1201 conflict = true
1202 lh.v.aux = extra -- previous assignment will use safe copy
1203 end
1204 end
1205 lh = lh.prev
1206 end
1207 if conflict then
1208 luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
1209 luaK:reserveregs(fs, 1)
1210 end
1211end
1212
1213------------------------------------------------------------------------
1214-- parse a variable assignment sequence
1215-- * recursively called
1216-- * used in exprstat()
1217------------------------------------------------------------------------
1218function luaY:assignment(ls, lh, nvars)
1219 local e = {} -- expdesc
1220 -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
1221 local c = lh.v.k
1222 self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
1223 or c == "VINDEXED", "syntax error")
1224 if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
1225 local nv = {} -- LHS_assign
1226 nv.v = {}
1227 nv.prev = lh
1228 self:primaryexp(ls, nv.v)
1229 if nv.v.k == "VLOCAL" then
1230 self:check_conflict(ls, lh, nv.v)
1231 end
1232 self:assignment(ls, nv, nvars + 1)
1233 else -- assignment -> '=' explist1
1234 self:check(ls, "=")
1235 local nexps = self:explist1(ls, e)
1236 if nexps ~= nvars then
1237 self:adjust_assign(ls, nvars, nexps, e)
1238 if nexps > nvars then
1239 ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
1240 end
1241 else
1242 luaK:setcallreturns(ls.fs, e, 1) -- close last expression
1243 luaK:storevar(ls.fs, lh.v, e)
1244 return -- avoid default
1245 end
1246 end
1247 self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
1248 luaK:storevar(ls.fs, lh.v, e)
1249end
1250
1251------------------------------------------------------------------------
1252-- parse condition in a repeat statement or an if control structure
1253-- * used in repeatstat(), test_then_block()
1254------------------------------------------------------------------------
1255function luaY:cond(ls, v)
1256 -- cond -> exp
1257 self:expr(ls, v) -- read condition
1258 if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here
1259 luaK:goiftrue(ls.fs, v)
1260 luaK:patchtohere(ls.fs, v.t)
1261end
1262
1263------------------------------------------------------------------------
1264-- The while statement optimizes its code by coding the condition
1265-- after its body (and thus avoiding one jump in the loop).
1266------------------------------------------------------------------------
1267
1268------------------------------------------------------------------------
1269-- maximum size of expressions for optimizing 'while' code
1270------------------------------------------------------------------------
1271if not luaY.MAXEXPWHILE then
1272 luaY.MAXEXPWHILE = 100
1273end
1274
1275------------------------------------------------------------------------
1276-- the call 'luaK_goiffalse' may grow the size of an expression by
1277-- at most this:
1278------------------------------------------------------------------------
1279luaY.EXTRAEXP = 5
1280
1281------------------------------------------------------------------------
1282-- parse a while-do control structure, body processed by block()
1283-- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
1284-- the function's implementation can be removed
1285-- * used in statements()
1286------------------------------------------------------------------------
1287function luaY:whilestat(ls, line)
1288 -- whilestat -> WHILE cond DO block END
1289 -- array size of [MAXEXPWHILE + EXTRAEXP] no longer required
1290 local codeexp = {} -- Instruction
1291 local fs = ls.fs
1292 local v = {} -- expdesc
1293 local bl = {} -- BlockCnt
1294 self:next(ls) -- skip WHILE
1295 local whileinit = luaK:jump(fs) -- jump to condition (which will be moved)
1296 local expinit = luaK:getlabel(fs)
1297 self:expr(ls, v) -- parse condition
1298 if v.k == "VK" then v.k = "VTRUE" end -- 'trues' are all equal here
1299 local lineexp = ls.linenumber
1300 luaK:goiffalse(fs, v)
1301 v.f = luaK:concat(fs, v.f, fs.jpc)
1302 fs.jpc = luaK.NO_JUMP
1303 local sizeexp = fs.pc - expinit -- size of expression code
1304 if sizeexp > self.MAXEXPWHILE then
1305 luaX:syntaxerror(ls, "`while' condition too complex")
1306 end
1307 for i = 0, sizeexp - 1 do -- save 'exp' code
1308 codeexp[i] = fs.f.code[expinit + i]
1309 end
1310 fs.pc = expinit -- remove 'exp' code
1311 self:enterblock(fs, bl, true)
1312 self:check(ls, "TK_DO")
1313 local blockinit = luaK:getlabel(fs)
1314 self:block(ls)
1315 luaK:patchtohere(fs, whileinit) -- initial jump jumps to here
1316 -- move 'exp' back to code
1317 if v.t ~= luaK.NO_JUMP then v.t = v.t + fs.pc - expinit end
1318 if v.f ~= luaK.NO_JUMP then v.f = v.f + fs.pc - expinit end
1319 for i = 0, sizeexp - 1 do
1320 luaK:code(fs, codeexp[i], lineexp)
1321 end
1322 self:check_match(ls, "TK_END", "TK_WHILE", line)
1323 self:leaveblock(fs)
1324 luaK:patchlist(fs, v.t, blockinit) -- true conditions go back to loop
1325 luaK:patchtohere(fs, v.f) -- false conditions finish the loop
1326end
1327
1328------------------------------------------------------------------------
1329-- parse a repeat-until control structure, body parsed by block()
1330-- * used in statements()
1331------------------------------------------------------------------------
1332function luaY:repeatstat(ls, line)
1333 -- repeatstat -> REPEAT block UNTIL cond
1334 local fs = ls.fs
1335 local repeat_init = luaK:getlabel(fs)
1336 local v = {} -- expdesc
1337 local bl = {} -- BlockCnt
1338 self:enterblock(fs, bl, true)
1339 self:next(ls)
1340 self:block(ls)
1341 self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
1342 self:cond(ls, v)
1343 luaK:patchlist(fs, v.f, repeat_init)
1344 self:leaveblock(fs)
1345end
1346
1347------------------------------------------------------------------------
1348-- parse the single expressions needed in numerical for loops
1349-- * used in fornum()
1350------------------------------------------------------------------------
1351function luaY:exp1(ls)
1352 local e = {} -- expdesc
1353 self:expr(ls, e)
1354 local k = e.k
1355 luaK:exp2nextreg(ls.fs, e)
1356 return k
1357end
1358
1359------------------------------------------------------------------------
1360-- parse a for loop body for both versions of the for loop
1361-- * used in fornum(), forlist()
1362------------------------------------------------------------------------
1363function luaY:forbody(ls, base, line, nvars, isnum)
1364 local bl = {} -- BlockCnt
1365 local fs = ls.fs
1366 self:adjustlocalvars(ls, nvars) -- scope for all variables
1367 self:check(ls, "TK_DO")
1368 self:enterblock(fs, bl, true) -- loop block
1369 local prep = luaK:getlabel(fs)
1370 self:block(ls)
1371 luaK:patchtohere(fs, prep - 1)
1372 local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
1373 or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars - 3)
1374 luaK:fixline(fs, line) -- pretend that 'OP_FOR' starts the loop
1375 luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep)
1376 self:leaveblock(fs)
1377end
1378
1379------------------------------------------------------------------------
1380-- parse a numerical for loop, calls forbody()
1381-- * used in forstat()
1382------------------------------------------------------------------------
1383function luaY:fornum(ls, varname, line)
1384 -- fornum -> NAME = exp1,exp1[,exp1] DO body
1385 local fs = ls.fs
1386 local base = fs.freereg
1387 self:new_localvar(ls, varname, 0)
1388 self:new_localvarstr(ls, "(for limit)", 1)
1389 self:new_localvarstr(ls, "(for step)", 2)
1390 self:check(ls, "=")
1391 self:exp1(ls) -- initial value
1392 self:check(ls, ",")
1393 self:exp1(ls) -- limit
1394 if self:testnext(ls, ",") then
1395 self:exp1(ls) -- optional step
1396 else -- default step = 1
1397 luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
1398 luaK:reserveregs(fs, 1)
1399 end
1400 luaK:codeABC(fs, "OP_SUB", fs.freereg - 3, fs.freereg - 3, fs.freereg - 1)
1401 luaK:jump(fs)
1402 self:forbody(ls, base, line, 3, true)
1403end
1404
1405------------------------------------------------------------------------
1406-- parse a generic for loop, calls forbody()
1407-- * used in forstat()
1408------------------------------------------------------------------------
1409function luaY:forlist(ls, indexname)
1410 -- forlist -> NAME {,NAME} IN explist1 DO body
1411 local fs = ls.fs
1412 local e = {} -- expdesc
1413 local nvars = 0
1414 local base = fs.freereg
1415 self:new_localvarstr(ls, "(for generator)", nvars)
1416 nvars = nvars + 1
1417 self:new_localvarstr(ls, "(for state)", nvars)
1418 nvars = nvars + 1
1419 self:new_localvar(ls, indexname, nvars)
1420 nvars = nvars + 1
1421 while self:testnext(ls, ",") do
1422 self:new_localvar(ls, self:str_checkname(ls), nvars)
1423 nvars = nvars + 1
1424 end
1425 self:check(ls, "TK_IN")
1426 local line = ls.linenumber
1427 self:adjust_assign(ls, nvars, self:explist1(ls, e), e)
1428 luaK:checkstack(fs, 3) -- extra space to call generator
1429 luaK:codeAsBx(fs, "OP_TFORPREP", base, luaK.NO_JUMP)
1430 self:forbody(ls, base, line, nvars, false)
1431end
1432
1433------------------------------------------------------------------------
1434-- initial parsing for a for loop, calls fornum() or forlist()
1435-- * used in statements()
1436------------------------------------------------------------------------
1437function luaY:forstat(ls, line)
1438 -- forstat -> fornum | forlist
1439 local fs = ls.fs
1440 local bl = {} -- BlockCnt
1441 self:enterblock(fs, bl, false) -- block to control variable scope
1442 self:next(ls) -- skip 'for'
1443 local varname = self:str_checkname(ls) -- first variable name
1444 local c = ls.t.token
1445 if c == "=" then
1446 self:fornum(ls, varname, line)
1447 elseif c == "," or c == "TK_IN" then
1448 self:forlist(ls, varname)
1449 else
1450 luaX:syntaxerror(ls, "`=' or `in' expected")
1451 end
1452 self:check_match(ls, "TK_END", "TK_FOR", line)
1453 self:leaveblock(fs)
1454end
1455
1456------------------------------------------------------------------------
1457-- parse part of an if control structure, including the condition
1458-- * used in ifstat()
1459------------------------------------------------------------------------
1460function luaY:test_then_block(ls, v)
1461 -- test_then_block -> [IF | ELSEIF] cond THEN block
1462 self:next(ls) -- skip IF or ELSEIF
1463 self:cond(ls, v)
1464 self:check(ls, "TK_THEN")
1465 self:block(ls) -- 'then' part
1466end
1467
1468------------------------------------------------------------------------
1469-- parse an if control structure
1470-- * used in statements()
1471------------------------------------------------------------------------
1472function luaY:ifstat(ls, line)
1473 -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
1474 local fs = ls.fs
1475 local v = {} -- expdesc
1476 local escapelist = luaK.NO_JUMP
1477 self:test_then_block(ls, v) -- IF cond THEN block
1478 while ls.t.token == "TK_ELSEIF" do
1479 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1480 luaK:patchtohere(fs, v.f)
1481 self:test_then_block(ls, v) -- ELSEIF cond THEN block
1482 end
1483 if ls.t.token == "TK_ELSE" then
1484 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1485 luaK:patchtohere(fs, v.f)
1486 self:next(ls) -- skip ELSE (after patch, for correct line info)
1487 self:block(ls) -- 'else' part
1488 else
1489 escapelist = luaK:concat(fs, escapelist, v.f)
1490 end
1491 luaK:patchtohere(fs, escapelist)
1492 self:check_match(ls, "TK_END", "TK_IF", line)
1493end
1494
1495------------------------------------------------------------------------
1496-- parse a local function statement
1497-- * used in statements()
1498------------------------------------------------------------------------
1499function luaY:localfunc(ls)
1500 local v, b = {}, {} -- expdesc
1501 local fs = ls.fs
1502 self:new_localvar(ls, self:str_checkname(ls), 0)
1503 self:init_exp(v, "VLOCAL", fs.freereg)
1504 luaK:reserveregs(fs, 1)
1505 self:adjustlocalvars(ls, 1)
1506 self:body(ls, b, false, ls.linenumber)
1507 luaK:storevar(fs, v, b)
1508 -- debug information will only see the variable after this point!
1509 self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
1510end
1511
1512------------------------------------------------------------------------
1513-- parse a local variable declaration statement
1514-- * used in statements()
1515------------------------------------------------------------------------
1516function luaY:localstat(ls)
1517 -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
1518 local nvars = 0
1519 local nexps
1520 local e = {} -- expdesc
1521 repeat
1522 self:new_localvar(ls, self:str_checkname(ls), nvars)
1523 nvars = nvars + 1
1524 until not self:testnext(ls, ",")
1525 if self:testnext(ls, "=") then
1526 nexps = self:explist1(ls, e)
1527 else
1528 e.k = "VVOID"
1529 nexps = 0
1530 end
1531 self:adjust_assign(ls, nvars, nexps, e)
1532 self:adjustlocalvars(ls, nvars)
1533end
1534
1535------------------------------------------------------------------------
1536-- parse a function name specification
1537-- * used in funcstat()
1538------------------------------------------------------------------------
1539function luaY:funcname(ls, v)
1540 -- funcname -> NAME {field} [':' NAME]
1541 local needself = false
1542 self:singlevar(ls, v, 1)
1543 while ls.t.token == "." do
1544 self:field(ls, v)
1545 end
1546 if ls.t.token == ":" then
1547 needself = true
1548 self:field(ls, v)
1549 end
1550 return needself
1551end
1552
1553------------------------------------------------------------------------
1554-- parse a function statement
1555-- * used in statements()
1556------------------------------------------------------------------------
1557function luaY:funcstat(ls, line)
1558 -- funcstat -> FUNCTION funcname body
1559 local v, b = {}, {} -- expdesc
1560 self:next(ls) -- skip FUNCTION
1561 local needself = self:funcname(ls, v)
1562 self:body(ls, b, needself, line)
1563 luaK:storevar(ls.fs, v, b)
1564 luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
1565end
1566
1567------------------------------------------------------------------------
1568-- parse a function call with no returns or an assignment statement
1569-- * used in statements()
1570------------------------------------------------------------------------
1571function luaY:exprstat(ls)
1572 -- stat -> func | assignment
1573 local fs = ls.fs
1574 local v = {} -- LHS_assign
1575 v.v = {}
1576 self:primaryexp(ls, v.v)
1577 if v.v.k == "VCALL" then -- stat -> func
1578 luaK:setcallreturns(fs, v.v, 0) -- call statement uses no results
1579 else -- stat -> assignment
1580 v.prev = nil
1581 self:assignment(ls, v, 1)
1582 end
1583end
1584
1585------------------------------------------------------------------------
1586-- parse a return statement
1587-- * used in statements()
1588------------------------------------------------------------------------
1589function luaY:retstat(ls)
1590 -- stat -> RETURN explist
1591 local fs = ls.fs
1592 local e = {} -- expdesc
1593 local first, nret -- registers with returned values
1594 self:next(ls) -- skip RETURN
1595 if self:block_follow(ls.t.token) or ls.t.token == ";" then
1596 first, nret = 0, 0 -- return no values
1597 else
1598 nret = self:explist1(ls, e) -- optional return values
1599 if e.k == "VCALL" then
1600 luaK:setcallreturns(fs, e, self.LUA_MULTRET)
1601 if nret == 1 then -- tail call?
1602 luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
1603 lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
1604 end
1605 first = fs.nactvar
1606 nret = self.LUA_MULTRET -- return all values
1607 else
1608 if nret == 1 then -- only one single value?
1609 first = luaK:exp2anyreg(fs, e)
1610 else
1611 luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
1612 first = fs.nactvar -- return all 'active' values
1613 lua_assert(nret == fs.freereg - first)
1614 end
1615 end--if
1616 end--if
1617 luaK:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
1618end
1619
1620------------------------------------------------------------------------
1621-- parse a break statement
1622-- * used in statements()
1623------------------------------------------------------------------------
1624function luaY:breakstat(ls)
1625 -- stat -> BREAK
1626 local fs = ls.fs
1627 local bl = fs.bl
1628 local upval = false
1629 self:next(ls) -- skip BREAK
1630 while bl and not bl.isbreakable do
1631 if bl.upval then upval = true end
1632 bl = bl.previous
1633 end
1634 if not bl then
1635 luaX:syntaxerror(ls, "no loop to break")
1636 end
1637 if upval then
1638 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
1639 end
1640 bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
1641end
1642
1643------------------------------------------------------------------------
1644-- initial parsing for statements, calls a lot of functions
1645-- * returns boolean instead of 0|1
1646-- * used in chunk()
1647------------------------------------------------------------------------
1648function luaY:statement(ls)
1649 local line = ls.linenumber -- may be needed for error messages
1650 local c = ls.t.token
1651 if c == "TK_IF" then -- stat -> ifstat
1652 self:ifstat(ls, line)
1653 return false
1654 elseif c == "TK_WHILE" then -- stat -> whilestat
1655 self:whilestat(ls, line)
1656 return false
1657 elseif c == "TK_DO" then -- stat -> DO block END
1658 self:next(ls) -- skip DO
1659 self:block(ls)
1660 self:check_match(ls, "TK_END", "TK_DO", line)
1661 return false
1662 elseif c == "TK_FOR" then -- stat -> forstat
1663 self:forstat(ls, line)
1664 return false
1665 elseif c == "TK_REPEAT" then -- stat -> repeatstat
1666 self:repeatstat(ls, line)
1667 return false
1668 elseif c == "TK_FUNCTION" then -- stat -> funcstat
1669 self:funcstat(ls, line)
1670 return false
1671 elseif c == "TK_LOCAL" then -- stat -> localstat
1672 self:next(ls) -- skip LOCAL
1673 if self:testnext(ls, "TK_FUNCTION") then -- local function?
1674 self:localfunc(ls)
1675 else
1676 self:localstat(ls)
1677 end
1678 return false
1679 elseif c == "TK_RETURN" then -- stat -> retstat
1680 self:retstat(ls)
1681 return true -- must be last statement
1682 elseif c == "TK_BREAK" then -- stat -> breakstat
1683 self:breakstat(ls)
1684 return true -- must be last statement
1685 else
1686 self:exprstat(ls)
1687 return false -- to avoid warnings
1688 end--if c
1689end
1690
1691------------------------------------------------------------------------
1692-- parse a chunk, which consists of a bunch of statements
1693-- * used in parser(), body(), block()
1694------------------------------------------------------------------------
1695function luaY:chunk(ls)
1696 -- chunk -> { stat [';'] }
1697 local islast = false
1698 self:enterlevel(ls)
1699 while not islast and not self:block_follow(ls.t.token) do
1700 islast = self:statement(ls)
1701 self:testnext(ls, ";")
1702 lua_assert(ls.fs.freereg >= ls.fs.nactvar)
1703 ls.fs.freereg = ls.fs.nactvar -- free registers
1704 end
1705 self:leavelevel(ls)
1706end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua
deleted file mode 100644
index 80cc4a5..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/luac.lua
+++ /dev/null
@@ -1,71 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 luac.lua
4 Primitive luac in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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.0.3 distribution
18-- * usage: lua luac.lua file.lua
19----------------------------------------------------------------------]]
20
21------------------------------------------------------------------------
22-- load and initialize the required modules
23------------------------------------------------------------------------
24require("lzio.lua")
25require("llex.lua")
26require("lopcodes.lua")
27require("ldump.lua")
28require("lcode.lua")
29require("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, "@"..filename)
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)
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"))
68f:write(assert(yloadfile(arg[1])))
69io.close(f)
70
71--end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua
deleted file mode 100644
index 7b98246..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lzio.lua
+++ /dev/null
@@ -1,120 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 lzio.lua
4 Lua 5 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 in buffer
21-- z.reader -- chunk reader function
22-- z.data -- additional data
23-- z.name -- name of stream
24-- * Current position, p, is now last read index instead of a pointer
25--
26-- Not implemented:
27-- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk
28-- * luaZ_read: used only in lundump.c:ezread to read +1 bytes
29-- * luaZ_openspace: dropped; let Lua handle buffers as strings
30-- * luaZ buffer macros: dropped; unused for now
31--
32-- Alternatives:
33-- * zname(z) is z.name
34--
35-- Added:
36-- (both of the following are vaguely adapted from lauxlib.c)
37-- * luaZ:make_getS: create Chunkreader from a string
38-- * luaZ:make_getF: create Chunkreader that reads from a file
39----------------------------------------------------------------------]]
40
41luaZ = {}
42
43------------------------------------------------------------------------
44-- * reader() should return a string, or nil if nothing else to parse.
45-- Unlike Chunkreaders, there are no arguments like additional data
46-- * Chunkreaders are handled in lauxlib.h, see luaL_load(file|buffer)
47-- * Original Chunkreader:
48-- const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz);
49-- * This Lua chunk reader implementation:
50-- returns string or nil, no arguments to function
51------------------------------------------------------------------------
52
53------------------------------------------------------------------------
54-- create a chunk reader from a source string
55------------------------------------------------------------------------
56function luaZ:make_getS(buff)
57 local b = buff
58 return function() -- chunk reader anonymous function here
59 if not b then return nil end
60 local data = b
61 b = nil
62 return data
63 end
64end
65
66------------------------------------------------------------------------
67-- create a chunk reader from a source file
68------------------------------------------------------------------------
69function luaZ:make_getF(filename)
70 local LUAL_BUFFERSIZE = 512
71 local h = io.open(filename, "r")
72 if not h then return nil end
73 return function() -- chunk reader anonymous function here
74 if not h or io.type(h) == "closed file" then return nil end
75 local buff = h:read(LUAL_BUFFERSIZE)
76 if not buff then h:close(); h = nil end
77 return buff
78 end
79end
80
81------------------------------------------------------------------------
82-- creates a zio input stream
83-- returns the ZIO structure, z
84------------------------------------------------------------------------
85function luaZ:init(reader, data, name)
86 if not reader then return end
87 local z = {}
88 z.reader = reader
89 z.data = data or ""
90 z.name = name
91 -- set up additional data for reading
92 if not data or data == "" then z.n = 0 else z.n = string.len(data) end
93 z.p = 0
94 return z
95end
96
97------------------------------------------------------------------------
98-- fill up input buffer
99------------------------------------------------------------------------
100function luaZ:fill(z)
101 local data = z.reader()
102 z.data = data
103 if not data or data == "" then return "EOZ" end
104 z.n = string.len(data) - 1
105 z.p = 1
106 return string.sub(data, 1, 1)
107end
108
109------------------------------------------------------------------------
110-- get next character from the input stream
111------------------------------------------------------------------------
112function luaZ:zgetc(z)
113 if z.n > 0 then
114 z.n = z.n - 1
115 z.p = z.p + 1
116 return string.sub(z.data, z.p, z.p)
117 else
118 return self:fill(z)
119 end
120end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua
deleted file mode 100644
index 0c9403e..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/bench_llex.lua
+++ /dev/null
@@ -1,99 +0,0 @@
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
15require("../lzio")
16require("../llex")
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.gfind([[
26../lcode.lua
27../ldump.lua
28../llex.lua
29../lopcodes.lua
30../lparser.lua
31../lzio.lua
32]], "%S+") do
33 table.insert(fileset, fn)
34end
35
36for i = 1, table.getn(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 = string.len(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, table.getn(fileset) do
70 ------------------------------------------------------------
71 local chunk = fileset[i]
72 local z = luaZ:init(luaZ:make_getS(chunk), nil, "=string")
73 luaX:setinput(L, LS, z, z.name)
74 while true do
75 LS.t.token = luaX:lex(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 + string.len(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.0.3/test/sample.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua
deleted file mode 100644
index dc6eaee..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/sample.lua
+++ /dev/null
@@ -1,3 +0,0 @@
1local a = 47
2local b = "hello, world!"
3print(a, b)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua
deleted file mode 100644
index d867688..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_ldump.lua
+++ /dev/null
@@ -1,98 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 test_ldump.lua
4 Test for ldump.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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
19require("../lopcodes")
20require("../ldump")
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.nups = 0
54F.numparams = 0
55F.is_vararg = 0
56F.maxstacksize = 5
57F.sizelineinfo = 7
58F.lineinfo = {}
59F.lineinfo[0] = 1
60F.lineinfo[1] = 2
61F.lineinfo[2] = 3
62F.lineinfo[3] = 3
63F.lineinfo[4] = 3
64F.lineinfo[5] = 3
65F.lineinfo[6] = 3
66F.sizelocvars = 2
67F.locvars = {}
68F.locvars[0] = { varname = "a", startpc = 1, endpc = 6 }
69F.locvars[1] = { varname = "b", startpc = 2, endpc = 6 }
70F.sizeupvalues = 0
71F.upvalues = {}
72F.sizek = 3
73F.k = {}
74F.k[0] = { value = 47 }
75F.k[1] = { value = "hello, world!" }
76F.k[2] = { value = "print" }
77F.sizep = 0
78F.p = {}
79F.sizecode = 7
80F.code = {}
81F.code[0] = { OP = 1, A = 0, Bx = 0 }
82F.code[1] = { OP = 1, A = 1, Bx = 1 }
83F.code[2] = { OP = 5, A = 2, Bx = 2 }
84F.code[3] = { OP = 0, A = 3, B = 0, C = 0 }
85F.code[4] = { OP = 0, A = 4, B = 1, C = 0 }
86F.code[5] = { OP = 25, A = 2, B = 3, C = 1 }
87F.code[6] = { OP = 27, A = 0, B = 1, C = 0 }
88
89local L = {}
90--[[
91local Writer, Buff = luaU:make_setS()
92luaU:dump(L, F, Writer, Buff)
93for i = 1, string.len(Buff.data) do
94 io.stdout:write(string.byte(string.sub(Buff.data, i, i)).." ")
95end
96--]]
97local Writer, Buff = luaU:make_setF("try.out")
98luaU:dump(L, F, Writer, Buff)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua
deleted file mode 100644
index 6bc834d..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_llex.lua
+++ /dev/null
@@ -1,504 +0,0 @@
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
20require("../lzio")
21require("../llex")
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",
120 "--[[bovine]]",
121 PASS, "1 TK_EOS",
122 },
123 -------------------------------------------------------------
124 { "unterminated block comment 1",
125 "--[[bovine",
126 FAIL, ":1: unfinished long comment near `<eof>'",
127 },
128 -------------------------------------------------------------
129 { "unterminated block comment 2",
130 "--[[bovine]",
131 FAIL, ":1: unfinished long comment near `<eof>'",
132 },
133 -------------------------------------------------------------
134 { "unterminated block comment 3",
135 "--[[bovine\nmoo moo\nwoof",
136 FAIL, ":3: unfinished long comment near `<eof>'",
137 },
138 -------------------------------------------------------------
139 { "basic long string",
140 "\n[[bovine]]\n",
141 PASS, "2 TK_STRING = bovine\n3 TK_EOS",
142 },
143 -------------------------------------------------------------
144 { "first newline consumed in long string",
145 "[[\nmoo]]",
146 PASS, "2 TK_STRING = moo\n2 TK_EOS",
147 },
148 -------------------------------------------------------------
149 { "multiline long string",
150 "[[moo\nmoo moo\n]]",
151 PASS, "3 TK_STRING = moo\nmoo moo\n\n3 TK_EOS",
152 },
153 -------------------------------------------------------------
154 { "unterminated long string 1",
155 "\n[[\nbovine",
156 FAIL, ":3: unfinished long string near `<eof>'",
157 },
158 -------------------------------------------------------------
159 { "unterminated long string 2",
160 "[[bovine]",
161 FAIL, ":1: unfinished long string near `<eof>'",
162 },
163 -------------------------------------------------------------
164 { "unterminated long string 3",
165 "[[[[ \n",
166 FAIL, ":2: unfinished long string near `<eof>'",
167 },
168 -------------------------------------------------------------
169 { "nested long string 1",
170 "[[moo[[moo]]moo]]",
171 PASS, "moo[[moo]]moo",
172 },
173 -------------------------------------------------------------
174 { "nested long string 2",
175 "[[moo[[moo[[[[]]]]moo]]moo]]",
176 PASS, "moo[[moo[[[[]]]]moo]]moo",
177 },
178 -------------------------------------------------------------
179 { "nested long string 3",
180 "[[[[[[]]]][[[[]]]]]]",
181 PASS, "[[[[]]]][[[[]]]]",
182 },
183 -------------------------------------------------------------
184 { "brackets in long strings 1",
185 "[[moo[moo]]",
186 PASS, "moo[moo",
187 },
188 -------------------------------------------------------------
189 { "brackets in long strings 2",
190 "[[moo[[moo]moo]]moo]]",
191 PASS, "moo[[moo]moo]]moo",
192 },
193 -------------------------------------------------------------
194 { "unprocessed escapes in long strings",
195 [[ [[\a\b\f\n\r\t\v\123]] ]],
196 PASS, [[\a\b\f\n\r\t\v\123]],
197 },
198 -------------------------------------------------------------
199 { "unbalanced long string",
200 "[[moo]]moo]]",
201 PASS, "1 TK_STRING = moo\n1 TK_NAME = moo\n1 CHAR = ']'\n1 CHAR = ']'\n1 TK_EOS",
202 },
203 -------------------------------------------------------------
204 { "keywords 1",
205 "and break do else",
206 PASS, "1 TK_AND\n1 TK_BREAK\n1 TK_DO\n1 TK_ELSE\n1 TK_EOS",
207 },
208 -------------------------------------------------------------
209 { "keywords 2",
210 "elseif end false for",
211 PASS, "1 TK_ELSEIF\n1 TK_END\n1 TK_FALSE\n1 TK_FOR\n1 TK_EOS",
212 },
213 -------------------------------------------------------------
214 { "keywords 3",
215 "function if in local nil",
216 PASS, "1 TK_FUNCTION\n1 TK_IF\n1 TK_IN\n1 TK_LOCAL\n1 TK_NIL\n1 TK_EOS",
217 },
218 -------------------------------------------------------------
219 { "keywords 4",
220 "not or repeat return",
221 PASS, "1 TK_NOT\n1 TK_OR\n1 TK_REPEAT\n1 TK_RETURN\n1 TK_EOS",
222 },
223 -------------------------------------------------------------
224 { "keywords 5",
225 "then true until while",
226 PASS, "1 TK_THEN\n1 TK_TRUE\n1 TK_UNTIL\n1 TK_WHILE\n1 TK_EOS",
227 },
228 -------------------------------------------------------------
229 { "concat and dots",
230 ".. ...",
231 PASS, "1 TK_CONCAT\n1 TK_DOTS\n1 TK_EOS",
232 },
233 -------------------------------------------------------------
234 { "shbang handling 1",
235 "#blahblah",
236 PASS, "1 TK_EOS",
237 },
238 -------------------------------------------------------------
239 { "shbang handling 2",
240 "#blahblah\nmoo moo\n",
241 PASS, "2 TK_NAME = moo\n2 TK_NAME = moo\n3 TK_EOS",
242 },
243 -------------------------------------------------------------
244 { "empty string",
245 [['']],
246 PASS, "1 TK_STRING = \n1 TK_EOS",
247 },
248 -------------------------------------------------------------
249 { "single-quoted string",
250 [['bovine']],
251 PASS, "1 TK_STRING = bovine\n1 TK_EOS",
252 },
253 -------------------------------------------------------------
254 { "double-quoted string",
255 [["bovine"]],
256 PASS, "1 TK_STRING = bovine\n1 TK_EOS",
257 },
258 -------------------------------------------------------------
259 { "unterminated string 1",
260 [['moo ]],
261 FAIL, ":1: unfinished string near `<eof>'",
262 },
263 -------------------------------------------------------------
264 { "unterminated string 2",
265 [["moo \n]],
266 FAIL, ":1: unfinished string near `<eof>'",
267 },
268 -------------------------------------------------------------
269 { "escaped newline in string, line number counted",
270 "\"moo\\\nmoo\\\nmoo\"",
271 PASS, "3 TK_STRING = moo\nmoo\nmoo\n3 TK_EOS",
272 },
273 -------------------------------------------------------------
274 { "escaped characters in string 1",
275 [["moo\amoo"]],
276 PASS, "1 TK_STRING = moo\amoo",
277 },
278 -------------------------------------------------------------
279 { "escaped characters in string 2",
280 [["moo\bmoo"]],
281 PASS, "1 TK_STRING = moo\bmoo",
282 },
283 -------------------------------------------------------------
284 { "escaped characters in string 3",
285 [["moo\f\n\r\t\vmoo"]],
286 PASS, "1 TK_STRING = moo\f\n\r\t\vmoo",
287 },
288 -------------------------------------------------------------
289 { "escaped characters in string 4",
290 [["\\ \" \' \? \[ \]"]],
291 PASS, "1 TK_STRING = \\ \" \' \? \[ \]",
292 },
293 -------------------------------------------------------------
294 { "escaped characters in string 5",
295 [["\z \k \: \;"]],
296 PASS, "1 TK_STRING = z k : ;",
297 },
298 -------------------------------------------------------------
299 { "escaped characters in string 6",
300 [["\8 \65 \160 \180K \097097"]],
301 PASS, "1 TK_STRING = \8 \65 \160 \180K \097097\n",
302 },
303 -------------------------------------------------------------
304 { "escaped characters in string 7",
305 [["\666"]],
306 FAIL, ":1: escape sequence too large near `\"'",
307 },
308 -------------------------------------------------------------
309 { "simple numbers",
310 "123 123+",
311 PASS, "1 TK_NUMBER = 123\n1 TK_NUMBER = 123\n1 CHAR = '+'\n1 TK_EOS",
312 },
313 -------------------------------------------------------------
314 { "longer numbers",
315 "1234567890 12345678901234567890",
316 PASS, "1 TK_NUMBER = 1234567890\n1 TK_NUMBER = 1.2345678901235e+19\n",
317 },
318 -------------------------------------------------------------
319 { "fractional numbers",
320 ".123 .12345678901234567890",
321 PASS, "1 TK_NUMBER = 0.123\n1 TK_NUMBER = 0.12345678901235\n",
322 },
323 -------------------------------------------------------------
324 { "more numbers with decimal points",
325 "12345.67890 1.1.",
326 PASS, "1 TK_NUMBER = 12345.6789\n1 TK_NUMBER = 1.1\n1 CHAR = '.'\n",
327 },
328 -------------------------------------------------------------
329 { "double decimal points",
330 ".1.1",
331 FAIL, ":1: malformed number near `.1.1'",
332 },
333 -------------------------------------------------------------
334 { "double dots within numbers",
335 "1..1",
336 FAIL, ":1: ambiguous syntax (decimal point x string concatenation) near `1..'",
337 },
338 -------------------------------------------------------------
339 { "incomplete exponential numbers",
340 "123e",
341 FAIL, ":1: malformed number near `123e'",
342 },
343 -------------------------------------------------------------
344 { "exponential numbers 1",
345 "1234e5 1234e5.",
346 PASS, "1 TK_NUMBER = 123400000\n1 TK_NUMBER = 123400000\n1 CHAR = '.'",
347 },
348 -------------------------------------------------------------
349 { "exponential numbers 2",
350 "1234e56 1.23e123",
351 PASS, "1 TK_NUMBER = 1.234e+59\n1 TK_NUMBER = 1.23e+123\n",
352 },
353 -------------------------------------------------------------
354 { "exponential numbers 3",
355 "12.34e+",
356 FAIL, ":1: malformed number near `12.34e+'",
357 },
358 -------------------------------------------------------------
359 { "exponential numbers 4",
360 "12.34e+5 123.4e-5 1234.E+5",
361 PASS, "1 TK_NUMBER = 1234000\n1 TK_NUMBER = 0.001234\n1 TK_NUMBER = 123400000\n",
362 },
363 -------------------------------------------------------------
364 { "single character symbols 1",
365 "= > < ~",
366 PASS, "1 CHAR = '='\n1 CHAR = '>'\n1 CHAR = '<'\n1 CHAR = '~'\n",
367 },
368 -------------------------------------------------------------
369 { "double character symbols",
370 "== >= <= ~=",
371 PASS, "1 TK_EQ\n1 TK_GE\n1 TK_LE\n1 TK_NE\n",
372 },
373 -------------------------------------------------------------
374 { "simple identifiers",
375 "abc ABC",
376 PASS, "1 TK_NAME = abc\n1 TK_NAME = ABC\n1 TK_EOS",
377 },
378 -------------------------------------------------------------
379 { "more identifiers",
380 "_abc _ABC",
381 PASS, "1 TK_NAME = _abc\n1 TK_NAME = _ABC\n1 TK_EOS",
382 },
383 -------------------------------------------------------------
384 { "still more identifiers",
385 "_aB_ _123",
386 PASS, "1 TK_NAME = _aB_\n1 TK_NAME = _123\n1 TK_EOS",
387 },
388 -------------------------------------------------------------
389 { "invalid control character",
390 "\4",
391 FAIL, ":1: invalid control char near `char(4)'",
392 },
393 -------------------------------------------------------------
394 { "single character symbols 2",
395 "` ! @ $ %",
396 PASS, "1 CHAR = '`'\n1 CHAR = '!'\n1 CHAR = '@'\n1 CHAR = '$'\n1 CHAR = '%'\n",
397 },
398 -------------------------------------------------------------
399 { "single character symbols 3",
400 "^ & * ( )",
401 PASS, "1 CHAR = '^'\n1 CHAR = '&'\n1 CHAR = '*'\n1 CHAR = '('\n1 CHAR = ')'\n",
402 },
403 -------------------------------------------------------------
404 { "single character symbols 4",
405 "_ - + \\ |",
406 PASS, "1 TK_NAME = _\n1 CHAR = '-'\n1 CHAR = '+'\n1 CHAR = '\\'\n1 CHAR = '|'\n",
407 },
408 -------------------------------------------------------------
409 { "single character symbols 5",
410 "{ } [ ] :",
411 PASS, "1 CHAR = '{'\n1 CHAR = '}'\n1 CHAR = '['\n1 CHAR = ']'\n1 CHAR = ':'\n",
412 },
413 -------------------------------------------------------------
414 { "single character symbols 6",
415 "; , . / ?",
416 PASS, "1 CHAR = ';'\n1 CHAR = ','\n1 CHAR = '.'\n1 CHAR = '/'\n1 CHAR = '?'\n",
417 },
418 -------------------------------------------------------------
419 }
420 ------------------------------------------------------------------
421 -- perform a test case
422 ------------------------------------------------------------------
423 function do_test_case(count, test_case)
424 if comment == "" then return end -- skip empty entries
425 local comment, chunk, outcome, matcher = unpack(test_case)
426 local result = PASS
427 local output = ""
428 -- initialize lexer
429 local L, LS = {}, {}
430 local z = luaZ:init(luaZ:make_getS(chunk), nil, "=test")
431 luaX:setinput(L, LS, z, z.name)
432 -- lexer test loop
433 repeat
434 -- protected call
435 local status, token = pcall(luaX.lex, luaX, LS, LS.t)
436 LS.t.token = token
437 output = output..LS.linenumber.." "
438 if status then
439 -- successful call
440 if string.len(token) > 1 then
441 if token == "TK_NAME"
442 or token == "TK_NUMBER"
443 or token == "TK_STRING" then
444 token = token.." = "..LS.t.seminfo
445 end
446 elseif string.byte(token) >= 32 then -- displayable chars
447 token = "CHAR = '"..token.."'"
448 else -- control characters
449 token = "CHAR = (".. string.byte(token)..")"
450 end
451 output = output..token.."\n"
452 else
453 -- failed call
454 output = output..token -- token is the error message
455 result = FAIL
456 break
457 end
458 until LS.t.token == "TK_EOS"
459 -- decision making and reporting
460 local head = "Test "..count..": "..comment
461 if matcher == "" then
462 -- nothing to check against, display for manual check
463 print(head.."\nMANUAL please check manually"..
464 "\n--chunk---------------------------------\n"..chunk..
465 "\n--actual--------------------------------\n"..output..
466 "\n\n")
467 return
468 else
469 if outcome == PASS then
470 -- success expected, may be a partial match
471 if string.find(output, matcher, 1, 1) and result == PASS then
472 if not BRIEF then print(head.."\nOK expected success\n") end
473 return
474 end
475 else
476 -- failure expected, may be a partial match
477 if string.find(output, matcher, 1, 1) and result == FAIL then
478 if not BRIEF then print(head.."\nOK expected failure\n") end
479 return
480 end
481 end
482 -- failed because of unmatched string or boolean result
483 local function passfail(status)
484 if status == PASS then return "PASS" else return "FAIL" end
485 end
486 print(head.." *FAILED*"..
487 "\noutcome="..passfail(outcome)..
488 "\nactual= "..passfail(result)..
489 "\n--chunk---------------------------------\n"..chunk..
490 "\n--expected------------------------------\n"..matcher..
491 "\n--actual--------------------------------\n"..output..
492 "\n\n")
493 end
494 end
495 ------------------------------------------------------------------
496 -- perform auto testing
497 ------------------------------------------------------------------
498 for i,test_case in ipairs(test_cases) do
499 do_test_case(i, test_case)
500 end
501end
502
503auto_test()
504--]]
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua
deleted file mode 100644
index b9400cc..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser.lua
+++ /dev/null
@@ -1,60 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 test_lparser.lua
4 Test for lparser.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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
19require("../lzio")
20require("../llex")
21require("../lopcodes")
22require("../ldump")
23require("../lcode")
24require("../lparser")
25
26function lua_assert(test)
27 if not test then error("assertion failed!") end
28end
29
30luaX:init()
31
32------------------------------------------------------------------------
33-- try 1
34------------------------------------------------------------------------
35
36local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string")
37local LuaState = {}
38local Func = luaY:parser(LuaState, zio, nil)
39
40--[[
41for i, v in Func do
42 if type(v) == "string" or type(v) == "number" then
43 print(i, v)
44 elseif type(v) == "table" then
45 print(i, "TABLE")
46 end
47end
48--]]
49
50local Writer, Buff = luaU:make_setF("parse1.out")
51luaU:dump(LuaState, Func, Writer, Buff)
52
53------------------------------------------------------------------------
54-- try 2
55------------------------------------------------------------------------
56
57zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua")
58Func = luaY:parser(LuaState, zio, nil)
59Writer, Buff = luaU:make_setF("parse2.out")
60luaU:dump(LuaState, Func, Writer, Buff)
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua
deleted file mode 100644
index b912e68..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lparser2.lua
+++ /dev/null
@@ -1,202 +0,0 @@
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.0.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
28require("../lzio")
29require("../llex")
30require("../lopcodes")
31require("../ldump")
32require("../lcode")
33require("../lparser")
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
45require("../../test_lua/test_parser-5.0")
46
47local test, expect, heading = {}, {}, {}
48local total, total_pass, total_fail = 0, 0, 0
49
50for ln in string.gfind(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, "test")
145 local status, func = pcall(luaY.parser, luaY, LuaState, zio, nil)
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 string.len(bc1) ~= string.len(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.0.3/test/test_lzio.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua
deleted file mode 100644
index cfd3f4b..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_lzio.lua
+++ /dev/null
@@ -1,55 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 test_lzio.lua
4 Test for lzio.lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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
17require("../lzio")
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--]]
42
43-- test read beyond end of file
44-- bug reported by Adam429
45--[[
46z = luaZ:init(luaZ:make_getF("test_lzio.lua"), nil, "=string")
47while true do
48 local c = luaZ:zgetc(z)
49 io.stdout:write("("..c..")")
50 if c == "EOZ" then break end
51end
52print(luaZ:zgetc(z))
53print(luaZ:zgetc(z))
54io.stdout:write("\n")
55--]]
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua
deleted file mode 100644
index eeabecb..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/test/test_number.lua
+++ /dev/null
@@ -1,174 +0,0 @@
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) 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-- * 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
24require("../ldump")
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
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua
deleted file mode 100644
index 5c60e17..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/call_graph.lua
+++ /dev/null
@@ -1,254 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 call_graph.lua
4 Call graph generator.
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-- * the call tracer wraps function calls in tables to do its work
18-- * not very elegant as the namespace of the table/module is affected
19-- * tracing using the debugger is probably much more powerful...
20-- * use of braces {} allows editors to match braces in the output
21-- and do folding, if such facilities are available; for example, the
22-- output looks better if Lua syntax highlighting is used on SciTE
23----------------------------------------------------------------------]]
24
25------------------------------------------------------------------------
26-- options
27------------------------------------------------------------------------
28
29local SHOW_EXPDESC = true -- show expdesc struct data
30
31------------------------------------------------------------------------
32-- load and initialize modules
33------------------------------------------------------------------------
34require("../lzio.lua")
35require("../llex.lua")
36require("../lopcodes.lua")
37require("../ldump.lua")
38require("../lcode.lua")
39require("../lparser.lua")
40
41function lua_assert(test)
42 if not test then error("assertion failed!") end
43end
44luaX:init()
45local LuaState = {}
46
47------------------------------------------------------------------------
48-- call graph generator
49-- * (1) logging functions, (2) the wrapper initializer itself
50------------------------------------------------------------------------
51
52llog = {}
53
54------------------------------------------------------------------------
55-- initialize log file; the usual mode is append; can use stdout/stderr
56------------------------------------------------------------------------
57function llog:init(filename)
58 if filename == "stdout" then self.h = io.stdout
59 elseif filename == "stderr" then self.h = io.stderr
60 else
61 self.h = io.open(filename, "ab")
62 if not self.h then
63 error("can't open log file "..filename.."for writing")
64 end
65 end
66 self.h:write("\n-- start of log --\n\n")
67end
68
69------------------------------------------------------------------------
70-- cleanly closes log file
71------------------------------------------------------------------------
72function llog:exit()
73 self.h:write("\n-- end of log --\n\n")
74 if self.h ~= io.stdout and self.h ~= io.stderr then
75 self.h:close()
76 end
77end
78
79------------------------------------------------------------------------
80-- logs a message at a particular call depth
81------------------------------------------------------------------------
82function llog:msg(msg, level)
83 if level then msg = string.rep(" ", level)..msg end
84 self.h:write(msg)
85 self.h:flush()
86end
87
88------------------------------------------------------------------------
89-- set up wrapper functions to do tracing on a per-module basis
90------------------------------------------------------------------------
91function llog:calltrace(parms)
92 ------------------------------------------------------------------
93 -- process parameters
94 ------------------------------------------------------------------
95 local module = parms.module
96 local modulename = parms.modulename
97 if type(module) ~= "table" then
98 error("module table parameter required")
99 elseif not modulename then
100 error("module name parameter required")
101 end
102 ------------------------------------------------------------------
103 -- use either allow or deny list
104 ------------------------------------------------------------------
105 local allow = parms.allow or {}
106 local deny = parms.deny or {}
107 if table.getn(allow) > 0 and table.getn(deny) > 0 then
108 error("can't apply both allow and deny lists at the same time")
109 end
110 ------------------------------------------------------------------
111 -- select functions to wrap
112 ------------------------------------------------------------------
113 local flist = {}
114 for i, f in pairs(module) do
115 local wrapthis
116 if table.getn(allow) > 0 then -- allow some only
117 wrapthis = false
118 for j, v in ipairs(allow) do
119 if i == v then wrapthis = true; break end
120 end
121 elseif table.getn(deny) > 0 then -- deny some only
122 wrapthis = true
123 for j, v in ipairs(deny) do
124 if i == v then wrapthis = false; break end
125 end
126 else -- default include
127 wrapthis = true
128 end
129 if wrapthis then flist[i] = f end
130 end
131 ------------------------------------------------------------------
132 -- wrapped function(s) in a module for tracing
133 ------------------------------------------------------------------
134 llog.level = 0 -- nesting level
135 for i, f in pairs(flist) do
136 local ModuleName = modulename..":"
137 local OldName, OldFunc = i, f
138 if type(OldFunc) == "function" then
139 local NewName = "__"..OldName
140 while module[NewName] ~= nil do -- avoid collisions
141 NewName = "_"..NewName
142 end
143 module[NewName] = OldFunc
144 module[OldName] =
145 ----------------------------------------------------------
146 -- wrapper function for a module's function
147 -- old function XYZ is renamed __XYZ
148 ----------------------------------------------------------
149 function(self, ...)
150 local parms = " ("
151 local exps = {}
152 -- look for expdesc structs, identify FuncState structs too
153 local function checkexpdesc(v)
154 local typ = type(v)
155 if typ == "table" then
156 if v.code then return "func"
157 elseif v.L then return "ls"
158 elseif v.seminfo then return "token"
159 elseif v.k then
160 table.insert(exps, v)
161 return "exp"..table.getn(exps)
162 end
163 end
164 return typ
165 end
166 -- format parameters for printing
167 for i,v in ipairs(arg) do
168 if type(v) == "number" then parms = parms..v..","
169 elseif type(v) == "string" then parms = parms.."'"..v.."',"
170 elseif type(v) == "boolean" then parms = parms..tostring(v)..","
171 elseif SHOW_EXPDESC then parms = parms..checkexpdesc(v)..","
172 else parms = parms..type(v)..","
173 end
174 end
175 if table.getn(arg) > 0 then -- chop last comma
176 parms = string.sub(parms, 1, -2)
177 end
178 -- up level
179 llog:msg(ModuleName..OldName..parms..") {\n", llog.level)
180 llog.level = llog.level + 1
181 -- display contents of expdesc
182 if SHOW_EXPDESC and table.getn(exps) > 0 then
183 for i,v in ipairs(exps) do
184 parms = "k:'"..v.k.."',"
185 if v.info then parms = parms.."info:"..v.info.."," end
186 if v.aux then parms = parms.."aux:"..v.aux.."," end
187 if v.t then parms = parms.."t:"..v.t.."," end
188 if v.f then parms = parms.."f:"..v.f.."," end
189 parms = string.sub(parms, 1, -2)
190 llog:msg("exp"..i.."("..parms..")\n", llog.level)
191 end
192 end
193 -- original function called here...
194 local retval = {self[NewName](self, unpack(arg))}
195 -- format return values
196 local rets = " = "
197 for i,v in ipairs(retval) do
198 if type(v) == "number" then rets = rets..v..","
199 elseif type(v) == "string" then rets = rets.."'"..v.."',"
200 elseif type(v) == "boolean" then rets = rets..tostring(v)..","
201 else rets = rets..type(v)..","
202 end
203 end
204 if table.getn(retval) > 0 then -- chop last comma
205 rets = string.sub(rets, 1, -2)
206 else
207 rets = ""
208 end
209 -- down level
210 llog.level = llog.level - 1
211 llog:msg("} "..ModuleName..OldName..rets.."\n", llog.level)
212 return unpack(retval)
213 end--function
214 ----------------------------------------------------------
215 --print("patched "..OldName)
216 end--if
217 end--for
218end
219
220------------------------------------------------------------------------
221-- testing here
222-- * allow/deny works a bit like a somewhat similar Apache syntax
223-- * e.g. to show only function 'lex' and 'save' -> allow={"lex","save",}
224-- to not show function 'save_and_next' -> deny={"save_and_next",}
225-- * you can't do both allow and deny at the same time
226------------------------------------------------------------------------
227
228-- select the file or stream to output to
229--llog:init("calls.log")
230llog:init("stdout")
231
232-- select modules to trace
233llog:calltrace{module=luaX, modulename="luaX", allow={"lex"} }
234 -- here we trace only the main lex() function, to avoid showing
235 -- too many lexer calls; we want to focus on luaY and luaK
236llog:calltrace{module=luaY, modulename="luaY", deny={"growvector"} }
237 -- growvector() is just a limit checker in Yueliang, so drop it
238 -- to simplify the output log
239llog:calltrace{module=luaK, modulename="luaK"}
240--llog:calltrace{module=luaU, modulename="luaU"}
241
242-- select input stream
243local zio = luaZ:init(luaZ:make_getS("local a = 1"), nil, "=string")
244--local zio = luaZ:init(luaZ:make_getF("sample.lua"), nil, "@sample.lua")
245
246-- compile the source
247local Func = luaY:parser(LuaState, zio, nil)
248
249-- write binary chunk
250local Writer, Buff = luaU:make_setF("call_graph.out")
251luaU:dump(LuaState, Func, Writer, Buff)
252
253llog:exit()
254--end
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log
deleted file mode 100644
index c163f6c..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/calls.log
+++ /dev/null
@@ -1,152 +0,0 @@
1
2-- start of log --
3
4luaY:parser (table,table) {
5 luaY:open_func (table,table) {
6 luaY:newproto (table) {
7 } luaY:newproto = table
8 } luaY:open_func
9 luaY:next (table) {
10 luaX:lex (table,table) {
11 } luaX:lex = 'TK_LOCAL'
12 } luaY:next
13 luaY:chunk (table) {
14 luaY:enterlevel (table) {
15 } luaY:enterlevel
16 luaY:block_follow ('TK_LOCAL') {
17 } luaY:block_follow = false
18 luaY:statement (table) {
19 luaY:next (table) {
20 luaX:lex (table,table) {
21 } luaX:lex = 'TK_NAME'
22 } luaY:next
23 luaY:testnext (table,'TK_FUNCTION') {
24 } luaY:testnext = false
25 luaY:localstat (table) {
26 luaY:str_checkname (table) {
27 luaY:check_condition (table,true,'<name> expected') {
28 } luaY:check_condition
29 luaY:next (table) {
30 luaX:lex (table,table) {
31 } luaX:lex = '='
32 } luaY:next
33 } luaY:str_checkname = 'a'
34 luaY:new_localvar (table,'a',0) {
35 luaY:registerlocalvar (table,'a') {
36 luaY:growvector (table,table,0,0) {
37 } luaY:growvector
38 } luaY:registerlocalvar = 0
39 } luaY:new_localvar
40 luaY:testnext (table,',') {
41 } luaY:testnext = false
42 luaY:testnext (table,'=') {
43 luaY:next (table) {
44 luaX:lex (table,table) {
45 } luaX:lex = 'TK_NUMBER'
46 } luaY:next
47 } luaY:testnext = true
48 luaY:explist1 (table,table) {
49 luaY:expr (table,table) {
50 luaY:subexpr (table,table,-1) {
51 luaY:enterlevel (table) {
52 } luaY:enterlevel
53 luaY:getunopr ('TK_NUMBER') {
54 } luaY:getunopr = 'OPR_NOUNOPR'
55 luaY:simpleexp (table,table) {
56 luaK:numberK (table,1) {
57 luaK:setnvalue (table,1) {
58 } luaK:setnvalue
59 luaK:addk (table,table,table) {
60 luaK:ttisnumber ) {
61 } luaK:ttisnumber = false
62 luaY:growvector (table,table,0,0) {
63 } luaY:growvector
64 luaK:setnvalue (table,0) {
65 } luaK:setnvalue
66 } luaK:addk = 0
67 } luaK:numberK = 0
68 luaY:init_exp (table,'VK',0) {
69 } luaY:init_exp
70 luaY:next (table) {
71 luaX:lex (table,table) {
72 } luaX:lex = 'TK_EOS'
73 } luaY:next
74 } luaY:simpleexp
75 luaY:getbinopr ('TK_EOS') {
76 } luaY:getbinopr = 'OPR_NOBINOPR'
77 luaY:leavelevel (table) {
78 } luaY:leavelevel
79 } luaY:subexpr = 'OPR_NOBINOPR'
80 } luaY:expr
81 luaY:testnext (table,',') {
82 } luaY:testnext = false
83 } luaY:explist1 = 1
84 luaY:adjust_assign (table,1,1,table) {
85 luaK:exp2nextreg (table,table) {
86 luaK:dischargevars (table,table) {
87 } luaK:dischargevars
88 luaK:freeexp (table,table) {
89 } luaK:freeexp
90 luaK:reserveregs (table,1) {
91 luaK:checkstack (table,1) {
92 } luaK:checkstack
93 } luaK:reserveregs
94 luaK:exp2reg (table,table,0) {
95 luaK:discharge2reg (table,table,0) {
96 luaK:dischargevars (table,table) {
97 } luaK:dischargevars
98 luaK:codeABx (table,'OP_LOADK',0,0) {
99 luaK:code (table,table,1) {
100 luaK:dischargejpc (table) {
101 luaK:patchlistaux (table,-1,0,255,0,255,0) {
102 } luaK:patchlistaux
103 } luaK:dischargejpc
104 luaY:growvector (table,table,0,0) {
105 } luaY:growvector
106 luaY:growvector (table,table,0,0) {
107 } luaY:growvector
108 } luaK:code = 0
109 } luaK:codeABx = 0
110 } luaK:discharge2reg
111 luaK:hasjumps (table) {
112 } luaK:hasjumps = false
113 } luaK:exp2reg
114 } luaK:exp2nextreg
115 } luaY:adjust_assign
116 luaY:adjustlocalvars (table,1) {
117 luaY:getlocvar (table,0) {
118 } luaY:getlocvar = table
119 } luaY:adjustlocalvars
120 } luaY:localstat
121 } luaY:statement = false
122 luaY:testnext (table,';') {
123 } luaY:testnext = false
124 luaY:block_follow ('TK_EOS') {
125 } luaY:block_follow = true
126 luaY:leavelevel (table) {
127 } luaY:leavelevel
128 } luaY:chunk
129 luaY:check_condition (table,true,'<eof> expected') {
130 } luaY:check_condition
131 luaY:close_func (table) {
132 luaY:removevars (table,0) {
133 luaY:getlocvar (table,0) {
134 } luaY:getlocvar = table
135 } luaY:removevars
136 luaK:codeABC (table,'OP_RETURN',0,1,0) {
137 luaK:code (table,table,1) {
138 luaK:dischargejpc (table) {
139 luaK:patchlistaux (table,-1,1,255,1,255,1) {
140 } luaK:patchlistaux
141 } luaK:dischargejpc
142 luaY:growvector (table,table,1,0) {
143 } luaY:growvector
144 luaY:growvector (table,table,1,0) {
145 } luaY:growvector
146 } luaK:code = 1
147 } luaK:codeABC = 1
148 } luaY:close_func
149} luaY:parser = table
150
151-- end of log --
152
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua
deleted file mode 100644
index 519cd4c..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/tools/sample_expr.lua
+++ /dev/null
@@ -1,195 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 sample_expr.lua
4 Stand-alone expression parsing demonstrator.
5 This file is part of Yueliang.
6
7 Copyright (c) 2005 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-- * this is an interactive demonstrator for implementing expression
18-- parsing in ChunkBake, a Lua assembler
19-- * evaluation is immediate, and a result is immediately generated
20----------------------------------------------------------------------]]
21
22require("../lzio.lua")
23require("../llex.lua")
24luaX:init()
25
26------------------------------------------------------------------------
27-- expression parser
28------------------------------------------------------------------------
29
30expr = {}
31
32expr.unop = {
33 ["TK_NOT"] = true,
34 ["-"] = true,
35}
36expr.binop = {
37 ["^"] = 10,
38 ["*"] = 7,
39 ["/"] = 7,
40 ["+"] = 6,
41 ["-"] = 6,
42 ["TK_CONCAT"] = 5,
43 ["TK_NE"] = 3,
44 ["TK_EQ"] = 3,
45 ["<"] = 3,
46 ["TK_LE"] = 3,
47 [">"] = 3,
48 ["TK_GE"] = 3,
49 ["TK_AND"] = 2,
50 ["TK_OR"] = 1,
51}
52expr.binop_r = {
53 ["^"] = 9,
54 ["*"] = 7,
55 ["/"] = 7,
56 ["+"] = 6,
57 ["-"] = 6,
58 ["TK_CONCAT"] = 4,
59 ["TK_NE"] = 3,
60 ["TK_EQ"] = 3,
61 ["<"] = 3,
62 ["TK_LE"] = 3,
63 [">"] = 3,
64 ["TK_GE"] = 3,
65 ["TK_AND"] = 2,
66 ["TK_OR"] = 1,
67}
68
69function expr:parse(str)
70 self.LS = {}
71 self.L = {}
72 self.z = luaZ:init(luaZ:make_getS(str), nil, "=string")
73 luaX:setinput(self.L, self.LS, self.z, self.z.name)
74 self:token()
75 local v = self:expr()
76 if self.tok ~= "TK_EOS" then
77 io.stderr:write("parse error: some tokens unparsed\n")
78 end
79 return v
80end
81
82function expr:token()
83 self.tok = luaX:lex(self.LS, self.LS.t)
84 self.seminfo = self.LS.t.seminfo
85 return self.tok
86end
87
88function expr:simpleexpr()
89 local tok = self.tok
90 if tok == "TK_NIL" then
91 self:token()
92 return nil
93 elseif tok == "TK_TRUE" then
94 self:token()
95 return true
96 elseif tok == "TK_FALSE" then
97 self:token()
98 return false
99 elseif tok == "TK_NUMBER" or tok == "TK_STRING" then
100 self:token()
101 return self.seminfo
102 elseif tok == "(" then
103 self:token()
104 local v = self:expr()
105 if self.tok ~= ")" then
106 io.stderr:write("parse error: expecting ')' to delimit\n")
107 else
108 self:token()
109 return v
110 end
111 end
112 self:token()
113 io.stderr:write("parse error: "..tok.." encountered, substituting nil\n")
114 return nil
115end
116
117function expr:subexpr(prev_op)
118 local v, op
119 if self.unop[self.tok] then
120 op = self.tok
121 self:token()
122 v = self:subexpr(8)
123 if op == "TK_NOT" then
124 v = not v
125 else-- op == "-" then
126 v = -v
127 end
128 else
129 v = self:simpleexpr()
130 end
131 op = self.tok
132 if self.binop[op] then
133 while self.binop[op] and self.binop[op] > prev_op do
134 self:token()
135 local v2, next_op = self:subexpr(self.binop_r[op])
136 if op == "^" then
137 v = v ^ v2
138 elseif op == "*" then
139 v = v * v2
140 elseif op == "/" then
141 v = v / v2
142 elseif op == "+" then
143 v = v + v2
144 elseif op == "-" then
145 v = v - v2
146 elseif op == "TK_CONCAT" then
147 v = v .. v2
148 elseif op == "TK_NE" then
149 v = v ~= v2
150 elseif op == "TK_EQ" then
151 v = v == v2
152 elseif op == "<" then
153 v = v < v2
154 elseif op == "TK_LE" then
155 v = v <= v2
156 elseif op == ">" then
157 v = v > v2
158 elseif op == "TK_GE" then
159 v = v >= v2
160 elseif op == "TK_AND" then
161 v = v and v2
162 else-- op == "TK_OR" then
163 v = v or v2
164 end
165 op = next_op
166 end
167 end
168 return v, op
169end
170
171function expr:expr()
172 return self:subexpr(-1)
173end
174
175------------------------------------------------------------------------
176-- interactive test code
177------------------------------------------------------------------------
178
179io.stdout:write([[
180Lua-style expression parsing demonstrator.
181Type 'exit' or 'quit' at the prompt to terminate session.
182]])
183local done = false
184while not done do
185 io.stdout:write(":>")
186 io.stdout:flush()
187 local l = io.stdin:read("*l")
188 if l == nil or (l == "exit" or l == "quit" and not prevline) then
189 done = true
190 else
191 local v = tostring(expr:parse(l))
192 io.stdout:write(v, "\n")
193 end
194end--while
195--end