aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua')
-rw-r--r--LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua1121
1 files changed, 0 insertions, 1121 deletions
diff --git a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua b/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua
deleted file mode 100644
index a46edc6..0000000
--- a/LuaSL/testLua/yueliang-0.4.1/nat-5.0.3/lparser_mk3b.lua
+++ /dev/null
@@ -1,1121 +0,0 @@
1--[[--------------------------------------------------------------------
2
3 lparser.lua
4 Lua 5 parser in Lua
5 This file is part of Yueliang.
6
7 Copyright (c) 2008 Kein-Hong Man <khman@users.sf.net>
8 The COPYRIGHT file describes the conditions
9 under which this software may be distributed.
10
11 See the ChangeLog for more information.
12
13----------------------------------------------------------------------]]
14
15--[[--------------------------------------------------------------------
16-- Notes:
17-- * this is a Lua 5.0.x parser skeleton, for llex_mk3.lua lexer
18-- * written as a module factory with recognizable lparser.c roots
19-- * builds some data, performs logging for educational purposes
20-- * target is to have relatively efficient and clear code
21-- * needs one parameter, a lexer module that implements:
22-- luaX:lex() - returns appropriate [token, semantic info] pairs
23-- luaX.ln - current line number
24-- luaX:errorline(s, [line]) - dies with error message
25--
26-- Usage example:
27-- lex_init = require("llex_mk3.lua")
28-- parser_init = require("lparser_mk3.lua")
29-- local luaX = lex_init(chunk, "=string")
30-- local luaY = parser_init(luaX)
31-- local fs = luaY:parser()
32--
33-- Development notes:
34-- * see test_parser-5.0.lua for grammar elements based on lparser.c
35-- * lparser has a few extra items to help parsing/syntax checking
36-- (a) line number (error reporting), lookahead token storage
37-- (b) per-prototype states needs a storage list
38-- (c) 'break' needs a per-block flag in a stack
39-- (d) 'kind' (v.k) testing needed in expr_stat() and assignment()
40-- for disambiguation, thus v.k manipulation is retained
41-- (e) one line # var (lastln) for ambiguous (split line) function
42-- call checking
43-- (f) most line number function call args retained for future use
44-- (g) Lua 4 compatibility code completely removed
45-- (h) minimal variable management code to differentiate each type
46-- * parsing starts from the end of this file in luaY:parser()
47--
48----------------------------------------------------------------------]]
49
50return
51function(luaX)
52--[[--------------------------------------------------------------------
53-- structures and data initialization
54----------------------------------------------------------------------]]
55
56 local line -- start line # for error messages
57 local lastln -- last line # for ambiguous syntax chk
58 local tok, seminfo -- token, semantic info pair
59 local peek_tok, peek_sem -- ditto, for lookahead
60 local fs -- function state
61 local top_fs = {} -- top-level function state
62 local luaY = {}
63 --------------------------------------------------------------------
64 local block_follow = {} -- lookahead check in chunk(), returnstat()
65 for v in string.gfind("else elseif end until <eof>", "%S+") do
66 block_follow[v] = true
67 end
68 --------------------------------------------------------------------
69 local stat_call = {} -- lookup for calls in stat()
70 for v in string.gfind("if while do for repeat function local return break", "%S+") do
71 stat_call[v] = v.."_stat"
72 end
73 --------------------------------------------------------------------
74 local binopr_left = {} -- binary operators, left priority
75 local binopr_right = {} -- binary operators, right priority
76 for op, lt, rt in string.gfind([[
77{+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{^ 10 9}{.. 5 4}
78{~= 3 3}{== 3 3}{< 3 3}{<= 3 3}{> 3 3}{>= 3 3}
79{and 2 2}{or 1 1}
80]], "{(%S+)%s(%d+)%s(%d+)}") do
81 binopr_left[op] = lt + 0
82 binopr_right[op] = rt + 0
83 end
84 local unopr = { ["not"] = true, ["-"] = true, } -- unary operators
85
86--[[--------------------------------------------------------------------
87-- logging: this logging function is for educational purposes
88-- * logged data can be retrieved from the returned data structure
89-- * or, replace self:log() instances with your custom code...
90----------------------------------------------------------------------]]
91
92 function luaY:log(msg)
93 local log = top_fs.log
94 if not log then log = {}; top_fs.log = log end
95 table.insert(top_fs.log, msg)
96 end
97
98--[[--------------------------------------------------------------------
99-- support functions
100----------------------------------------------------------------------]]
101
102 --------------------------------------------------------------------
103 -- reads in next token
104 --------------------------------------------------------------------
105 function luaY:next()
106 lastln = luaX.ln
107 if peek_tok then -- is there a look-ahead token? if yes, use it
108 tok, seminfo = peek_tok, peek_sem
109 peek_tok = nil
110 else
111 tok, seminfo = luaX:lex() -- read next token
112 end
113 end
114 --------------------------------------------------------------------
115 -- peek at next token (single lookahead for table constructor)
116 --------------------------------------------------------------------
117 function luaY:lookahead()
118 peek_tok, peek_sem = luaX:lex()
119 return peek_tok
120 end
121
122 ------------------------------------------------------------------------
123 -- throws a syntax error
124 ------------------------------------------------------------------------
125 function luaY:syntaxerror(msg)
126 local tok = tok
127 if tok ~= "<number>" and tok ~= "<string>" then
128 if tok == "<name>" then tok = seminfo end
129 tok = "'"..tok.."'"
130 end
131 luaX:errorline(msg.." near "..tok)
132 end
133 --------------------------------------------------------------------
134 -- throws a syntax error if token expected is not there
135 --------------------------------------------------------------------
136 function luaY:error_expected(token)
137 self:syntaxerror("'"..token.."' expected")
138 end
139
140 --------------------------------------------------------------------
141 -- verifies token conditions are met or else throw error
142 --------------------------------------------------------------------
143 function luaY:check_match(what, who, where)
144 if not self:testnext(what) then
145 if where == luaX.ln then
146 self:error_expected(what)
147 else
148 self:syntaxerror("'"..what.."' expected (to close '"..who.."' at line "..where..")")
149 end
150 end
151 end
152 --------------------------------------------------------------------
153 -- tests for a token, returns outcome
154 -- * return value changed to boolean
155 --------------------------------------------------------------------
156 function luaY:testnext(c)
157 if tok == c then self:next(); return true end
158 end
159 --------------------------------------------------------------------
160 -- throws error if condition not matched
161 --------------------------------------------------------------------
162 function luaY:check_condition(c, msg)
163 if not c then self:syntaxerror(msg) end
164 end
165 --------------------------------------------------------------------
166 -- check for existence of a token, throws error if not found
167 --------------------------------------------------------------------
168 function luaY:check(c)
169 if not self:testnext(c) then self:error_expected(c) end
170 end
171
172 --------------------------------------------------------------------
173 -- expect that token is a name, return the name
174 --------------------------------------------------------------------
175 function luaY:str_checkname()
176 self:check_condition(tok == "<name>", "<name> expected")
177 local ts = seminfo
178 self:next()
179 self:log(" str_checkname: '"..ts.."'")
180 return ts
181 end
182 --------------------------------------------------------------------
183 -- adds given string s in string pool, sets e as VK
184 --------------------------------------------------------------------
185 function luaY:codestring(e, s)
186 e.k = "VK"
187 self:log(" codestring: "..string.format("%q", s))
188 end
189 --------------------------------------------------------------------
190 -- consume a name token, adds it to string pool
191 --------------------------------------------------------------------
192 function luaY:checkname(e)
193 self:log(" checkname:")
194 self:codestring(e, self:str_checkname())
195 end
196
197--[[--------------------------------------------------------------------
198-- state management functions with open/close pairs
199----------------------------------------------------------------------]]
200
201 --------------------------------------------------------------------
202 -- enters a code unit, initializes elements
203 --------------------------------------------------------------------
204 function luaY:enterblock(isbreakable)
205 local bl = {} -- per-block state
206 bl.isbreakable = isbreakable
207 bl.prev = fs.bl
208 bl.locallist = {}
209 fs.bl = bl
210 self:log(">> enterblock(isbreakable="..tostring(isbreakable)..")")
211 end
212 --------------------------------------------------------------------
213 -- leaves a code unit, close any upvalues
214 --------------------------------------------------------------------
215 function luaY:leaveblock()
216 local bl = fs.bl
217 fs.bl = bl.prev
218 self:log("<< leaveblock")
219 end
220 --------------------------------------------------------------------
221 -- opening of a function
222 --------------------------------------------------------------------
223 function luaY:open_func()
224 local new_fs -- per-function state
225 if not fs then -- top_fs is created early
226 new_fs = top_fs
227 else
228 new_fs = {}
229 end
230 new_fs.prev = fs -- linked list of function states
231 new_fs.bl = nil
232 new_fs.locallist = {}
233 fs = new_fs
234 self:log(">> open_func")
235 end
236 --------------------------------------------------------------------
237 -- closing of a function
238 --------------------------------------------------------------------
239 function luaY:close_func()
240 fs = fs.prev
241 self:log("<< close_func")
242 end
243
244--[[--------------------------------------------------------------------
245-- variable (global|local|upvalue) handling
246-- * a pure parser does not really need this, but if we want to produce
247-- useful output, might as well write minimal code to manage this...
248-- * entry point is singlevar() for variable lookups
249-- * three entry points for local variable creation, in order to keep
250-- to original C calls, but the extra arguments such as positioning
251-- are removed as we are not allocating registers -- we are only
252-- doing simple classification
253-- * lookup tables (bl.locallist) are maintained awkwardly in the basic
254-- block data structures, PLUS the function data structure (this is
255-- an inelegant hack, since bl is nil for the top level of a function)
256----------------------------------------------------------------------]]
257
258 --------------------------------------------------------------------
259 -- register a local variable, set in active variable list
260 -- * used in new_localvarstr(), parlist(), fornum(), forlist(),
261 -- localfunc(), localstat()
262 --------------------------------------------------------------------
263 function luaY:new_localvar(name)
264 local bl = fs.bl
265 local locallist
266 if bl then
267 locallist = bl.locallist
268 else
269 locallist = fs.locallist
270 end
271 locallist[name] = true
272 self:log(" new_localvar: '"..name.."'")
273 end
274 --------------------------------------------------------------------
275 -- creates a new local variable given a name
276 -- * used in fornum(), forlist() for loop variables; in create_local()
277 --------------------------------------------------------------------
278 function luaY:new_localvarstr(name)
279 self:new_localvar(name)
280 end
281 --------------------------------------------------------------------
282 -- creates a single local variable and activates it
283 -- * used only in code_params() for "arg", body() for "self"
284 --------------------------------------------------------------------
285 function luaY:create_local(name)
286 self:new_localvarstr(name)
287 end
288
289 --------------------------------------------------------------------
290 -- search the local variable namespace of the given fs for a match
291 -- * a simple lookup only, no active variable list kept, so no useful
292 -- index value can be returned by this function
293 -- * used only in singlevaraux()
294 --------------------------------------------------------------------
295 function luaY:searchvar(fs, n)
296 local bl = fs.bl
297 if bl then
298 locallist = bl.locallist
299 while locallist do
300 if locallist[n] then return 1 end -- found
301 bl = bl.prev
302 locallist = bl and bl.locallist
303 end
304 end
305 locallist = fs.locallist
306 if locallist[n] then return 1 end -- found
307 return -1 -- not found
308 end
309 --------------------------------------------------------------------
310 -- handle locals, globals and upvalues and related processing
311 -- * search mechanism is recursive, calls itself to search parents
312 -- * used only in singlevar()
313 --------------------------------------------------------------------
314 function luaY:singlevaraux(fs, n, var, base)
315 if fs == nil then -- no more levels?
316 var.k = "VGLOBAL" -- default is global variable
317 else
318 local v = self:searchvar(fs, n) -- look up at current level
319 if v >= 0 then
320 var.k = "VLOCAL"
321 else -- not found at current level; try upper one
322 self:singlevaraux(fs.prev, n, var, 0)
323 if var.k == "VGLOBAL" then
324 -- handle global var processing here
325 else -- LOCAL or UPVAL
326 var.k = "VUPVAL"
327 end
328 end--if v
329 end--if fs
330 end
331 --------------------------------------------------------------------
332 -- consume a name token, creates a variable (global|local|upvalue)
333 -- * used in prefixexp(), funcname()
334 --------------------------------------------------------------------
335 function luaY:singlevar(v)
336 local varname = self:str_checkname()
337 self:singlevaraux(fs, varname, v, 1)
338 self:log(" singlevar(kind): '"..v.k.."'")
339 end
340
341--[[--------------------------------------------------------------------
342-- other parsing functions
343-- * for table constructor, parameter list, argument list
344----------------------------------------------------------------------]]
345
346 --------------------------------------------------------------------
347 -- parse a function name suffix, for function call specifications
348 -- * used in primaryexp(), funcname()
349 --------------------------------------------------------------------
350 function luaY:field(v)
351 -- field -> ['.' | ':'] NAME
352 local key = {}
353 self:log(" field: operator="..tok)
354 self:next() -- skip the dot or colon
355 self:checkname(key)
356 v.k = "VINDEXED"
357 end
358 --------------------------------------------------------------------
359 -- parse a table indexing suffix, for constructors, expressions
360 -- * used in recfield(), primaryexp()
361 --------------------------------------------------------------------
362 function luaY:index(v)
363 -- index -> '[' expr ']'
364 self:log(">> index: begin '['")
365 self:next() -- skip the '['
366 self:expr(v)
367 self:check("]")
368 self:log("<< index: end ']'")
369 end
370 --------------------------------------------------------------------
371 -- parse a table record (hash) field
372 -- * used in constructor()
373 --------------------------------------------------------------------
374 function luaY:recfield(cc)
375 -- recfield -> (NAME | '['exp1']') = exp1
376 local key, val = {}, {}
377 if tok == "<name>" then
378 self:log("recfield: name")
379 self:checkname(key)
380 else-- tok == '['
381 self:log("recfield: [ exp1 ]")
382 self:index(key)
383 end
384 self:check("=")
385 self:expr(val)
386 end
387 --------------------------------------------------------------------
388 -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
389 -- * note: retained in this skeleton because it modifies cc.v.k
390 -- * used in constructor()
391 --------------------------------------------------------------------
392 function luaY:closelistfield(cc)
393 if cc.v.k == "VVOID" then return end -- there is no list item
394 cc.v.k = "VVOID"
395 end
396 --------------------------------------------------------------------
397 -- parse a table list (array) field
398 -- * used in constructor()
399 --------------------------------------------------------------------
400 function luaY:listfield(cc)
401 self:log("listfield: expr")
402 self:expr(cc.v)
403 end
404 --------------------------------------------------------------------
405 -- parse a table constructor
406 -- * used in funcargs(), simpleexp()
407 --------------------------------------------------------------------
408 function luaY:constructor(t)
409 -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
410 -- field -> recfield | listfield
411 -- fieldsep -> ',' | ';'
412 self:log(">> constructor: begin")
413 local line = luaX.ln
414 local cc = {}
415 cc.v = {}
416 cc.t = t
417 t.k = "VRELOCABLE"
418 cc.v.k = "VVOID"
419 self:check("{")
420 repeat
421 self:testnext(";") -- compatibility only
422 if tok == "}" then break end
423 -- closelistfield(cc) here
424 local c = tok
425 if c == "<name>" then -- may be listfields or recfields
426 if self:lookahead() ~= "=" then -- look ahead: expression?
427 self:listfield(cc)
428 else
429 self:recfield(cc)
430 end
431 elseif c == "[" then -- constructor_item -> recfield
432 self:recfield(cc)
433 else -- constructor_part -> listfield
434 self:listfield(cc)
435 end
436 until not self:testnext(",") and not self:testnext(";")
437 self:check_match("}", "{", line)
438 -- lastlistfield(cc) here
439 self:log("<< constructor: end")
440 end
441 --------------------------------------------------------------------
442 -- parse the arguments (parameters) of a function declaration
443 -- * used in body()
444 --------------------------------------------------------------------
445 function luaY:parlist()
446 -- parlist -> [ param { ',' param } ]
447 self:log(">> parlist: begin")
448 local dots = false
449 if tok ~= ")" then -- is 'parlist' not empty?
450 repeat
451 local c = tok
452 if c == "..." then
453 self:log("parlist: ... (dots)")
454 dots = true
455 self:next()
456 elseif c == "<name>" then
457 self:new_localvar(self:str_checkname())
458 else
459 self:syntaxerror("<name> or '...' expected")
460 end
461 until dots or not self:testnext(",")
462 end
463 -- was code_params()
464 if dots then
465 self:create_local("arg")
466 end
467 self:log("<< parlist: end")
468 end
469 --------------------------------------------------------------------
470 -- parse the parameters of a function call
471 -- * contrast with parlist(), used in function declarations
472 -- * used in primaryexp()
473 --------------------------------------------------------------------
474 function luaY:funcargs(f)
475 local args = {}
476 local line = luaX.ln
477 local c = tok
478 if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
479 self:log(">> funcargs: begin '('")
480 if line ~= lastln then
481 self:syntaxerror("ambiguous syntax (function call x new statement)")
482 end
483 self:next()
484 if tok == ")" then -- arg list is empty?
485 args.k = "VVOID"
486 else
487 self:explist1(args)
488 end
489 self:check_match(")", "(", line)
490 elseif c == "{" then -- funcargs -> constructor
491 self:log(">> funcargs: begin '{'")
492 self:constructor(args)
493 elseif c == "<string>" then -- funcargs -> STRING
494 self:log(">> funcargs: begin <string>")
495 self:codestring(args, seminfo)
496 self:next() -- must use 'seminfo' before 'next'
497 else
498 self:syntaxerror("function arguments expected")
499 return
500 end--if c
501 f.k = "VCALL"
502 self:log("<< funcargs: end -- expr is a VCALL")
503 end
504
505--[[--------------------------------------------------------------------
506-- mostly expression functions
507----------------------------------------------------------------------]]
508
509 --------------------------------------------------------------------
510 -- parses an expression in parentheses or a single variable
511 -- * used in primaryexp()
512 --------------------------------------------------------------------
513 function luaY:prefixexp(v)
514 -- prefixexp -> NAME | '(' expr ')'
515 local c = tok
516 if c == "(" then
517 self:log(">> prefixexp: begin ( expr ) ")
518 local line = self.ln
519 self:next()
520 self:expr(v)
521 self:check_match(")", "(", line)
522 self:log("<< prefixexp: end ( expr ) ")
523 elseif c == "<name>" then
524 self:log("prefixexp: <name>")
525 self:singlevar(v)
526 else
527 self:syntaxerror("unexpected symbol")
528 end--if c
529 end
530 --------------------------------------------------------------------
531 -- parses a prefixexp (an expression in parentheses or a single
532 -- variable) or a function call specification
533 -- * used in simpleexp(), assignment(), expr_stat()
534 --------------------------------------------------------------------
535 function luaY:primaryexp(v)
536 -- primaryexp ->
537 -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
538 self:prefixexp(v)
539 while true do
540 local c = tok
541 if c == "." then -- field
542 self:log("primaryexp: '.' field")
543 self:field(v)
544 elseif c == "[" then -- '[' exp1 ']'
545 self:log("primaryexp: [ exp1 ]")
546 local key = {}
547 self:index(key)
548 elseif c == ":" then -- ':' NAME funcargs
549 self:log("primaryexp: :<name> funcargs")
550 local key = {}
551 self:next()
552 self:checkname(key)
553 self:funcargs(v)
554 elseif c == "(" or c == "<string>" or c == "{" then -- funcargs
555 self:log("primaryexp: "..c.." funcargs")
556 self:funcargs(v)
557 else
558 return
559 end--if c
560 end--while
561 end
562 --------------------------------------------------------------------
563 -- parses general expression types, constants handled here
564 -- * used in subexpr()
565 --------------------------------------------------------------------
566 function luaY:simpleexp(v)
567 -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | constructor
568 -- | FUNCTION body | primaryexp
569 local c = tok
570 if c == "<number>" then
571 self:log("simpleexp: <number>="..seminfo)
572 v.k = "VK"
573 self:next() -- must use 'seminfo' before 'next'
574 elseif c == "<string>" then
575 self:log("simpleexp: <string>="..seminfo)
576 self:codestring(v, seminfo)
577 self:next() -- must use 'seminfo' before 'next'
578 elseif c == "nil" then
579 self:log("simpleexp: nil")
580 v.k = "VNIL"
581 self:next()
582 elseif c == "true" then
583 self:log("simpleexp: true")
584 v.k = "VTRUE"
585 self:next()
586 elseif c == "false" then
587 self:log("simpleexp: false")
588 v.k = "VFALSE"
589 self:next()
590 elseif c == "{" then -- constructor
591 self:log("simpleexp: constructor")
592 self:constructor(v)
593 elseif c == "function" then
594 self:log("simpleexp: function")
595 self:next()
596 self:body(v, false, luaX.ln)
597 else
598 self:primaryexp(v)
599 end--if c
600 end
601 ------------------------------------------------------------------------
602 -- Parse subexpressions. Includes handling of unary operators and binary
603 -- operators. A subexpr is given the rhs priority level of the operator
604 -- immediately left of it, if any (limit is -1 if none,) and if a binop
605 -- is found, limit is compared with the lhs priority level of the binop
606 -- in order to determine which executes first.
607 -- * recursively called
608 -- * used in expr()
609 ------------------------------------------------------------------------
610 function luaY:subexpr(v, limit)
611 -- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
612 -- * where 'binop' is any binary operator with a priority
613 -- higher than 'limit'
614 local op = tok
615 local uop = unopr[op]
616 if uop then
617 self:log(" subexpr: uop='"..op.."'")
618 self:next()
619 self:subexpr(v, 8) -- UNARY_PRIORITY
620 else
621 self:simpleexp(v)
622 end
623 -- expand while operators have priorities higher than 'limit'
624 op = tok
625 local binop = binopr_left[op]
626 while binop and binop > limit do
627 local v2 = {}
628 self:log(">> subexpr: binop='"..op.."'")
629 self:next()
630 -- read sub-expression with higher priority
631 local nextop = self:subexpr(v2, binopr_right[op])
632 self:log("<< subexpr: -- evaluate")
633 op = nextop
634 binop = binopr_left[op]
635 end
636 return op -- return first untreated operator
637 end
638 --------------------------------------------------------------------
639 -- Expression parsing starts here. Function subexpr is entered with the
640 -- left operator (which is non-existent) priority of -1, which is lower
641 -- than all actual operators. Expr information is returned in parm v.
642 -- * used in cond(), explist1(), index(), recfield(), listfield(),
643 -- prefixexp(), while_stat(), exp1()
644 --------------------------------------------------------------------
645 function luaY:expr(v)
646 -- expr -> subexpr
647 self:log("expr:")
648 self:subexpr(v, -1)
649 end
650
651--[[--------------------------------------------------------------------
652-- third level parsing functions
653----------------------------------------------------------------------]]
654
655 --------------------------------------------------------------------
656 -- parse a variable assignment sequence
657 -- * recursively called
658 -- * used in expr_stat()
659 --------------------------------------------------------------------
660 function luaY:assignment(v)
661 local e = {}
662 local c = v.v.k
663 self:check_condition(c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
664 or c == "VINDEXED", "syntax error")
665 if self:testnext(",") then -- assignment -> ',' primaryexp assignment
666 local nv = {} -- expdesc
667 nv.v = {}
668 self:log("assignment: ',' -- next LHS element")
669 self:primaryexp(nv.v)
670 -- lparser.c deals with some register usage conflict here
671 self:assignment(nv)
672 else -- assignment -> '=' explist1
673 self:check("=")
674 self:log("assignment: '=' -- RHS elements follows")
675 self:explist1(e)
676 return -- avoid default
677 end
678 e.k = "VNONRELOC"
679 end
680 --------------------------------------------------------------------
681 -- parse a for loop body for both versions of the for loop
682 -- * used in fornum(), forlist()
683 --------------------------------------------------------------------
684 function luaY:forbody(line, isnum)
685 self:check("do")
686 self:enterblock(true) -- loop block
687 self:block()
688 self:leaveblock()
689 end
690 --------------------------------------------------------------------
691 -- parse a numerical for loop, calls forbody()
692 -- * used in for_stat()
693 --------------------------------------------------------------------
694 function luaY:fornum(varname, line)
695 -- fornum -> NAME = exp1, exp1 [, exp1] DO body
696 self:new_localvar(varname)
697 self:new_localvarstr("(for limit)")
698 self:new_localvarstr("(for step)")
699 self:log(">> fornum: begin")
700 self:check("=")
701 self:log("fornum: index start")
702 self:exp1() -- initial value
703 self:check(",")
704 self:log("fornum: index stop")
705 self:exp1() -- limit
706 if self:testnext(",") then
707 self:log("fornum: index step")
708 self:exp1() -- optional step
709 else
710 -- default step = 1
711 end
712 self:log("fornum: body")
713 self:forbody(line, true)
714 self:log("<< fornum: end")
715 end
716 --------------------------------------------------------------------
717 -- parse a generic for loop, calls forbody()
718 -- * used in for_stat()
719 --------------------------------------------------------------------
720 function luaY:forlist(indexname)
721 -- forlist -> NAME {, NAME} IN explist1 DO body
722 self:log(">> forlist: begin")
723 local e = {}
724 self:new_localvarstr("(for generator)")
725 self:new_localvarstr("(for state)")
726 self:new_localvar(indexname)
727 while self:testnext(",") do
728 self:new_localvar(self:str_checkname())
729 end
730 self:check("in")
731 local line = line
732 self:log("forlist: explist1")
733 self:explist1(e)
734 self:log("forlist: body")
735 self:forbody(line, false)
736 self:log("<< forlist: end")
737 end
738 --------------------------------------------------------------------
739 -- parse a function name specification
740 -- * used in func_stat()
741 --------------------------------------------------------------------
742 function luaY:funcname(v)
743 -- funcname -> NAME {field} [':' NAME]
744 self:log(">> funcname: begin")
745 local needself = false
746 self:singlevar(v)
747 while tok == "." do
748 self:log("funcname: -- '.' field")
749 self:field(v)
750 end
751 if tok == ":" then
752 self:log("funcname: -- ':' field")
753 needself = true
754 self:field(v)
755 end
756 self:log("<< funcname: end")
757 return needself
758 end
759 --------------------------------------------------------------------
760 -- parse the single expressions needed in numerical for loops
761 -- * used in fornum()
762 --------------------------------------------------------------------
763 function luaY:exp1()
764 -- exp1 -> expr
765 local e = {}
766 self:log(">> exp1: begin")
767 self:expr(e)
768 self:log("<< exp1: end")
769 end
770 --------------------------------------------------------------------
771 -- parse condition in a repeat statement or an if control structure
772 -- * used in repeat_stat(), test_then_block()
773 --------------------------------------------------------------------
774 function luaY:cond(v)
775 -- cond -> expr
776 self:log(">> cond: begin")
777 self:expr(v) -- read condition
778 self:log("<< cond: end")
779 end
780 --------------------------------------------------------------------
781 -- parse part of an if control structure, including the condition
782 -- * used in if_stat()
783 --------------------------------------------------------------------
784 function luaY:test_then_block(v)
785 -- test_then_block -> [IF | ELSEIF] cond THEN block
786 self:next() -- skip IF or ELSEIF
787 self:log("test_then_block: test condition")
788 self:cond(v)
789 self:check("then")
790 self:log("test_then_block: then block")
791 self:block() -- 'then' part
792 end
793 --------------------------------------------------------------------
794 -- parse a local function statement
795 -- * used in local_stat()
796 --------------------------------------------------------------------
797 function luaY:localfunc()
798 -- localfunc -> NAME body
799 local v, b = {}
800 self:log("localfunc: begin")
801 self:new_localvar(self:str_checkname())
802 v.k = "VLOCAL"
803 self:log("localfunc: body")
804 self:body(b, false, luaX.ln)
805 self:log("localfunc: end")
806 end
807 --------------------------------------------------------------------
808 -- parse a local variable declaration statement
809 -- * used in local_stat()
810 --------------------------------------------------------------------
811 function luaY:localstat()
812 -- localstat -> NAME {',' NAME} ['=' explist1]
813 self:log(">> localstat: begin")
814 local e = {}
815 repeat
816 self:new_localvar(self:str_checkname())
817 until not self:testnext(",")
818 if self:testnext("=") then
819 self:log("localstat: -- assignment")
820 self:explist1(e)
821 else
822 e.k = "VVOID"
823 end
824 self:log("<< localstat: end")
825 end
826 --------------------------------------------------------------------
827 -- parse a list of comma-separated expressions
828 -- * used in return_stat(), localstat(), funcargs(), assignment(),
829 -- forlist()
830 --------------------------------------------------------------------
831 function luaY:explist1(e)
832 -- explist1 -> expr { ',' expr }
833 self:log(">> explist1: begin")
834 self:expr(e)
835 while self:testnext(",") do
836 self:log("explist1: ',' -- continuation")
837 self:expr(e)
838 end
839 self:log("<< explist1: end")
840 end
841 --------------------------------------------------------------------
842 -- parse function declaration body
843 -- * used in simpleexp(), localfunc(), func_stat()
844 --------------------------------------------------------------------
845 function luaY:body(e, needself, line)
846 -- body -> '(' parlist ')' chunk END
847 self:open_func()
848 self:log("body: begin")
849 self:check("(")
850 if needself then
851 self:create_local("self")
852 end
853 self:log("body: parlist")
854 self:parlist()
855 self:check(")")
856 self:log("body: chunk")
857 self:chunk()
858 self:check_match("end", "function", line)
859 self:log("body: end")
860 self:close_func()
861 end
862 --------------------------------------------------------------------
863 -- parse a code block or unit
864 -- * used in do_stat(), while_stat(), repeat_stat(), forbody(),
865 -- test_then_block(), if_stat()
866 --------------------------------------------------------------------
867 function luaY:block()
868 -- block -> chunk
869 self:log("block: begin")
870 self:enterblock(false)
871 self:chunk()
872 self:leaveblock()
873 self:log("block: end")
874 end
875
876--[[--------------------------------------------------------------------
877-- second level parsing functions, all with '_stat' suffix
878-- * stat() -> *_stat()
879----------------------------------------------------------------------]]
880
881 --------------------------------------------------------------------
882 -- initial parsing for a for loop, calls fornum() or forlist()
883 -- * used in stat()
884 --------------------------------------------------------------------
885 function luaY:for_stat()
886 -- stat -> for_stat -> fornum | forlist
887 local line = line
888 self:log("for_stat: begin")
889 self:enterblock(false) -- block to control variable scope
890 self:next() -- skip 'for'
891 local varname = self:str_checkname() -- first variable name
892 local c = tok
893 if c == "=" then
894 self:log("for_stat: numerical loop")
895 self:fornum(varname, line)
896 elseif c == "," or c == "in" then
897 self:log("for_stat: list-based loop")
898 self:forlist(varname)
899 else
900 self:syntaxerror("'=' or 'in' expected")
901 end
902 self:check_match("end", "for", line)
903 self:leaveblock()
904 self:log("for_stat: end")
905 end
906 --------------------------------------------------------------------
907 -- parse a while-do control structure, body processed by block()
908 -- * used in stat()
909 --------------------------------------------------------------------
910 function luaY:while_stat()
911 -- stat -> while_stat -> WHILE cond DO block END
912 local line = line
913 local v = {}
914 self:next() -- skip WHILE
915 self:log("while_stat: begin/condition")
916 self:expr(v) -- parse condition
917 self:enterblock(true)
918 self:check("do")
919 self:log("while_stat: block")
920 self:block()
921 self:check_match("end", "while", line)
922 self:leaveblock()
923 self:log("while_stat: end")
924 end
925 --------------------------------------------------------------------
926 -- parse a repeat-until control structure, body parsed by block()
927 -- * used in stat()
928 --------------------------------------------------------------------
929 function luaY:repeat_stat()
930 -- stat -> repeat_stat -> REPEAT block UNTIL cond
931 local line = line
932 local v = {}
933 self:log("repeat_stat: begin")
934 self:enterblock(true)
935 self:next()
936 self:block()
937 self:check_match("until", "repeat", line)
938 self:log("repeat_stat: condition")
939 self:cond(v)
940 self:leaveblock()
941 self:log("repeat_stat: end")
942 end
943 --------------------------------------------------------------------
944 -- parse an if control structure
945 -- * used in stat()
946 --------------------------------------------------------------------
947 function luaY:if_stat()
948 -- stat -> if_stat -> IF cond THEN block
949 -- {ELSEIF cond THEN block} [ELSE block] END
950 local line = line
951 local v = {}
952 self:log("if_stat: if...then")
953 self:test_then_block(v) -- IF cond THEN block
954 while tok == "elseif" do
955 self:log("if_stat: elseif...then")
956 self:test_then_block(v) -- ELSEIF cond THEN block
957 end
958 if tok == "else" then
959 self:log("if_stat: else...")
960 self:next() -- skip ELSE
961 self:block() -- 'else' part
962 end
963 self:check_match("end", "if", line)
964 self:log("if_stat: end")
965 end
966 --------------------------------------------------------------------
967 -- parse a return statement
968 -- * used in stat()
969 --------------------------------------------------------------------
970 function luaY:return_stat()
971 -- stat -> return_stat -> RETURN explist
972 local e = {}
973 self:next() -- skip RETURN
974 local c = tok
975 if block_follow[c] or c == ";" then
976 -- return no values
977 self:log("return_stat: no return values")
978 else
979 self:log("return_stat: begin")
980 self:explist1(e) -- optional return values
981 self:log("return_stat: end")
982 end
983 end
984 --------------------------------------------------------------------
985 -- parse a break statement
986 -- * used in stat()
987 --------------------------------------------------------------------
988 function luaY:break_stat()
989 -- stat -> break_stat -> BREAK
990 local bl = fs.bl
991 self:next() -- skip BREAK
992 while bl and not bl.isbreakable do -- find a breakable block
993 bl = bl.prev
994 end
995 if not bl then
996 self:syntaxerror("no loop to break")
997 end
998 self:log("break_stat: -- break out of loop")
999 end
1000 --------------------------------------------------------------------
1001 -- parse a function call with no returns or an assignment statement
1002 -- * the struct with .prev is used for name searching in lparse.c,
1003 -- so it is retained for now; present in assignment() also
1004 -- * used in stat()
1005 --------------------------------------------------------------------
1006 function luaY:expr_stat()
1007 -- stat -> expr_stat -> func | assignment
1008 local v = {}
1009 v.v = {}
1010 self:primaryexp(v.v)
1011 if v.v.k == "VCALL" then -- stat -> func
1012 -- call statement uses no results
1013 self:log("expr_stat: function call k='"..v.v.k.."'")
1014 else -- stat -> assignment
1015 self:log("expr_stat: assignment k='"..v.v.k.."'")
1016 v.prev = nil
1017 self:assignment(v)
1018 end
1019 end
1020 --------------------------------------------------------------------
1021 -- parse a function statement
1022 -- * used in stat()
1023 --------------------------------------------------------------------
1024 function luaY:function_stat()
1025 -- stat -> function_stat -> FUNCTION funcname body
1026 local line = line
1027 local v, b = {}, {}
1028 self:log("function_stat: begin")
1029 self:next() -- skip FUNCTION
1030 local needself = self:funcname(v)
1031 self:log("function_stat: body needself='"..tostring(needself).."'")
1032 self:body(b, needself, line)
1033 self:log("function_stat: end")
1034 end
1035 --------------------------------------------------------------------
1036 -- parse a simple block enclosed by a DO..END pair
1037 -- * used in stat()
1038 --------------------------------------------------------------------
1039 function luaY:do_stat()
1040 -- stat -> do_stat -> DO block END
1041 self:next() -- skip DO
1042 self:log("do_stat: begin")
1043 self:block()
1044 self:log("do_stat: end")
1045 self:check_match("end", "do", line)
1046 end
1047 --------------------------------------------------------------------
1048 -- parse a statement starting with LOCAL
1049 -- * used in stat()
1050 --------------------------------------------------------------------
1051 function luaY:local_stat()
1052 -- stat -> local_stat -> LOCAL FUNCTION localfunc
1053 -- -> LOCAL localstat
1054 self:next() -- skip LOCAL
1055 if self:testnext("function") then -- local function?
1056 self:log("local_stat: local function")
1057 self:localfunc()
1058 else
1059 self:log("local_stat: local statement")
1060 self:localstat()
1061 end
1062 end
1063
1064--[[--------------------------------------------------------------------
1065-- main function, top level parsing functions
1066-- * [entry] -> parser() -> chunk() -> stat()
1067----------------------------------------------------------------------]]
1068
1069 --------------------------------------------------------------------
1070 -- initial parsing for statements, calls '_stat' suffixed functions
1071 -- * used in chunk()
1072 --------------------------------------------------------------------
1073 function luaY:stat()
1074 line = luaX.ln
1075 local c = tok
1076 local fn = stat_call[c]
1077 -- handles: if while do for repeat function local return break
1078 if fn then
1079 self:log("-- STATEMENT: begin '"..c.."' line="..line)
1080 self[fn](self)
1081 self:log("-- STATEMENT: end '"..c.."'")
1082 -- return or break must be last statement
1083 if c == "return" or c == "break" then return true end
1084 else
1085 self:log("-- STATEMENT: begin 'expr' line="..line)
1086 self:expr_stat()
1087 self:log("-- STATEMENT: end 'expr'")
1088 end
1089 self:log("")
1090 return false
1091 end
1092 --------------------------------------------------------------------
1093 -- parse a chunk, which consists of a bunch of statements
1094 -- * used in parser(), body(), block()
1095 --------------------------------------------------------------------
1096 function luaY:chunk()
1097 -- chunk -> { stat [';'] }
1098 self:log("chunk:")
1099 local islast = false
1100 while not islast and not block_follow[tok] do
1101 islast = self:stat()
1102 self:testnext(";")
1103 end
1104 end
1105 --------------------------------------------------------------------
1106 -- performs parsing, returns parsed data structure
1107 --------------------------------------------------------------------
1108 function luaY:parser()
1109 self:log("-- TOP: begin")
1110 self:open_func()
1111 self:log("")
1112 self:next() -- read first token
1113 self:chunk()
1114 self:check_condition(tok == "<eof>", "<eof> expected")
1115 self:close_func()
1116 self:log("-- TOP: end")
1117 return top_fs
1118 end
1119 --------------------------------------------------------------------
1120 return luaY -- return actual module to user, done
1121end