aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua')
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lparser.lua1706
1 files changed, 0 insertions, 1706 deletions
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