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