aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua')
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua1747
1 files changed, 0 insertions, 1747 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua
deleted file mode 100644
index 2535056..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/orig-5.1.3/lparser.lua
+++ /dev/null
@@ -1,1747 +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-2007 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * some unused C code that were not converted are kept as comments
18-- * LUA_COMPAT_VARARG option changed into a comment block
19-- * for value/size specific code added, look for 'NOTE: '
20--
21-- Not implemented:
22-- * luaX_newstring not needed by this Lua implementation
23-- * luaG_checkcode() in lua_assert is not currently implemented
24--
25-- Added:
26-- * some constants added from various header files
27-- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h)
28-- * luaY:LUA_QL needed for error messages (from luaconf.h)
29-- * luaY:growvector (from lmem.h) -- skeleton only, limit checking
30-- * luaY.SHRT_MAX (from <limits.h>) for registerlocalvar
31-- * luaY:newproto (from lfunc.c)
32-- * luaY:int2fb (from lobject.c)
33-- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation
34-- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop
35--
36-- Changed in 5.1.x:
37-- * various code changes are not detailed...
38-- * names of constants may have changed, e.g. added a LUAI_ prefix
39-- * struct expkind: added VKNUM, VVARARG; VCALL's info changed?
40-- * struct expdesc: added nval
41-- * struct FuncState: upvalues data type changed to upvaldesc
42-- * macro hasmultret is new
43-- * function checklimit moved to parser from lexer
44-- * functions anchor_token, errorlimit, checknext are new
45-- * checknext is new, equivalent to 5.0.x's check, see check too
46-- * luaY:next and luaY:lookahead moved to lexer
47-- * break keyword no longer skipped in luaY:breakstat
48-- * function new_localvarstr replaced by new_localvarliteral
49-- * registerlocalvar limits local variables to SHRT_MAX
50-- * create_local deleted, new_localvarliteral used instead
51-- * constant LUAI_MAXUPVALUES increased to 60
52-- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed
53-- * function interface changed: singlevaraux, singlevar
54-- * enterlevel and leavelevel uses nCcalls to track call depth
55-- * added a name argument to main entry function, luaY:parser
56-- * function luaY_index changed to yindex
57-- * luaY:int2fb()'s table size encoding format has been changed
58-- * luaY:log2() no longer needed for table constructors
59-- * function code_params deleted, functionality folded in parlist
60-- * vararg flags handling (is_vararg) changes; also see VARARG_*
61-- * LUA_COMPATUPSYNTAX section for old-style upvalues removed
62-- * repeatstat() calls chunk() instead of block()
63-- * function interface changed: cond, test_then_block
64-- * while statement implementation considerably simplified; MAXEXPWHILE
65-- and EXTRAEXP no longer required, no limits to the complexity of a
66-- while condition
67-- * repeat, forbody statement implementation has major changes,
68-- mostly due to new scoping behaviour of local variables
69-- * OPR_MULT renamed to OPR_MUL
70----------------------------------------------------------------------]]
71
72--requires luaP, luaX, luaK
73luaY = {}
74
75--[[--------------------------------------------------------------------
76-- Expression descriptor
77-- * expkind changed to string constants; luaY:assignment was the only
78-- function to use a relational operator with this enumeration
79-- VVOID -- no value
80-- VNIL -- no value
81-- VTRUE -- no value
82-- VFALSE -- no value
83-- VK -- info = index of constant in 'k'
84-- VKNUM -- nval = numerical value
85-- VLOCAL -- info = local register
86-- VUPVAL, -- info = index of upvalue in 'upvalues'
87-- VGLOBAL -- info = index of table; aux = index of global name in 'k'
88-- VINDEXED -- info = table register; aux = index register (or 'k')
89-- VJMP -- info = instruction pc
90-- VRELOCABLE -- info = instruction pc
91-- VNONRELOC -- info = result register
92-- VCALL -- info = instruction pc
93-- VVARARG -- info = instruction pc
94} ----------------------------------------------------------------------]]
95
96--[[--------------------------------------------------------------------
97-- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
98-- implementation ignores all instances of u and s usage
99-- struct expdesc:
100-- k -- (enum: expkind)
101-- info, aux -- (int, int)
102-- nval -- (lua_Number)
103-- t -- patch list of 'exit when true'
104-- f -- patch list of 'exit when false'
105----------------------------------------------------------------------]]
106
107--[[--------------------------------------------------------------------
108-- struct upvaldesc:
109-- k -- (lu_byte)
110-- info -- (lu_byte)
111----------------------------------------------------------------------]]
112
113--[[--------------------------------------------------------------------
114-- state needed to generate code for a given function
115-- struct FuncState:
116-- f -- current function header (table: Proto)
117-- h -- table to find (and reuse) elements in 'k' (table: Table)
118-- prev -- enclosing function (table: FuncState)
119-- ls -- lexical state (table: LexState)
120-- L -- copy of the Lua state (table: lua_State)
121-- bl -- chain of current blocks (table: BlockCnt)
122-- pc -- next position to code (equivalent to 'ncode')
123-- lasttarget -- 'pc' of last 'jump target'
124-- jpc -- list of pending jumps to 'pc'
125-- freereg -- first free register
126-- nk -- number of elements in 'k'
127-- np -- number of elements in 'p'
128-- nlocvars -- number of elements in 'locvars'
129-- nactvar -- number of active local variables
130-- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc)
131-- actvar[LUAI_MAXVARS] -- declared-variable stack
132----------------------------------------------------------------------]]
133
134------------------------------------------------------------------------
135-- constants used by parser
136-- * picks up duplicate values from luaX if required
137------------------------------------------------------------------------
138luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h)
139
140luaY.SHRT_MAX = 32767 -- (from <limits.h>)
141luaY.LUAI_MAXVARS = 200 -- (luaconf.h)
142luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h)
143luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h)
144 -- * INT_MAX-2 for 32-bit systems
145luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h)
146
147luaY.VARARG_HASARG = 1 -- (from lobject.h)
148-- NOTE: HASARG_MASK is value-specific
149luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
150luaY.VARARG_ISVARARG = 2
151-- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
152luaY.VARARG_NEEDSARG = 4
153
154luaY.LUA_MULTRET = -1 -- (lua.h)
155
156--[[--------------------------------------------------------------------
157-- other functions
158----------------------------------------------------------------------]]
159
160------------------------------------------------------------------------
161-- LUA_QL describes how error messages quote program elements.
162-- CHANGE it if you want a different appearance. (from luaconf.h)
163------------------------------------------------------------------------
164function luaY:LUA_QL(x)
165 return "'"..x.."'"
166end
167
168------------------------------------------------------------------------
169-- this is a stripped-down luaM_growvector (from lmem.h) which is a
170-- macro based on luaM_growaux (in lmem.c); all the following does is
171-- reproduce the size limit checking logic of the original function
172-- so that error behaviour is identical; all arguments preserved for
173-- convenience, even those which are unused
174-- * set the t field to nil, since this originally does a sizeof(t)
175-- * size (originally a pointer) is never updated, their final values
176-- are set by luaY:close_func(), so overall things should still work
177------------------------------------------------------------------------
178function luaY:growvector(L, v, nelems, size, t, limit, e)
179 if nelems >= limit then
180 error(e) -- was luaG_runerror
181 end
182end
183
184------------------------------------------------------------------------
185-- initialize a new function prototype structure (from lfunc.c)
186-- * used only in open_func()
187------------------------------------------------------------------------
188function luaY:newproto(L)
189 local f = {} -- Proto
190 -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
191 f.k = {}
192 f.sizek = 0
193 f.p = {}
194 f.sizep = 0
195 f.code = {}
196 f.sizecode = 0
197 f.sizelineinfo = 0
198 f.sizeupvalues = 0
199 f.nups = 0
200 f.upvalues = {}
201 f.numparams = 0
202 f.is_vararg = 0
203 f.maxstacksize = 0
204 f.lineinfo = {}
205 f.sizelocvars = 0
206 f.locvars = {}
207 f.lineDefined = 0
208 f.lastlinedefined = 0
209 f.source = nil
210 return f
211end
212
213------------------------------------------------------------------------
214-- converts an integer to a "floating point byte", represented as
215-- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
216-- eeeee != 0 and (xxx) otherwise.
217------------------------------------------------------------------------
218function luaY:int2fb(x)
219 local e = 0 -- exponent
220 while x >= 16 do
221 x = math.floor((x + 1) / 2)
222 e = e + 1
223 end
224 if x < 8 then
225 return x
226 else
227 return ((e + 1) * 8) + (x - 8)
228 end
229end
230
231--[[--------------------------------------------------------------------
232-- parser functions
233----------------------------------------------------------------------]]
234
235------------------------------------------------------------------------
236-- true of the kind of expression produces multiple return values
237------------------------------------------------------------------------
238function luaY:hasmultret(k)
239 return k == "VCALL" or k == "VVARARG"
240end
241
242------------------------------------------------------------------------
243-- convenience function to access active local i, returns entry
244------------------------------------------------------------------------
245function luaY:getlocvar(fs, i)
246 return fs.f.locvars[ fs.actvar[i] ]
247end
248
249------------------------------------------------------------------------
250-- check a limit, string m provided as an error message
251------------------------------------------------------------------------
252function luaY:checklimit(fs, v, l, m)
253 if v > l then self:errorlimit(fs, l, m) end
254end
255
256--[[--------------------------------------------------------------------
257-- nodes for block list (list of active blocks)
258-- struct BlockCnt:
259-- previous -- chain (table: BlockCnt)
260-- breaklist -- list of jumps out of this loop
261-- nactvar -- # active local variables outside the breakable structure
262-- upval -- true if some variable in the block is an upvalue (boolean)
263-- isbreakable -- true if 'block' is a loop (boolean)
264----------------------------------------------------------------------]]
265
266------------------------------------------------------------------------
267-- prototypes for recursive non-terminal functions
268------------------------------------------------------------------------
269-- prototypes deleted; not required in Lua
270
271------------------------------------------------------------------------
272-- reanchor if last token is has a constant string, see close_func()
273-- * used only in close_func()
274------------------------------------------------------------------------
275function luaY:anchor_token(ls)
276 if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
277 -- not relevant to Lua implementation of parser
278 -- local ts = ls.t.seminfo
279 -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
280 end
281end
282
283------------------------------------------------------------------------
284-- throws a syntax error if token expected is not there
285------------------------------------------------------------------------
286function luaY:error_expected(ls, token)
287 luaX:syntaxerror(ls,
288 string.format(self.LUA_QS.." expected", luaX:token2str(ls, token)))
289end
290
291------------------------------------------------------------------------
292-- prepares error message for display, for limits exceeded
293-- * used only in checklimit()
294------------------------------------------------------------------------
295function luaY:errorlimit(fs, limit, what)
296 local msg = (fs.f.linedefined == 0) and
297 string.format("main function has more than %d %s", limit, what) or
298 string.format("function at line %d has more than %d %s",
299 fs.f.linedefined, limit, what)
300 luaX:lexerror(fs.ls, msg, 0)
301end
302
303------------------------------------------------------------------------
304-- tests for a token, returns outcome
305-- * return value changed to boolean
306------------------------------------------------------------------------
307function luaY:testnext(ls, c)
308 if ls.t.token == c then
309 luaX:next(ls)
310 return true
311 else
312 return false
313 end
314end
315
316------------------------------------------------------------------------
317-- check for existence of a token, throws error if not found
318------------------------------------------------------------------------
319function luaY:check(ls, c)
320 if ls.t.token ~= c then
321 self:error_expected(ls, c)
322 end
323end
324
325------------------------------------------------------------------------
326-- verify existence of a token, then skip it
327------------------------------------------------------------------------
328function luaY:checknext(ls, c)
329 self:check(ls, c)
330 luaX:next(ls)
331end
332
333------------------------------------------------------------------------
334-- throws error if condition not matched
335------------------------------------------------------------------------
336function luaY:check_condition(ls, c, msg)
337 if not c then luaX:syntaxerror(ls, msg) end
338end
339
340------------------------------------------------------------------------
341-- verifies token conditions are met or else throw error
342------------------------------------------------------------------------
343function luaY:check_match(ls, what, who, where)
344 if not self:testnext(ls, what) then
345 if where == ls.linenumber then
346 self:error_expected(ls, what)
347 else
348 luaX:syntaxerror(ls, string.format(
349 self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)",
350 luaX:token2str(ls, what), luaX:token2str(ls, who), where))
351 end
352 end
353end
354
355------------------------------------------------------------------------
356-- expect that token is a name, return the name
357------------------------------------------------------------------------
358function luaY:str_checkname(ls)
359 self:check(ls, "TK_NAME")
360 local ts = ls.t.seminfo
361 luaX:next(ls)
362 return ts
363end
364
365------------------------------------------------------------------------
366-- initialize a struct expdesc, expression description data structure
367------------------------------------------------------------------------
368function luaY:init_exp(e, k, i)
369 e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
370 e.k = k
371 e.info = i
372end
373
374------------------------------------------------------------------------
375-- adds given string s in string pool, sets e as VK
376------------------------------------------------------------------------
377function luaY:codestring(ls, e, s)
378 self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
379end
380
381------------------------------------------------------------------------
382-- consume a name token, adds it to string pool, sets e as VK
383------------------------------------------------------------------------
384function luaY:checkname(ls, e)
385 self:codestring(ls, e, self:str_checkname(ls))
386end
387
388------------------------------------------------------------------------
389-- creates struct entry for a local variable
390-- * used only in new_localvar()
391------------------------------------------------------------------------
392function luaY:registerlocalvar(ls, varname)
393 local fs = ls.fs
394 local f = fs.f
395 self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
396 nil, self.SHRT_MAX, "too many local variables")
397 -- loop to initialize empty f.locvar positions not required
398 f.locvars[fs.nlocvars] = {} -- LocVar
399 f.locvars[fs.nlocvars].varname = varname
400 -- luaC_objbarrier(ls.L, f, varname) /* GC */
401 local nlocvars = fs.nlocvars
402 fs.nlocvars = fs.nlocvars + 1
403 return nlocvars
404end
405
406------------------------------------------------------------------------
407-- creates a new local variable given a name and an offset from nactvar
408-- * used in fornum(), forlist(), parlist(), body()
409------------------------------------------------------------------------
410function luaY:new_localvarliteral(ls, v, n)
411 self:new_localvar(ls, v, n)
412end
413
414------------------------------------------------------------------------
415-- register a local variable, set in active variable list
416------------------------------------------------------------------------
417function luaY:new_localvar(ls, name, n)
418 local fs = ls.fs
419 self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
420 fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
421end
422
423------------------------------------------------------------------------
424-- adds nvars number of new local variables, set debug information
425------------------------------------------------------------------------
426function luaY:adjustlocalvars(ls, nvars)
427 local fs = ls.fs
428 fs.nactvar = fs.nactvar + nvars
429 for i = nvars, 1, -1 do
430 self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
431 end
432end
433
434------------------------------------------------------------------------
435-- removes a number of locals, set debug information
436------------------------------------------------------------------------
437function luaY:removevars(ls, tolevel)
438 local fs = ls.fs
439 while fs.nactvar > tolevel do
440 fs.nactvar = fs.nactvar - 1
441 self:getlocvar(fs, fs.nactvar).endpc = fs.pc
442 end
443end
444
445------------------------------------------------------------------------
446-- returns an existing upvalue index based on the given name, or
447-- creates a new upvalue struct entry and returns the new index
448-- * used only in singlevaraux()
449------------------------------------------------------------------------
450function luaY:indexupvalue(fs, name, v)
451 local f = fs.f
452 for i = 0, f.nups - 1 do
453 if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
454 lua_assert(f.upvalues[i] == name)
455 return i
456 end
457 end
458 -- new one
459 self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
460 self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues,
461 nil, self.MAX_INT, "")
462 -- loop to initialize empty f.upvalues positions not required
463 f.upvalues[f.nups] = name
464 -- luaC_objbarrier(fs->L, f, name); /* GC */
465 lua_assert(v.k == "VLOCAL" or v.k == "VUPVAL")
466 -- this is a partial copy; only k & info fields used
467 fs.upvalues[f.nups] = { k = v.k, info = v.info }
468 local nups = f.nups
469 f.nups = f.nups + 1
470 return nups
471end
472
473------------------------------------------------------------------------
474-- search the local variable namespace of the given fs for a match
475-- * used only in singlevaraux()
476------------------------------------------------------------------------
477function luaY:searchvar(fs, n)
478 for i = fs.nactvar - 1, 0, -1 do
479 if n == self:getlocvar(fs, i).varname then
480 return i
481 end
482 end
483 return -1 -- not found
484end
485
486------------------------------------------------------------------------
487-- * mark upvalue flags in function states up to a given level
488-- * used only in singlevaraux()
489------------------------------------------------------------------------
490function luaY:markupval(fs, level)
491 local bl = fs.bl
492 while bl and bl.nactvar > level do bl = bl.previous end
493 if bl then bl.upval = true end
494end
495
496------------------------------------------------------------------------
497-- handle locals, globals and upvalues and related processing
498-- * search mechanism is recursive, calls itself to search parents
499-- * used only in singlevar()
500------------------------------------------------------------------------
501function luaY:singlevaraux(fs, n, var, base)
502 if fs == nil then -- no more levels?
503 self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
504 return "VGLOBAL"
505 else
506 local v = self:searchvar(fs, n) -- look up at current level
507 if v >= 0 then
508 self:init_exp(var, "VLOCAL", v)
509 if base == 0 then
510 self:markupval(fs, v) -- local will be used as an upval
511 end
512 return "VLOCAL"
513 else -- not found at current level; try upper one
514 if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
515 return "VGLOBAL"
516 end
517 var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL
518 var.k = "VUPVAL" -- upvalue in this level
519 return "VUPVAL"
520 end--if v
521 end--if fs
522end
523
524------------------------------------------------------------------------
525-- consume a name token, creates a variable (global|local|upvalue)
526-- * used in prefixexp(), funcname()
527------------------------------------------------------------------------
528function luaY:singlevar(ls, var)
529 local varname = self:str_checkname(ls)
530 local fs = ls.fs
531 if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
532 var.info = luaK:stringK(fs, varname) -- info points to global name
533 end
534end
535
536------------------------------------------------------------------------
537-- adjust RHS to match LHS in an assignment
538-- * used in assignment(), forlist(), localstat()
539------------------------------------------------------------------------
540function luaY:adjust_assign(ls, nvars, nexps, e)
541 local fs = ls.fs
542 local extra = nvars - nexps
543 if self:hasmultret(e.k) then
544 extra = extra + 1 -- includes call itself
545 if extra <= 0 then extra = 0 end
546 luaK:setreturns(fs, e, extra) -- last exp. provides the difference
547 if extra > 1 then luaK:reserveregs(fs, extra - 1) end
548 else
549 if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression
550 if extra > 0 then
551 local reg = fs.freereg
552 luaK:reserveregs(fs, extra)
553 luaK:_nil(fs, reg, extra)
554 end
555 end
556end
557
558------------------------------------------------------------------------
559-- tracks and limits parsing depth, assert check at end of parsing
560------------------------------------------------------------------------
561function luaY:enterlevel(ls)
562 ls.L.nCcalls = ls.L.nCcalls + 1
563 if ls.L.nCcalls > self.LUAI_MAXCCALLS then
564 luaX:lexerror(ls, "chunk has too many syntax levels", 0)
565 end
566end
567
568------------------------------------------------------------------------
569-- tracks parsing depth, a pair with luaY:enterlevel()
570------------------------------------------------------------------------
571function luaY:leavelevel(ls)
572 ls.L.nCcalls = ls.L.nCcalls - 1
573end
574
575------------------------------------------------------------------------
576-- enters a code unit, initializes elements
577------------------------------------------------------------------------
578function luaY:enterblock(fs, bl, isbreakable)
579 bl.breaklist = luaK.NO_JUMP
580 bl.isbreakable = isbreakable
581 bl.nactvar = fs.nactvar
582 bl.upval = false
583 bl.previous = fs.bl
584 fs.bl = bl
585 lua_assert(fs.freereg == fs.nactvar)
586end
587
588------------------------------------------------------------------------
589-- leaves a code unit, close any upvalues
590------------------------------------------------------------------------
591function luaY:leaveblock(fs)
592 local bl = fs.bl
593 fs.bl = bl.previous
594 self:removevars(fs.ls, bl.nactvar)
595 if bl.upval then
596 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
597 end
598 -- a block either controls scope or breaks (never both)
599 lua_assert(not bl.isbreakable or not bl.upval)
600 lua_assert(bl.nactvar == fs.nactvar)
601 fs.freereg = fs.nactvar -- free registers
602 luaK:patchtohere(fs, bl.breaklist)
603end
604
605------------------------------------------------------------------------
606-- implement the instantiation of a function prototype, append list of
607-- upvalues after the instantiation instruction
608-- * used only in body()
609------------------------------------------------------------------------
610function luaY:pushclosure(ls, func, v)
611 local fs = ls.fs
612 local f = fs.f
613 self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
614 luaP.MAXARG_Bx, "constant table overflow")
615 -- loop to initialize empty f.p positions not required
616 f.p[fs.np] = func.f
617 fs.np = fs.np + 1
618 -- luaC_objbarrier(ls->L, f, func->f); /* C */
619 self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
620 for i = 0, func.f.nups - 1 do
621 local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
622 luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
623 end
624end
625
626------------------------------------------------------------------------
627-- opening of a function
628------------------------------------------------------------------------
629function luaY:open_func(ls, fs)
630 local L = ls.L
631 local f = self:newproto(ls.L)
632 fs.f = f
633 fs.prev = ls.fs -- linked list of funcstates
634 fs.ls = ls
635 fs.L = L
636 ls.fs = fs
637 fs.pc = 0
638 fs.lasttarget = -1
639 fs.jpc = luaK.NO_JUMP
640 fs.freereg = 0
641 fs.nk = 0
642 fs.np = 0
643 fs.nlocvars = 0
644 fs.nactvar = 0
645 fs.bl = nil
646 f.source = ls.source
647 f.maxstacksize = 2 -- registers 0/1 are always valid
648 fs.h = {} -- constant table; was luaH_new call
649 -- anchor table of constants and prototype (to avoid being collected)
650 -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
651 -- setptvalue2s(L, L->top, f); incr_top(L);
652end
653
654------------------------------------------------------------------------
655-- closing of a function
656------------------------------------------------------------------------
657function luaY:close_func(ls)
658 local L = ls.L
659 local fs = ls.fs
660 local f = fs.f
661 self:removevars(ls, 0)
662 luaK:ret(fs, 0, 0) -- final return
663 -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
664 -- f->locvars, f->upvalues; not required for Lua table arrays
665 f.sizecode = fs.pc
666 f.sizelineinfo = fs.pc
667 f.sizek = fs.nk
668 f.sizep = fs.np
669 f.sizelocvars = fs.nlocvars
670 f.sizeupvalues = f.nups
671 --lua_assert(luaG_checkcode(f)) -- currently not implemented
672 lua_assert(fs.bl == nil)
673 ls.fs = fs.prev
674 -- the following is not required for this implementation; kept here
675 -- for completeness
676 -- L->top -= 2; /* remove table and prototype from the stack */
677 -- last token read was anchored in defunct function; must reanchor it
678 if fs then self:anchor_token(ls) end
679end
680
681------------------------------------------------------------------------
682-- parser initialization function
683-- * note additional sub-tables needed for LexState, FuncState
684------------------------------------------------------------------------
685function luaY:parser(L, z, buff, name)
686 local lexstate = {} -- LexState
687 lexstate.t = {}
688 lexstate.lookahead = {}
689 local funcstate = {} -- FuncState
690 funcstate.upvalues = {}
691 funcstate.actvar = {}
692 -- the following nCcalls initialization added for convenience
693 L.nCcalls = 0
694 lexstate.buff = buff
695 luaX:setinput(L, lexstate, z, name)
696 self:open_func(lexstate, funcstate)
697 funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg
698 luaX:next(lexstate) -- read first token
699 self:chunk(lexstate)
700 self:check(lexstate, "TK_EOS")
701 self:close_func(lexstate)
702 lua_assert(funcstate.prev == nil)
703 lua_assert(funcstate.f.nups == 0)
704 lua_assert(lexstate.fs == nil)
705 return funcstate.f
706end
707
708--[[--------------------------------------------------------------------
709-- GRAMMAR RULES
710----------------------------------------------------------------------]]
711
712------------------------------------------------------------------------
713-- parse a function name suffix, for function call specifications
714-- * used in primaryexp(), funcname()
715------------------------------------------------------------------------
716function luaY:field(ls, v)
717 -- field -> ['.' | ':'] NAME
718 local fs = ls.fs
719 local key = {} -- expdesc
720 luaK:exp2anyreg(fs, v)
721 luaX:next(ls) -- skip the dot or colon
722 self:checkname(ls, key)
723 luaK:indexed(fs, v, key)
724end
725
726------------------------------------------------------------------------
727-- parse a table indexing suffix, for constructors, expressions
728-- * used in recfield(), primaryexp()
729------------------------------------------------------------------------
730function luaY:yindex(ls, v)
731 -- index -> '[' expr ']'
732 luaX:next(ls) -- skip the '['
733 self:expr(ls, v)
734 luaK:exp2val(ls.fs, v)
735 self:checknext(ls, "]")
736end
737
738--[[--------------------------------------------------------------------
739-- Rules for Constructors
740----------------------------------------------------------------------]]
741
742--[[--------------------------------------------------------------------
743-- struct ConsControl:
744-- v -- last list item read (table: struct expdesc)
745-- t -- table descriptor (table: struct expdesc)
746-- nh -- total number of 'record' elements
747-- na -- total number of array elements
748-- tostore -- number of array elements pending to be stored
749----------------------------------------------------------------------]]
750
751------------------------------------------------------------------------
752-- parse a table record (hash) field
753-- * used in constructor()
754------------------------------------------------------------------------
755function luaY:recfield(ls, cc)
756 -- recfield -> (NAME | '['exp1']') = exp1
757 local fs = ls.fs
758 local reg = ls.fs.freereg
759 local key, val = {}, {} -- expdesc
760 if ls.t.token == "TK_NAME" then
761 self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
762 self:checkname(ls, key)
763 else -- ls->t.token == '['
764 self:yindex(ls, key)
765 end
766 cc.nh = cc.nh + 1
767 self:checknext(ls, "=")
768 local rkkey = luaK:exp2RK(fs, key)
769 self:expr(ls, val)
770 luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
771 fs.freereg = reg -- free registers
772end
773
774------------------------------------------------------------------------
775-- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
776-- * used in constructor()
777------------------------------------------------------------------------
778function luaY:closelistfield(fs, cc)
779 if cc.v.k == "VVOID" then return end -- there is no list item
780 luaK:exp2nextreg(fs, cc.v)
781 cc.v.k = "VVOID"
782 if cc.tostore == luaP.LFIELDS_PER_FLUSH then
783 luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush
784 cc.tostore = 0 -- no more items pending
785 end
786end
787
788------------------------------------------------------------------------
789-- emit a set list instruction at the end of parsing list constructor
790-- * used in constructor()
791------------------------------------------------------------------------
792function luaY:lastlistfield(fs, cc)
793 if cc.tostore == 0 then return end
794 if self:hasmultret(cc.v.k) then
795 luaK:setmultret(fs, cc.v)
796 luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
797 cc.na = cc.na - 1 -- do not count last expression (unknown number of elements)
798 else
799 if cc.v.k ~= "VVOID" then
800 luaK:exp2nextreg(fs, cc.v)
801 end
802 luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
803 end
804end
805
806------------------------------------------------------------------------
807-- parse a table list (array) field
808-- * used in constructor()
809------------------------------------------------------------------------
810function luaY:listfield(ls, cc)
811 self:expr(ls, cc.v)
812 self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
813 cc.na = cc.na + 1
814 cc.tostore = cc.tostore + 1
815end
816
817------------------------------------------------------------------------
818-- parse a table constructor
819-- * used in funcargs(), simpleexp()
820------------------------------------------------------------------------
821function luaY:constructor(ls, t)
822 -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
823 -- field -> recfield | listfield
824 -- fieldsep -> ',' | ';'
825 local fs = ls.fs
826 local line = ls.linenumber
827 local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
828 local cc = {} -- ConsControl
829 cc.v = {}
830 cc.na, cc.nh, cc.tostore = 0, 0, 0
831 cc.t = t
832 self:init_exp(t, "VRELOCABLE", pc)
833 self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
834 luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
835 self:checknext(ls, "{")
836 repeat
837 lua_assert(cc.v.k == "VVOID" or cc.tostore > 0)
838 if ls.t.token == "}" then break end
839 self:closelistfield(fs, cc)
840 local c = ls.t.token
841
842 if c == "TK_NAME" then -- may be listfields or recfields
843 luaX:lookahead(ls)
844 if ls.lookahead.token ~= "=" then -- expression?
845 self:listfield(ls, cc)
846 else
847 self:recfield(ls, cc)
848 end
849 elseif c == "[" then -- constructor_item -> recfield
850 self:recfield(ls, cc)
851 else -- constructor_part -> listfield
852 self:listfield(ls, cc)
853 end
854 until not self:testnext(ls, ",") and not self:testnext(ls, ";")
855 self:check_match(ls, "}", "{", line)
856 self:lastlistfield(fs, cc)
857 luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
858 luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
859end
860
861-- }======================================================================
862
863------------------------------------------------------------------------
864-- parse the arguments (parameters) of a function declaration
865-- * used in body()
866------------------------------------------------------------------------
867function luaY:parlist(ls)
868 -- parlist -> [ param { ',' param } ]
869 local fs = ls.fs
870 local f = fs.f
871 local nparams = 0
872 f.is_vararg = 0
873 if ls.t.token ~= ")" then -- is 'parlist' not empty?
874 repeat
875 local c = ls.t.token
876 if c == "TK_NAME" then -- param -> NAME
877 self:new_localvar(ls, self:str_checkname(ls), nparams)
878 nparams = nparams + 1
879 elseif c == "TK_DOTS" then -- param -> `...'
880 luaX:next(ls)
881-- [[
882-- #if defined(LUA_COMPAT_VARARG)
883 -- use `arg' as default name
884 self:new_localvarliteral(ls, "arg", nparams)
885 nparams = nparams + 1
886 f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
887-- #endif
888--]]
889 f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
890 else
891 luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected")
892 end
893 until f.is_vararg ~= 0 or not self:testnext(ls, ",")
894 end--if
895 self:adjustlocalvars(ls, nparams)
896 -- NOTE: the following works only when HASARG_MASK is 2!
897 f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
898 luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
899end
900
901------------------------------------------------------------------------
902-- parse function declaration body
903-- * used in simpleexp(), localfunc(), funcstat()
904------------------------------------------------------------------------
905function luaY:body(ls, e, needself, line)
906 -- body -> '(' parlist ')' chunk END
907 local new_fs = {} -- FuncState
908 new_fs.upvalues = {}
909 new_fs.actvar = {}
910 self:open_func(ls, new_fs)
911 new_fs.f.lineDefined = line
912 self:checknext(ls, "(")
913 if needself then
914 self:new_localvarliteral(ls, "self", 0)
915 self:adjustlocalvars(ls, 1)
916 end
917 self:parlist(ls)
918 self:checknext(ls, ")")
919 self:chunk(ls)
920 new_fs.f.lastlinedefined = ls.linenumber
921 self:check_match(ls, "TK_END", "TK_FUNCTION", line)
922 self:close_func(ls)
923 self:pushclosure(ls, new_fs, e)
924end
925
926------------------------------------------------------------------------
927-- parse a list of comma-separated expressions
928-- * used is multiple locations
929------------------------------------------------------------------------
930function luaY:explist1(ls, v)
931 -- explist1 -> expr { ',' expr }
932 local n = 1 -- at least one expression
933 self:expr(ls, v)
934 while self:testnext(ls, ",") do
935 luaK:exp2nextreg(ls.fs, v)
936 self:expr(ls, v)
937 n = n + 1
938 end
939 return n
940end
941
942------------------------------------------------------------------------
943-- parse the parameters of a function call
944-- * contrast with parlist(), used in function declarations
945-- * used in primaryexp()
946------------------------------------------------------------------------
947function luaY:funcargs(ls, f)
948 local fs = ls.fs
949 local args = {} -- expdesc
950 local nparams
951 local line = ls.linenumber
952 local c = ls.t.token
953 if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
954 if line ~= ls.lastline then
955 luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
956 end
957 luaX:next(ls)
958 if ls.t.token == ")" then -- arg list is empty?
959 args.k = "VVOID"
960 else
961 self:explist1(ls, args)
962 luaK:setmultret(fs, args)
963 end
964 self:check_match(ls, ")", "(", line)
965 elseif c == "{" then -- funcargs -> constructor
966 self:constructor(ls, args)
967 elseif c == "TK_STRING" then -- funcargs -> STRING
968 self:codestring(ls, args, ls.t.seminfo)
969 luaX:next(ls) -- must use 'seminfo' before 'next'
970 else
971 luaX:syntaxerror(ls, "function arguments expected")
972 return
973 end
974 lua_assert(f.k == "VNONRELOC")
975 local base = f.info -- base register for call
976 if self:hasmultret(args.k) then
977 nparams = self.LUA_MULTRET -- open call
978 else
979 if args.k ~= "VVOID" then
980 luaK:exp2nextreg(fs, args) -- close last argument
981 end
982 nparams = fs.freereg - (base + 1)
983 end
984 self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
985 luaK:fixline(fs, line)
986 fs.freereg = base + 1 -- call remove function and arguments and leaves
987 -- (unless changed) one result
988end
989
990--[[--------------------------------------------------------------------
991-- Expression parsing
992----------------------------------------------------------------------]]
993
994------------------------------------------------------------------------
995-- parses an expression in parentheses or a single variable
996-- * used in primaryexp()
997------------------------------------------------------------------------
998function luaY:prefixexp(ls, v)
999 -- prefixexp -> NAME | '(' expr ')'
1000 local c = ls.t.token
1001 if c == "(" then
1002 local line = ls.linenumber
1003 luaX:next(ls)
1004 self:expr(ls, v)
1005 self:check_match(ls, ")", "(", line)
1006 luaK:dischargevars(ls.fs, v)
1007 elseif c == "TK_NAME" then
1008 self:singlevar(ls, v)
1009 else
1010 luaX:syntaxerror(ls, "unexpected symbol")
1011 end--if c
1012 return
1013end
1014
1015------------------------------------------------------------------------
1016-- parses a prefixexp (an expression in parentheses or a single variable)
1017-- or a function call specification
1018-- * used in simpleexp(), assignment(), exprstat()
1019------------------------------------------------------------------------
1020function luaY:primaryexp(ls, v)
1021 -- primaryexp ->
1022 -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
1023 local fs = ls.fs
1024 self:prefixexp(ls, v)
1025 while true do
1026 local c = ls.t.token
1027 if c == "." then -- field
1028 self:field(ls, v)
1029 elseif c == "[" then -- '[' exp1 ']'
1030 local key = {} -- expdesc
1031 luaK:exp2anyreg(fs, v)
1032 self:yindex(ls, key)
1033 luaK:indexed(fs, v, key)
1034 elseif c == ":" then -- ':' NAME funcargs
1035 local key = {} -- expdesc
1036 luaX:next(ls)
1037 self:checkname(ls, key)
1038 luaK:_self(fs, v, key)
1039 self:funcargs(ls, v)
1040 elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
1041 luaK:exp2nextreg(fs, v)
1042 self:funcargs(ls, v)
1043 else
1044 return
1045 end--if c
1046 end--while
1047end
1048
1049------------------------------------------------------------------------
1050-- parses general expression types, constants handled here
1051-- * used in subexpr()
1052------------------------------------------------------------------------
1053function luaY:simpleexp(ls, v)
1054 -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
1055 -- constructor | FUNCTION body | primaryexp
1056 local c = ls.t.token
1057 if c == "TK_NUMBER" then
1058 self:init_exp(v, "VKNUM", 0)
1059 v.nval = ls.t.seminfo
1060 elseif c == "TK_STRING" then
1061 self:codestring(ls, v, ls.t.seminfo)
1062 elseif c == "TK_NIL" then
1063 self:init_exp(v, "VNIL", 0)
1064 elseif c == "TK_TRUE" then
1065 self:init_exp(v, "VTRUE", 0)
1066 elseif c == "TK_FALSE" then
1067 self:init_exp(v, "VFALSE", 0)
1068 elseif c == "TK_DOTS" then -- vararg
1069 local fs = ls.fs
1070 self:check_condition(ls, fs.f.is_vararg ~= 0,
1071 "cannot use "..self:LUA_QL("...").." outside a vararg function");
1072 -- NOTE: the following substitutes for a bitop, but is value-specific
1073 local is_vararg = fs.f.is_vararg
1074 if is_vararg >= self.VARARG_NEEDSARG then
1075 fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg'
1076 end
1077 self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
1078 elseif c == "{" then -- constructor
1079 self:constructor(ls, v)
1080 return
1081 elseif c == "TK_FUNCTION" then
1082 luaX:next(ls)
1083 self:body(ls, v, false, ls.linenumber)
1084 return
1085 else
1086 self:primaryexp(ls, v)
1087 return
1088 end--if c
1089 luaX:next(ls)
1090end
1091
1092------------------------------------------------------------------------
1093-- Translates unary operators tokens if found, otherwise returns
1094-- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
1095-- * used in subexpr()
1096------------------------------------------------------------------------
1097function luaY:getunopr(op)
1098 if op == "TK_NOT" then
1099 return "OPR_NOT"
1100 elseif op == "-" then
1101 return "OPR_MINUS"
1102 elseif op == "#" then
1103 return "OPR_LEN"
1104 else
1105 return "OPR_NOUNOPR"
1106 end
1107end
1108
1109------------------------------------------------------------------------
1110-- Translates binary operator tokens if found, otherwise returns
1111-- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
1112-- * used in subexpr()
1113------------------------------------------------------------------------
1114luaY.getbinopr_table = {
1115 ["+"] = "OPR_ADD",
1116 ["-"] = "OPR_SUB",
1117 ["*"] = "OPR_MUL",
1118 ["/"] = "OPR_DIV",
1119 ["%"] = "OPR_MOD",
1120 ["^"] = "OPR_POW",
1121 ["TK_CONCAT"] = "OPR_CONCAT",
1122 ["TK_NE"] = "OPR_NE",
1123 ["TK_EQ"] = "OPR_EQ",
1124 ["<"] = "OPR_LT",
1125 ["TK_LE"] = "OPR_LE",
1126 [">"] = "OPR_GT",
1127 ["TK_GE"] = "OPR_GE",
1128 ["TK_AND"] = "OPR_AND",
1129 ["TK_OR"] = "OPR_OR",
1130}
1131function luaY:getbinopr(op)
1132 local opr = self.getbinopr_table[op]
1133 if opr then return opr else return "OPR_NOBINOPR" end
1134end
1135
1136------------------------------------------------------------------------
1137-- the following priority table consists of pairs of left/right values
1138-- for binary operators (was a static const struct); grep for ORDER OPR
1139-- * the following struct is replaced:
1140-- static const struct {
1141-- lu_byte left; /* left priority for each binary operator */
1142-- lu_byte right; /* right priority */
1143-- } priority[] = { /* ORDER OPR */
1144------------------------------------------------------------------------
1145luaY.priority = {
1146 {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%'
1147 {10, 9}, {5, 4}, -- power and concat (right associative)
1148 {3, 3}, {3, 3}, -- equality
1149 {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order
1150 {2, 2}, {1, 1} -- logical (and/or)
1151}
1152
1153luaY.UNARY_PRIORITY = 8 -- priority for unary operators
1154
1155------------------------------------------------------------------------
1156-- Parse subexpressions. Includes handling of unary operators and binary
1157-- operators. A subexpr is given the rhs priority level of the operator
1158-- immediately left of it, if any (limit is -1 if none,) and if a binop
1159-- is found, limit is compared with the lhs priority level of the binop
1160-- in order to determine which executes first.
1161------------------------------------------------------------------------
1162
1163------------------------------------------------------------------------
1164-- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
1165-- where 'binop' is any binary operator with a priority higher than 'limit'
1166-- * for priority lookups with self.priority[], 1=left and 2=right
1167-- * recursively called
1168-- * used in expr()
1169------------------------------------------------------------------------
1170function luaY:subexpr(ls, v, limit)
1171 self:enterlevel(ls)
1172 local uop = self:getunopr(ls.t.token)
1173 if uop ~= "OPR_NOUNOPR" then
1174 luaX:next(ls)
1175 self:subexpr(ls, v, self.UNARY_PRIORITY)
1176 luaK:prefix(ls.fs, uop, v)
1177 else
1178 self:simpleexp(ls, v)
1179 end
1180 -- expand while operators have priorities higher than 'limit'
1181 local op = self:getbinopr(ls.t.token)
1182 while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
1183 local v2 = {} -- expdesc
1184 luaX:next(ls)
1185 luaK:infix(ls.fs, op, v)
1186 -- read sub-expression with higher priority
1187 local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
1188 luaK:posfix(ls.fs, op, v, v2)
1189 op = nextop
1190 end
1191 self:leavelevel(ls)
1192 return op -- return first untreated operator
1193end
1194
1195------------------------------------------------------------------------
1196-- Expression parsing starts here. Function subexpr is entered with the
1197-- left operator (which is non-existent) priority of -1, which is lower
1198-- than all actual operators. Expr information is returned in parm v.
1199-- * used in multiple locations
1200------------------------------------------------------------------------
1201function luaY:expr(ls, v)
1202 self:subexpr(ls, v, 0)
1203end
1204
1205-- }====================================================================
1206
1207--[[--------------------------------------------------------------------
1208-- Rules for Statements
1209----------------------------------------------------------------------]]
1210
1211------------------------------------------------------------------------
1212-- checks next token, used as a look-ahead
1213-- * returns boolean instead of 0|1
1214-- * used in retstat(), chunk()
1215------------------------------------------------------------------------
1216function luaY:block_follow(token)
1217 if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
1218 or token == "TK_UNTIL" or token == "TK_EOS" then
1219 return true
1220 else
1221 return false
1222 end
1223end
1224
1225------------------------------------------------------------------------
1226-- parse a code block or unit
1227-- * used in multiple functions
1228------------------------------------------------------------------------
1229function luaY:block(ls)
1230 -- block -> chunk
1231 local fs = ls.fs
1232 local bl = {} -- BlockCnt
1233 self:enterblock(fs, bl, false)
1234 self:chunk(ls)
1235 lua_assert(bl.breaklist == luaK.NO_JUMP)
1236 self:leaveblock(fs)
1237end
1238
1239------------------------------------------------------------------------
1240-- structure to chain all variables in the left-hand side of an
1241-- assignment
1242-- struct LHS_assign:
1243-- prev -- (table: struct LHS_assign)
1244-- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
1245------------------------------------------------------------------------
1246
1247------------------------------------------------------------------------
1248-- check whether, in an assignment to a local variable, the local variable
1249-- is needed in a previous assignment (to a table). If so, save original
1250-- local value in a safe place and use this safe copy in the previous
1251-- assignment.
1252-- * used in assignment()
1253------------------------------------------------------------------------
1254function luaY:check_conflict(ls, lh, v)
1255 local fs = ls.fs
1256 local extra = fs.freereg -- eventual position to save local variable
1257 local conflict = false
1258 while lh do
1259 if lh.v.k == "VINDEXED" then
1260 if lh.v.info == v.info then -- conflict?
1261 conflict = true
1262 lh.v.info = extra -- previous assignment will use safe copy
1263 end
1264 if lh.v.aux == v.info then -- conflict?
1265 conflict = true
1266 lh.v.aux = extra -- previous assignment will use safe copy
1267 end
1268 end
1269 lh = lh.prev
1270 end
1271 if conflict then
1272 luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
1273 luaK:reserveregs(fs, 1)
1274 end
1275end
1276
1277------------------------------------------------------------------------
1278-- parse a variable assignment sequence
1279-- * recursively called
1280-- * used in exprstat()
1281------------------------------------------------------------------------
1282function luaY:assignment(ls, lh, nvars)
1283 local e = {} -- expdesc
1284 -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
1285 local c = lh.v.k
1286 self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
1287 or c == "VINDEXED", "syntax error")
1288 if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
1289 local nv = {} -- LHS_assign
1290 nv.v = {}
1291 nv.prev = lh
1292 self:primaryexp(ls, nv.v)
1293 if nv.v.k == "VLOCAL" then
1294 self:check_conflict(ls, lh, nv.v)
1295 end
1296 self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls,
1297 "variables in assignment")
1298 self:assignment(ls, nv, nvars + 1)
1299 else -- assignment -> '=' explist1
1300 self:checknext(ls, "=")
1301 local nexps = self:explist1(ls, e)
1302 if nexps ~= nvars then
1303 self:adjust_assign(ls, nvars, nexps, e)
1304 if nexps > nvars then
1305 ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
1306 end
1307 else
1308 luaK:setoneret(ls.fs, e) -- close last expression
1309 luaK:storevar(ls.fs, lh.v, e)
1310 return -- avoid default
1311 end
1312 end
1313 self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
1314 luaK:storevar(ls.fs, lh.v, e)
1315end
1316
1317------------------------------------------------------------------------
1318-- parse condition in a repeat statement or an if control structure
1319-- * used in repeatstat(), test_then_block()
1320------------------------------------------------------------------------
1321function luaY:cond(ls)
1322 -- cond -> exp
1323 local v = {} -- expdesc
1324 self:expr(ls, v) -- read condition
1325 if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here
1326 luaK:goiftrue(ls.fs, v)
1327 return v.f
1328end
1329
1330------------------------------------------------------------------------
1331-- parse a break statement
1332-- * used in statements()
1333------------------------------------------------------------------------
1334function luaY:breakstat(ls)
1335 -- stat -> BREAK
1336 local fs = ls.fs
1337 local bl = fs.bl
1338 local upval = false
1339 while bl and not bl.isbreakable do
1340 if bl.upval then upval = true end
1341 bl = bl.previous
1342 end
1343 if not bl then
1344 luaX:syntaxerror(ls, "no loop to break")
1345 end
1346 if upval then
1347 luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
1348 end
1349 bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
1350end
1351
1352------------------------------------------------------------------------
1353-- parse a while-do control structure, body processed by block()
1354-- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
1355-- the function's implementation can be removed
1356-- * used in statements()
1357------------------------------------------------------------------------
1358function luaY:whilestat(ls, line)
1359 -- whilestat -> WHILE cond DO block END
1360 local fs = ls.fs
1361 local bl = {} -- BlockCnt
1362 luaX:next(ls) -- skip WHILE
1363 local whileinit = luaK:getlabel(fs)
1364 local condexit = self:cond(ls)
1365 self:enterblock(fs, bl, true)
1366 self:checknext(ls, "TK_DO")
1367 self:block(ls)
1368 luaK:patchlist(fs, luaK:jump(fs), whileinit)
1369 self:check_match(ls, "TK_END", "TK_WHILE", line)
1370 self:leaveblock(fs)
1371 luaK:patchtohere(fs, condexit) -- false conditions finish the loop
1372end
1373
1374------------------------------------------------------------------------
1375-- parse a repeat-until control structure, body parsed by chunk()
1376-- * used in statements()
1377------------------------------------------------------------------------
1378function luaY:repeatstat(ls, line)
1379 -- repeatstat -> REPEAT block UNTIL cond
1380 local fs = ls.fs
1381 local repeat_init = luaK:getlabel(fs)
1382 local bl1, bl2 = {}, {} -- BlockCnt
1383 self:enterblock(fs, bl1, true) -- loop block
1384 self:enterblock(fs, bl2, false) -- scope block
1385 luaX:next(ls) -- skip REPEAT
1386 self:chunk(ls)
1387 self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
1388 local condexit = self:cond(ls) -- read condition (inside scope block)
1389 if not bl2.upval then -- no upvalues?
1390 self:leaveblock(fs) -- finish scope
1391 luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop
1392 else -- complete semantics when there are upvalues
1393 self:breakstat(ls) -- if condition then break
1394 luaK:patchtohere(ls.fs, condexit) -- else...
1395 self:leaveblock(fs) -- finish scope...
1396 luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat
1397 end
1398 self:leaveblock(fs) -- finish loop
1399end
1400
1401------------------------------------------------------------------------
1402-- parse the single expressions needed in numerical for loops
1403-- * used in fornum()
1404------------------------------------------------------------------------
1405function luaY:exp1(ls)
1406 local e = {} -- expdesc
1407 self:expr(ls, e)
1408 local k = e.k
1409 luaK:exp2nextreg(ls.fs, e)
1410 return k
1411end
1412
1413------------------------------------------------------------------------
1414-- parse a for loop body for both versions of the for loop
1415-- * used in fornum(), forlist()
1416------------------------------------------------------------------------
1417function luaY:forbody(ls, base, line, nvars, isnum)
1418 -- forbody -> DO block
1419 local bl = {} -- BlockCnt
1420 local fs = ls.fs
1421 self:adjustlocalvars(ls, 3) -- control variables
1422 self:checknext(ls, "TK_DO")
1423 local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP)
1424 or luaK:jump(fs)
1425 self:enterblock(fs, bl, false) -- scope for declared variables
1426 self:adjustlocalvars(ls, nvars)
1427 luaK:reserveregs(fs, nvars)
1428 self:block(ls)
1429 self:leaveblock(fs) -- end of scope for declared variables
1430 luaK:patchtohere(fs, prep)
1431 local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
1432 or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
1433 luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop
1434 luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
1435end
1436
1437------------------------------------------------------------------------
1438-- parse a numerical for loop, calls forbody()
1439-- * used in forstat()
1440------------------------------------------------------------------------
1441function luaY:fornum(ls, varname, line)
1442 -- fornum -> NAME = exp1,exp1[,exp1] forbody
1443 local fs = ls.fs
1444 local base = fs.freereg
1445 self:new_localvarliteral(ls, "(for index)", 0)
1446 self:new_localvarliteral(ls, "(for limit)", 1)
1447 self:new_localvarliteral(ls, "(for step)", 2)
1448 self:new_localvar(ls, varname, 3)
1449 self:checknext(ls, '=')
1450 self:exp1(ls) -- initial value
1451 self:checknext(ls, ",")
1452 self:exp1(ls) -- limit
1453 if self:testnext(ls, ",") then
1454 self:exp1(ls) -- optional step
1455 else -- default step = 1
1456 luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
1457 luaK:reserveregs(fs, 1)
1458 end
1459 self:forbody(ls, base, line, 1, true)
1460end
1461
1462------------------------------------------------------------------------
1463-- parse a generic for loop, calls forbody()
1464-- * used in forstat()
1465------------------------------------------------------------------------
1466function luaY:forlist(ls, indexname)
1467 -- forlist -> NAME {,NAME} IN explist1 forbody
1468 local fs = ls.fs
1469 local e = {} -- expdesc
1470 local nvars = 0
1471 local base = fs.freereg
1472 -- create control variables
1473 self:new_localvarliteral(ls, "(for generator)", nvars)
1474 nvars = nvars + 1
1475 self:new_localvarliteral(ls, "(for state)", nvars)
1476 nvars = nvars + 1
1477 self:new_localvarliteral(ls, "(for control)", nvars)
1478 nvars = nvars + 1
1479 -- create declared variables
1480 self:new_localvar(ls, indexname, nvars)
1481 nvars = nvars + 1
1482 while self:testnext(ls, ",") do
1483 self:new_localvar(ls, self:str_checkname(ls), nvars)
1484 nvars = nvars + 1
1485 end
1486 self:checknext(ls, "TK_IN")
1487 local line = ls.linenumber
1488 self:adjust_assign(ls, 3, self:explist1(ls, e), e)
1489 luaK:checkstack(fs, 3) -- extra space to call generator
1490 self:forbody(ls, base, line, nvars - 3, false)
1491end
1492
1493------------------------------------------------------------------------
1494-- initial parsing for a for loop, calls fornum() or forlist()
1495-- * used in statements()
1496------------------------------------------------------------------------
1497function luaY:forstat(ls, line)
1498 -- forstat -> FOR (fornum | forlist) END
1499 local fs = ls.fs
1500 local bl = {} -- BlockCnt
1501 self:enterblock(fs, bl, true) -- scope for loop and control variables
1502 luaX:next(ls) -- skip `for'
1503 local varname = self:str_checkname(ls) -- first variable name
1504 local c = ls.t.token
1505 if c == "=" then
1506 self:fornum(ls, varname, line)
1507 elseif c == "," or c == "TK_IN" then
1508 self:forlist(ls, varname)
1509 else
1510 luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected")
1511 end
1512 self:check_match(ls, "TK_END", "TK_FOR", line)
1513 self:leaveblock(fs) -- loop scope (`break' jumps to this point)
1514end
1515
1516------------------------------------------------------------------------
1517-- parse part of an if control structure, including the condition
1518-- * used in ifstat()
1519------------------------------------------------------------------------
1520function luaY:test_then_block(ls)
1521 -- test_then_block -> [IF | ELSEIF] cond THEN block
1522 luaX:next(ls) -- skip IF or ELSEIF
1523 local condexit = self:cond(ls)
1524 self:checknext(ls, "TK_THEN")
1525 self:block(ls) -- `then' part
1526 return condexit
1527end
1528
1529------------------------------------------------------------------------
1530-- parse an if control structure
1531-- * used in statements()
1532------------------------------------------------------------------------
1533function luaY:ifstat(ls, line)
1534 -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
1535 local fs = ls.fs
1536 local escapelist = luaK.NO_JUMP
1537 local flist = self:test_then_block(ls) -- IF cond THEN block
1538 while ls.t.token == "TK_ELSEIF" do
1539 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1540 luaK:patchtohere(fs, flist)
1541 flist = self:test_then_block(ls) -- ELSEIF cond THEN block
1542 end
1543 if ls.t.token == "TK_ELSE" then
1544 escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
1545 luaK:patchtohere(fs, flist)
1546 luaX:next(ls) -- skip ELSE (after patch, for correct line info)
1547 self:block(ls) -- 'else' part
1548 else
1549 escapelist = luaK:concat(fs, escapelist, flist)
1550 end
1551 luaK:patchtohere(fs, escapelist)
1552 self:check_match(ls, "TK_END", "TK_IF", line)
1553end
1554
1555------------------------------------------------------------------------
1556-- parse a local function statement
1557-- * used in statements()
1558------------------------------------------------------------------------
1559function luaY:localfunc(ls)
1560 local v, b = {}, {} -- expdesc
1561 local fs = ls.fs
1562 self:new_localvar(ls, self:str_checkname(ls), 0)
1563 self:init_exp(v, "VLOCAL", fs.freereg)
1564 luaK:reserveregs(fs, 1)
1565 self:adjustlocalvars(ls, 1)
1566 self:body(ls, b, false, ls.linenumber)
1567 luaK:storevar(fs, v, b)
1568 -- debug information will only see the variable after this point!
1569 self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
1570end
1571
1572------------------------------------------------------------------------
1573-- parse a local variable declaration statement
1574-- * used in statements()
1575------------------------------------------------------------------------
1576function luaY:localstat(ls)
1577 -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
1578 local nvars = 0
1579 local nexps
1580 local e = {} -- expdesc
1581 repeat
1582 self:new_localvar(ls, self:str_checkname(ls), nvars)
1583 nvars = nvars + 1
1584 until not self:testnext(ls, ",")
1585 if self:testnext(ls, "=") then
1586 nexps = self:explist1(ls, e)
1587 else
1588 e.k = "VVOID"
1589 nexps = 0
1590 end
1591 self:adjust_assign(ls, nvars, nexps, e)
1592 self:adjustlocalvars(ls, nvars)
1593end
1594
1595------------------------------------------------------------------------
1596-- parse a function name specification
1597-- * used in funcstat()
1598------------------------------------------------------------------------
1599function luaY:funcname(ls, v)
1600 -- funcname -> NAME {field} [':' NAME]
1601 local needself = false
1602 self:singlevar(ls, v)
1603 while ls.t.token == "." do
1604 self:field(ls, v)
1605 end
1606 if ls.t.token == ":" then
1607 needself = true
1608 self:field(ls, v)
1609 end
1610 return needself
1611end
1612
1613------------------------------------------------------------------------
1614-- parse a function statement
1615-- * used in statements()
1616------------------------------------------------------------------------
1617function luaY:funcstat(ls, line)
1618 -- funcstat -> FUNCTION funcname body
1619 local v, b = {}, {} -- expdesc
1620 luaX:next(ls) -- skip FUNCTION
1621 local needself = self:funcname(ls, v)
1622 self:body(ls, b, needself, line)
1623 luaK:storevar(ls.fs, v, b)
1624 luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
1625end
1626
1627------------------------------------------------------------------------
1628-- parse a function call with no returns or an assignment statement
1629-- * used in statements()
1630------------------------------------------------------------------------
1631function luaY:exprstat(ls)
1632 -- stat -> func | assignment
1633 local fs = ls.fs
1634 local v = {} -- LHS_assign
1635 v.v = {}
1636 self:primaryexp(ls, v.v)
1637 if v.v.k == "VCALL" then -- stat -> func
1638 luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results
1639 else -- stat -> assignment
1640 v.prev = nil
1641 self:assignment(ls, v, 1)
1642 end
1643end
1644
1645------------------------------------------------------------------------
1646-- parse a return statement
1647-- * used in statements()
1648------------------------------------------------------------------------
1649function luaY:retstat(ls)
1650 -- stat -> RETURN explist
1651 local fs = ls.fs
1652 local e = {} -- expdesc
1653 local first, nret -- registers with returned values
1654 luaX:next(ls) -- skip RETURN
1655 if self:block_follow(ls.t.token) or ls.t.token == ";" then
1656 first, nret = 0, 0 -- return no values
1657 else
1658 nret = self:explist1(ls, e) -- optional return values
1659 if self:hasmultret(e.k) then
1660 luaK:setmultret(fs, e)
1661 if e.k == "VCALL" and nret == 1 then -- tail call?
1662 luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
1663 lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
1664 end
1665 first = fs.nactvar
1666 nret = self.LUA_MULTRET -- return all values
1667 else
1668 if nret == 1 then -- only one single value?
1669 first = luaK:exp2anyreg(fs, e)
1670 else
1671 luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
1672 first = fs.nactvar -- return all 'active' values
1673 lua_assert(nret == fs.freereg - first)
1674 end
1675 end--if
1676 end--if
1677 luaK:ret(fs, first, nret)
1678end
1679
1680------------------------------------------------------------------------
1681-- initial parsing for statements, calls a lot of functions
1682-- * returns boolean instead of 0|1
1683-- * used in chunk()
1684------------------------------------------------------------------------
1685function luaY:statement(ls)
1686 local line = ls.linenumber -- may be needed for error messages
1687 local c = ls.t.token
1688 if c == "TK_IF" then -- stat -> ifstat
1689 self:ifstat(ls, line)
1690 return false
1691 elseif c == "TK_WHILE" then -- stat -> whilestat
1692 self:whilestat(ls, line)
1693 return false
1694 elseif c == "TK_DO" then -- stat -> DO block END
1695 luaX:next(ls) -- skip DO
1696 self:block(ls)
1697 self:check_match(ls, "TK_END", "TK_DO", line)
1698 return false
1699 elseif c == "TK_FOR" then -- stat -> forstat
1700 self:forstat(ls, line)
1701 return false
1702 elseif c == "TK_REPEAT" then -- stat -> repeatstat
1703 self:repeatstat(ls, line)
1704 return false
1705 elseif c == "TK_FUNCTION" then -- stat -> funcstat
1706 self:funcstat(ls, line)
1707 return false
1708 elseif c == "TK_LOCAL" then -- stat -> localstat
1709 luaX:next(ls) -- skip LOCAL
1710 if self:testnext(ls, "TK_FUNCTION") then -- local function?
1711 self:localfunc(ls)
1712 else
1713 self:localstat(ls)
1714 end
1715 return false
1716 elseif c == "TK_RETURN" then -- stat -> retstat
1717 self:retstat(ls)
1718 return true -- must be last statement
1719 elseif c == "TK_BREAK" then -- stat -> breakstat
1720 luaX:next(ls) -- skip BREAK
1721 self:breakstat(ls)
1722 return true -- must be last statement
1723 else
1724 self:exprstat(ls)
1725 return false -- to avoid warnings
1726 end--if c
1727end
1728
1729------------------------------------------------------------------------
1730-- parse a chunk, which consists of a bunch of statements
1731-- * used in parser(), body(), block(), repeatstat()
1732------------------------------------------------------------------------
1733function luaY:chunk(ls)
1734 -- chunk -> { stat [';'] }
1735 local islast = false
1736 self:enterlevel(ls)
1737 while not islast and not self:block_follow(ls.t.token) do
1738 islast = self:statement(ls)
1739 self:testnext(ls, ";")
1740 lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg and
1741 ls.fs.freereg >= ls.fs.nactvar)
1742 ls.fs.freereg = ls.fs.nactvar -- free registers
1743 end
1744 self:leavelevel(ls)
1745end
1746
1747-- }======================================================================