@rbxts/zyntex-sdk 1.0.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4449 +0,0 @@
1
- -- Adapted from the amazing Yueliang project
2
- -- http://yueliang.luaforge.net/
3
-
4
- --[[--------------------------------------------------------------------
5
-
6
- luac.lua
7
- Primitive luac in Lua
8
- This file is part of Yueliang.
9
-
10
- Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
11
- The COPYRIGHT file describes the conditions
12
- under which this software may be distributed.
13
-
14
- See the ChangeLog for more information.
15
-
16
- ----------------------------------------------------------------------]]
17
-
18
- --[[--------------------------------------------------------------------
19
- -- Notes:
20
- -- * based on luac.lua in the test directory of the 5.1.2 distribution
21
- -- * usage: lua luac.lua file.lua
22
- ----------------------------------------------------------------------]]
23
-
24
- ------------------------------------------------------------------------
25
- -- load and initialize the required modules
26
- ------------------------------------------------------------------------
27
- local luaZ = {}
28
- local luaY = {}
29
- local luaX = {}
30
- local luaP = {}
31
- local luaU = {}
32
- local luaK = {}
33
- local size_size_t = 8
34
-
35
- -- currently asserts are enabled because the codebase hasn't been tested
36
- -- much (if you don't want asserts, just comment them out)
37
- local function lua_assert(test)
38
- if not test then
39
- error("assertion failed!")
40
- end
41
- end
42
-
43
- -- dofile("lzio.lua")
44
-
45
- ------------------------------------------------------------------------
46
- -- * reader() should return a string, or nil if nothing else to parse.
47
- -- Additional data can be set only during stream initialization
48
- -- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string)
49
- -- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h)
50
- -- * Original Reader typedef:
51
- -- const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
52
- -- * This Lua chunk reader implementation:
53
- -- returns string or nil, no arguments to function
54
- ------------------------------------------------------------------------
55
-
56
- ------------------------------------------------------------------------
57
- -- create a chunk reader from a source string
58
- ------------------------------------------------------------------------
59
- function luaZ:make_getS(buff)
60
- local b = buff
61
- return function() -- chunk reader anonymous function here
62
- if not b then
63
- return nil
64
- end
65
- local data = b
66
- b = nil
67
- return data
68
- end
69
- end
70
-
71
- ------------------------------------------------------------------------
72
- -- create a chunk reader from a source file
73
- ------------------------------------------------------------------------
74
- -- function luaZ:make_getF(filename)
75
- -- local LUAL_BUFFERSIZE = 512
76
- -- local h = io.open(filename, "r")
77
- -- if not h then return nil end
78
- -- return function() -- chunk reader anonymous function here
79
- -- if not h or io.type(h) == "closed file" then return nil end
80
- -- local buff = h:read(LUAL_BUFFERSIZE)
81
- -- if not buff then h:close(); h = nil end
82
- -- return buff
83
- -- end
84
- -- end
85
-
86
- function luaZ:make_getF(source)
87
- local LUAL_BUFFERSIZE = 512
88
- local pos = 1
89
-
90
- return function() -- chunk reader anonymous function here
91
- local buff = source:sub(pos, pos + LUAL_BUFFERSIZE - 1)
92
- pos = math.min(#source + 1, pos + LUAL_BUFFERSIZE)
93
- return buff
94
- end
95
- end
96
-
97
- ------------------------------------------------------------------------
98
- -- creates a zio input stream
99
- -- returns the ZIO structure, z
100
- ------------------------------------------------------------------------
101
- function luaZ:init(reader, data)
102
- if not reader then
103
- return
104
- end
105
- local z = {}
106
- z.reader = reader
107
- z.data = data or ""
108
- z.name = name
109
- -- set up additional data for reading
110
- if not data or data == "" then
111
- z.n = 0
112
- else
113
- z.n = #data
114
- end
115
- z.p = 0
116
- return z
117
- end
118
-
119
- ------------------------------------------------------------------------
120
- -- fill up input buffer
121
- ------------------------------------------------------------------------
122
- function luaZ:fill(z)
123
- local buff = z.reader()
124
- z.data = buff
125
- if not buff or buff == "" then
126
- return "EOZ"
127
- end
128
- z.n, z.p = #buff - 1, 1
129
- return string.sub(buff, 1, 1)
130
- end
131
-
132
- ------------------------------------------------------------------------
133
- -- get next character from the input stream
134
- -- * local n, p are used to optimize code generation
135
- ------------------------------------------------------------------------
136
- function luaZ:zgetc(z)
137
- local n, p = z.n, z.p + 1
138
- if n > 0 then
139
- z.n, z.p = n - 1, p
140
- return string.sub(z.data, p, p)
141
- else
142
- return self:fill(z)
143
- end
144
- end
145
-
146
- -- dofile("llex.lua")
147
-
148
- -- FIRST_RESERVED is not required as tokens are manipulated as strings
149
- -- TOKEN_LEN deleted; maximum length of a reserved word not needed
150
-
151
- ------------------------------------------------------------------------
152
- -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
153
- ------------------------------------------------------------------------
154
-
155
- -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
156
- -- other terminal symbols: TK_NAME to TK_EOS
157
- luaX.RESERVED = [[
158
- TK_AND and
159
- TK_BREAK break
160
- TK_DO do
161
- TK_ELSE else
162
- TK_ELSEIF elseif
163
- TK_END end
164
- TK_FALSE false
165
- TK_FOR for
166
- TK_FUNCTION function
167
- TK_IF if
168
- TK_IN in
169
- TK_LOCAL local
170
- TK_NIL nil
171
- TK_NOT not
172
- TK_OR or
173
- TK_REPEAT repeat
174
- TK_RETURN return
175
- TK_THEN then
176
- TK_TRUE true
177
- TK_UNTIL until
178
- TK_WHILE while
179
- TK_CONCAT ..
180
- TK_DOTS ...
181
- TK_EQ ==
182
- TK_GE >=
183
- TK_LE <=
184
- TK_NE ~=
185
- TK_NAME <name>
186
- TK_NUMBER <number>
187
- TK_STRING <string>
188
- TK_EOS <eof>]]
189
-
190
- -- NUM_RESERVED is not required; number of reserved words
191
-
192
- --[[--------------------------------------------------------------------
193
- -- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed
194
- -- so that lexer functions can use its table element, ls.t.seminfo
195
- --
196
- -- SemInfo (struct no longer needed, a mixed-type value is used)
197
- --
198
- -- Token (struct of ls.t and ls.lookahead):
199
- -- token -- token symbol
200
- -- seminfo -- semantics information
201
- --
202
- -- LexState (struct of ls; ls is initialized by luaX:setinput):
203
- -- current -- current character (charint)
204
- -- linenumber -- input line counter
205
- -- lastline -- line of last token 'consumed'
206
- -- t -- current token (table: struct Token)
207
- -- lookahead -- look ahead token (table: struct Token)
208
- -- fs -- 'FuncState' is private to the parser
209
- -- L -- LuaState
210
- -- z -- input stream
211
- -- buff -- buffer for tokens
212
- -- source -- current source name
213
- -- decpoint -- locale decimal point
214
- -- nestlevel -- level of nested non-terminals
215
- ----------------------------------------------------------------------]]
216
-
217
- -- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init
218
-
219
- luaX.MAXSRC = 80
220
- luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above)
221
- luaX.LUA_QS = "'%s'"
222
- luaX.LUA_COMPAT_LSTR = 1
223
- --luaX.MAX_SIZET = 4294967293
224
-
225
- ------------------------------------------------------------------------
226
- -- initialize lexer
227
- -- * original luaX_init has code to create and register token strings
228
- -- * luaX.tokens: TK_* -> token
229
- -- * luaX.enums: token -> TK_* (used in luaX:llex)
230
- ------------------------------------------------------------------------
231
- function luaX:init()
232
- local tokens, enums = {}, {}
233
- for v in string.gmatch(self.RESERVED, "[^\n]+") do
234
- local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
235
- tokens[tok] = str
236
- enums[str] = tok
237
- end
238
- self.tokens = tokens
239
- self.enums = enums
240
- end
241
-
242
- ------------------------------------------------------------------------
243
- -- returns a suitably-formatted chunk name or id
244
- -- * from lobject.c, used in llex.c and ldebug.c
245
- -- * the result, out, is returned (was first argument)
246
- ------------------------------------------------------------------------
247
- function luaX:chunkid(source, bufflen)
248
- local out
249
- local first = string.sub(source, 1, 1)
250
- if first == "=" then
251
- out = string.sub(source, 2, bufflen) -- remove first char
252
- else -- out = "source", or "...source"
253
- if first == "@" then
254
- source = string.sub(source, 2) -- skip the '@'
255
- bufflen = bufflen - #" '...' "
256
- local l = #source
257
- out = ""
258
- if l > bufflen then
259
- source = string.sub(source, 1 + l - bufflen) -- get last part of file name
260
- out = out .. "..."
261
- end
262
- out = out .. source
263
- else -- out = [string "string"]
264
- local len = string.find(source, "[\n\r]") -- stop at first newline
265
- len = len and (len - 1) or #source
266
- bufflen = bufflen - #' [string "..."] '
267
- if len > bufflen then
268
- len = bufflen
269
- end
270
- out = '[string "'
271
- if len < #source then -- must truncate?
272
- out = out .. string.sub(source, 1, len) .. "..."
273
- else
274
- out = out .. source
275
- end
276
- out = out .. '"]'
277
- end
278
- end
279
- return out
280
- end
281
-
282
- --[[--------------------------------------------------------------------
283
- -- Support functions for lexer
284
- -- * all lexer errors eventually reaches lexerror:
285
- syntaxerror -> lexerror
286
- ----------------------------------------------------------------------]]
287
-
288
- ------------------------------------------------------------------------
289
- -- look up token and return keyword if found (also called by parser)
290
- ------------------------------------------------------------------------
291
- function luaX:token2str(ls, token)
292
- if string.sub(token, 1, 3) ~= "TK_" then
293
- if string.find(token, "%c") then
294
- return string.format("char(%d)", string.byte(token))
295
- end
296
- return token
297
- else
298
- return self.tokens[token]
299
- end
300
- end
301
-
302
- ------------------------------------------------------------------------
303
- -- throws a lexer error
304
- -- * txtToken has been made local to luaX:lexerror
305
- -- * can't communicate LUA_ERRSYNTAX, so it is unimplemented
306
- ------------------------------------------------------------------------
307
- function luaX:lexerror(ls, msg, token)
308
- local function txtToken(ls, token)
309
- if token == "TK_NAME" or token == "TK_STRING" or token == "TK_NUMBER" then
310
- return ls.buff
311
- else
312
- return self:token2str(ls, token)
313
- end
314
- end
315
- local buff = self:chunkid(ls.source, self.MAXSRC)
316
- local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg)
317
- if token then
318
- msg = string.format("%s near " .. self.LUA_QS, msg, txtToken(ls, token))
319
- end
320
- -- luaD_throw(ls->L, LUA_ERRSYNTAX)
321
- error(msg)
322
- end
323
-
324
- ------------------------------------------------------------------------
325
- -- throws a syntax error (mainly called by parser)
326
- -- * ls.t.token has to be set by the function calling luaX:llex
327
- -- (see luaX:next and luaX:lookahead elsewhere in this file)
328
- ------------------------------------------------------------------------
329
- function luaX:syntaxerror(ls, msg)
330
- self:lexerror(ls, msg, ls.t.token)
331
- end
332
-
333
- ------------------------------------------------------------------------
334
- -- move on to next line
335
- ------------------------------------------------------------------------
336
- function luaX:currIsNewline(ls)
337
- return ls.current == "\n" or ls.current == "\r"
338
- end
339
-
340
- function luaX:inclinenumber(ls)
341
- local old = ls.current
342
- -- lua_assert(currIsNewline(ls))
343
- self:nextc(ls) -- skip '\n' or '\r'
344
- if self:currIsNewline(ls) and ls.current ~= old then
345
- self:nextc(ls) -- skip '\n\r' or '\r\n'
346
- end
347
- ls.linenumber = ls.linenumber + 1
348
- if ls.linenumber >= self.MAX_INT then
349
- self:syntaxerror(ls, "chunk has too many lines")
350
- end
351
- end
352
-
353
- ------------------------------------------------------------------------
354
- -- initializes an input stream for lexing
355
- -- * if ls (the lexer state) is passed as a table, then it is filled in,
356
- -- otherwise it has to be retrieved as a return value
357
- -- * LUA_MINBUFFER not used; buffer handling not required any more
358
- ------------------------------------------------------------------------
359
- function luaX:setinput(L, ls, z, source)
360
- if not ls then
361
- ls = {}
362
- end -- create struct
363
- if not ls.lookahead then
364
- ls.lookahead = {}
365
- end
366
- if not ls.t then
367
- ls.t = {}
368
- end
369
- ls.decpoint = "."
370
- ls.L = L
371
- ls.lookahead.token = "TK_EOS" -- no look-ahead token
372
- ls.z = z
373
- ls.fs = nil
374
- ls.linenumber = 1
375
- ls.lastline = 1
376
- ls.source = source
377
- self:nextc(ls) -- read first char
378
- end
379
-
380
- --[[--------------------------------------------------------------------
381
- -- LEXICAL ANALYZER
382
- ----------------------------------------------------------------------]]
383
-
384
- ------------------------------------------------------------------------
385
- -- checks if current character read is found in the set 'set'
386
- ------------------------------------------------------------------------
387
- function luaX:check_next(ls, set)
388
- if not string.find(set, ls.current, 1, 1) then
389
- return false
390
- end
391
- self:save_and_next(ls)
392
- return true
393
- end
394
-
395
- ------------------------------------------------------------------------
396
- -- retrieve next token, checking the lookahead buffer if necessary
397
- -- * note that the macro next(ls) in llex.c is now luaX:nextc
398
- -- * utilized used in lparser.c (various places)
399
- ------------------------------------------------------------------------
400
- function luaX:next(ls)
401
- ls.lastline = ls.linenumber
402
- if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token?
403
- -- this must be copy-by-value
404
- ls.t.seminfo = ls.lookahead.seminfo -- use this one
405
- ls.t.token = ls.lookahead.token
406
- ls.lookahead.token = "TK_EOS" -- and discharge it
407
- else
408
- ls.t.token = self:llex(ls, ls.t) -- read next token
409
- end
410
- end
411
-
412
- ------------------------------------------------------------------------
413
- -- fill in the lookahead buffer
414
- -- * utilized used in lparser.c:constructor
415
- ------------------------------------------------------------------------
416
- function luaX:lookahead(ls)
417
- -- lua_assert(ls.lookahead.token == "TK_EOS")
418
- ls.lookahead.token = self:llex(ls, ls.lookahead)
419
- end
420
-
421
- ------------------------------------------------------------------------
422
- -- gets the next character and returns it
423
- -- * this is the next() macro in llex.c; see notes at the beginning
424
- ------------------------------------------------------------------------
425
- function luaX:nextc(ls)
426
- local c = luaZ:zgetc(ls.z)
427
- ls.current = c
428
- return c
429
- end
430
-
431
- ------------------------------------------------------------------------
432
- -- saves the given character into the token buffer
433
- -- * buffer handling code removed, not used in this implementation
434
- -- * test for maximum token buffer length not used, makes things faster
435
- ------------------------------------------------------------------------
436
-
437
- function luaX:save(ls, c)
438
- local buff = ls.buff
439
- -- if you want to use this, please uncomment luaX.MAX_SIZET further up
440
- --if #buff > self.MAX_SIZET then
441
- -- self:lexerror(ls, "lexical element too long")
442
- --end
443
- ls.buff = buff .. c
444
- end
445
-
446
- ------------------------------------------------------------------------
447
- -- save current character into token buffer, grabs next character
448
- -- * like luaX:nextc, returns the character read for convenience
449
- ------------------------------------------------------------------------
450
- function luaX:save_and_next(ls)
451
- self:save(ls, ls.current)
452
- return self:nextc(ls)
453
- end
454
-
455
- ------------------------------------------------------------------------
456
- -- LUA_NUMBER
457
- -- * luaX:read_numeral is the main lexer function to read a number
458
- -- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions
459
- ------------------------------------------------------------------------
460
-
461
- ------------------------------------------------------------------------
462
- -- string to number converter (was luaO_str2d from lobject.c)
463
- -- * returns the number, nil if fails (originally returns a boolean)
464
- -- * conversion function originally lua_str2number(s,p), a macro which
465
- -- maps to the strtod() function by default (from luaconf.h)
466
- ------------------------------------------------------------------------
467
- function luaX:str2d(s)
468
- local result = tonumber(s)
469
- if result then
470
- return result
471
- end
472
- -- conversion failed
473
- if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant?
474
- result = tonumber(s, 16)
475
- if result then
476
- return result
477
- end -- most common case
478
- -- Was: invalid trailing characters?
479
- -- In C, this function then skips over trailing spaces.
480
- -- true is returned if nothing else is found except for spaces.
481
- -- If there is still something else, then it returns a false.
482
- -- All this is not necessary using Lua's tonumber.
483
- end
484
- return nil
485
- end
486
-
487
- ------------------------------------------------------------------------
488
- -- single-character replacement, for locale-aware decimal points
489
- ------------------------------------------------------------------------
490
- function luaX:buffreplace(ls, from, to)
491
- local result, buff = "", ls.buff
492
- for p = 1, #buff do
493
- local c = string.sub(buff, p, p)
494
- if c == from then
495
- c = to
496
- end
497
- result = result .. c
498
- end
499
- ls.buff = result
500
- end
501
-
502
- ------------------------------------------------------------------------
503
- -- Attempt to convert a number by translating '.' decimal points to
504
- -- the decimal point character used by the current locale. This is not
505
- -- needed in Yueliang as Lua's tonumber() is already locale-aware.
506
- -- Instead, the code is here in case the user implements localeconv().
507
- ------------------------------------------------------------------------
508
- function luaX:trydecpoint(ls, Token)
509
- -- format error: try to update decimal point separator
510
- local old = ls.decpoint
511
- -- translate the following to Lua if you implement localeconv():
512
- -- struct lconv *cv = localeconv();
513
- -- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
514
- self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator
515
- local seminfo = self:str2d(ls.buff)
516
- Token.seminfo = seminfo
517
- if not seminfo then
518
- -- format error with correct decimal point: no more options
519
- self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message)
520
- self:lexerror(ls, "malformed number", "TK_NUMBER")
521
- end
522
- end
523
-
524
- ------------------------------------------------------------------------
525
- -- main number conversion function
526
- -- * "^%w$" needed in the scan in order to detect "EOZ"
527
- ------------------------------------------------------------------------
528
- function luaX:read_numeral(ls, Token)
529
- -- lua_assert(string.find(ls.current, "%d"))
530
- repeat
531
- self:save_and_next(ls)
532
- until string.find(ls.current, "%D") and ls.current ~= "."
533
- if self:check_next(ls, "Ee") then -- 'E'?
534
- self:check_next(ls, "+-") -- optional exponent sign
535
- end
536
- while string.find(ls.current, "^%w$") or ls.current == "_" do
537
- self:save_and_next(ls)
538
- end
539
- self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point
540
- local seminfo = self:str2d(ls.buff)
541
- Token.seminfo = seminfo
542
- if not seminfo then -- format error?
543
- self:trydecpoint(ls, Token) -- try to update decimal point separator
544
- end
545
- end
546
-
547
- ------------------------------------------------------------------------
548
- -- count separators ("=") in a long string delimiter
549
- -- * used by luaX:read_long_string
550
- ------------------------------------------------------------------------
551
- function luaX:skip_sep(ls)
552
- local count = 0
553
- local s = ls.current
554
- -- lua_assert(s == "[" or s == "]")
555
- self:save_and_next(ls)
556
- while ls.current == "=" do
557
- self:save_and_next(ls)
558
- count = count + 1
559
- end
560
- return (ls.current == s) and count or -count - 1
561
- end
562
-
563
- ------------------------------------------------------------------------
564
- -- reads a long string or long comment
565
- ------------------------------------------------------------------------
566
- function luaX:read_long_string(ls, Token, sep)
567
- local cont = 0
568
- self:save_and_next(ls) -- skip 2nd '['
569
- if self:currIsNewline(ls) then -- string starts with a newline?
570
- self:inclinenumber(ls) -- skip it
571
- end
572
- while true do
573
- local c = ls.current
574
- if c == "EOZ" then
575
- self:lexerror(ls, Token and "unfinished long string" or "unfinished long comment", "TK_EOS")
576
- elseif c == "[" then
577
- --# compatibility code start
578
- if self.LUA_COMPAT_LSTR then
579
- if self:skip_sep(ls) == sep then
580
- self:save_and_next(ls) -- skip 2nd '['
581
- cont = cont + 1
582
- --# compatibility code start
583
- if self.LUA_COMPAT_LSTR == 1 then
584
- if sep == 0 then
585
- self:lexerror(ls, "nesting of [[...]] is deprecated", "[")
586
- end
587
- end
588
- --# compatibility code end
589
- end
590
- end
591
- --# compatibility code end
592
- elseif c == "]" then
593
- if self:skip_sep(ls) == sep then
594
- self:save_and_next(ls) -- skip 2nd ']'
595
- --# compatibility code start
596
- if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then
597
- cont = cont - 1
598
- if sep == 0 and cont >= 0 then
599
- break
600
- end
601
- end
602
- --# compatibility code end
603
- break
604
- end
605
- elseif self:currIsNewline(ls) then
606
- self:save(ls, "\n")
607
- self:inclinenumber(ls)
608
- if not Token then
609
- ls.buff = ""
610
- end -- avoid wasting space
611
- else -- default
612
- if Token then
613
- self:save_and_next(ls)
614
- else
615
- self:nextc(ls)
616
- end
617
- end --if c
618
- end --while
619
- if Token then
620
- local p = 3 + sep
621
- Token.seminfo = string.sub(ls.buff, p, -p)
622
- end
623
- end
624
-
625
- ------------------------------------------------------------------------
626
- -- reads a string
627
- -- * has been restructured significantly compared to the original C code
628
- ------------------------------------------------------------------------
629
-
630
- function luaX:read_string(ls, del, Token)
631
- self:save_and_next(ls)
632
- while ls.current ~= del do
633
- local c = ls.current
634
- if c == "EOZ" then
635
- self:lexerror(ls, "unfinished string", "TK_EOS")
636
- elseif self:currIsNewline(ls) then
637
- self:lexerror(ls, "unfinished string", "TK_STRING")
638
- elseif c == "\\" then
639
- c = self:nextc(ls) -- do not save the '\'
640
- if self:currIsNewline(ls) then -- go through
641
- self:save(ls, "\n")
642
- self:inclinenumber(ls)
643
- elseif c ~= "EOZ" then -- will raise an error next loop
644
- -- escapes handling greatly simplified here:
645
- local i = string.find("abfnrtv", c, 1, 1)
646
- if i then
647
- self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i))
648
- self:nextc(ls)
649
- elseif not string.find(c, "%d") then
650
- self:save_and_next(ls) -- handles \\, \", \', and \?
651
- else -- \xxx
652
- c, i = 0, 0
653
- repeat
654
- c = 10 * c + ls.current
655
- self:nextc(ls)
656
- i = i + 1
657
- until i >= 3 or not string.find(ls.current, "%d")
658
- if c > 255 then -- UCHAR_MAX
659
- self:lexerror(ls, "escape sequence too large", "TK_STRING")
660
- end
661
- self:save(ls, string.char(c))
662
- end
663
- end
664
- else
665
- self:save_and_next(ls)
666
- end --if c
667
- end --while
668
- self:save_and_next(ls) -- skip delimiter
669
- Token.seminfo = string.sub(ls.buff, 2, -2)
670
- end
671
-
672
- ------------------------------------------------------------------------
673
- -- main lexer function
674
- ------------------------------------------------------------------------
675
- function luaX:llex(ls, Token)
676
- ls.buff = ""
677
- while true do
678
- local c = ls.current
679
- ----------------------------------------------------------------
680
- if self:currIsNewline(ls) then
681
- self:inclinenumber(ls)
682
- ----------------------------------------------------------------
683
- elseif c == "-" then
684
- c = self:nextc(ls)
685
- if c ~= "-" then
686
- return "-"
687
- end
688
- -- else is a comment
689
- local sep = -1
690
- if self:nextc(ls) == "[" then
691
- sep = self:skip_sep(ls)
692
- ls.buff = "" -- 'skip_sep' may dirty the buffer
693
- end
694
- if sep >= 0 then
695
- self:read_long_string(ls, nil, sep) -- long comment
696
- ls.buff = ""
697
- else -- else short comment
698
- while not self:currIsNewline(ls) and ls.current ~= "EOZ" do
699
- self:nextc(ls)
700
- end
701
- end
702
- ----------------------------------------------------------------
703
- elseif c == "[" then
704
- local sep = self:skip_sep(ls)
705
- if sep >= 0 then
706
- self:read_long_string(ls, Token, sep)
707
- return "TK_STRING"
708
- elseif sep == -1 then
709
- return "["
710
- else
711
- self:lexerror(ls, "invalid long string delimiter", "TK_STRING")
712
- end
713
- ----------------------------------------------------------------
714
- elseif c == "=" then
715
- c = self:nextc(ls)
716
- if c ~= "=" then
717
- return "="
718
- else
719
- self:nextc(ls)
720
- return "TK_EQ"
721
- end
722
- ----------------------------------------------------------------
723
- elseif c == "<" then
724
- c = self:nextc(ls)
725
- if c ~= "=" then
726
- return "<"
727
- else
728
- self:nextc(ls)
729
- return "TK_LE"
730
- end
731
- ----------------------------------------------------------------
732
- elseif c == ">" then
733
- c = self:nextc(ls)
734
- if c ~= "=" then
735
- return ">"
736
- else
737
- self:nextc(ls)
738
- return "TK_GE"
739
- end
740
- ----------------------------------------------------------------
741
- elseif c == "~" then
742
- c = self:nextc(ls)
743
- if c ~= "=" then
744
- return "~"
745
- else
746
- self:nextc(ls)
747
- return "TK_NE"
748
- end
749
- ----------------------------------------------------------------
750
- elseif c == '"' or c == "'" then
751
- self:read_string(ls, c, Token)
752
- return "TK_STRING"
753
- ----------------------------------------------------------------
754
- elseif c == "." then
755
- c = self:save_and_next(ls)
756
- if self:check_next(ls, ".") then
757
- if self:check_next(ls, ".") then
758
- return "TK_DOTS" -- ...
759
- else
760
- return "TK_CONCAT" -- ..
761
- end
762
- elseif not string.find(c, "%d") then
763
- return "."
764
- else
765
- self:read_numeral(ls, Token)
766
- return "TK_NUMBER"
767
- end
768
- ----------------------------------------------------------------
769
- elseif c == "EOZ" then
770
- return "TK_EOS"
771
- ----------------------------------------------------------------
772
- else -- default
773
- if string.find(c, "%s") then
774
- -- lua_assert(self:currIsNewline(ls))
775
- self:nextc(ls)
776
- elseif string.find(c, "%d") then
777
- self:read_numeral(ls, Token)
778
- return "TK_NUMBER"
779
- elseif string.find(c, "[_%a]") then
780
- -- identifier or reserved word
781
- repeat
782
- c = self:save_and_next(ls)
783
- until c == "EOZ" or not string.find(c, "[_%w]")
784
- local ts = ls.buff
785
- local tok = self.enums[ts]
786
- if tok then
787
- return tok
788
- end -- reserved word?
789
- Token.seminfo = ts
790
- return "TK_NAME"
791
- else
792
- self:nextc(ls)
793
- return c -- single-char tokens (+ - / ...)
794
- end
795
- ----------------------------------------------------------------
796
- end --if c
797
- end --while
798
- end
799
-
800
- --dofile("lopcodes.lua")
801
-
802
- --[[
803
- ===========================================================================
804
- We assume that instructions are unsigned numbers.
805
- All instructions have an opcode in the first 6 bits.
806
- Instructions can have the following fields:
807
- 'A' : 8 bits
808
- 'B' : 9 bits
809
- 'C' : 9 bits
810
- 'Bx' : 18 bits ('B' and 'C' together)
811
- 'sBx' : signed Bx
812
-
813
- A signed argument is represented in excess K; that is, the number
814
- value is the unsigned value minus K. K is exactly the maximum value
815
- for that argument (so that -max is represented by 0, and +max is
816
- represented by 2*max), which is half the maximum for the corresponding
817
- unsigned argument.
818
- ===========================================================================
819
- --]]
820
-
821
- luaP.OpMode = { iABC = 0, iABx = 1, iAsBx = 2 } -- basic instruction format
822
-
823
- ------------------------------------------------------------------------
824
- -- size and position of opcode arguments.
825
- -- * WARNING size and position is hard-coded elsewhere in this script
826
- ------------------------------------------------------------------------
827
- luaP.SIZE_C = 9
828
- luaP.SIZE_B = 9
829
- luaP.SIZE_Bx = luaP.SIZE_C + luaP.SIZE_B
830
- luaP.SIZE_A = 8
831
-
832
- luaP.SIZE_OP = 6
833
-
834
- luaP.POS_OP = 0
835
- luaP.POS_A = luaP.POS_OP + luaP.SIZE_OP
836
- luaP.POS_C = luaP.POS_A + luaP.SIZE_A
837
- luaP.POS_B = luaP.POS_C + luaP.SIZE_C
838
- luaP.POS_Bx = luaP.POS_C
839
-
840
- ------------------------------------------------------------------------
841
- -- limits for opcode arguments.
842
- -- we use (signed) int to manipulate most arguments,
843
- -- so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
844
- ------------------------------------------------------------------------
845
- -- removed "#if SIZE_Bx < BITS_INT-1" test, assume this script is
846
- -- running on a Lua VM with double or int as LUA_NUMBER
847
-
848
- luaP.MAXARG_Bx = math.ldexp(1, luaP.SIZE_Bx) - 1
849
- luaP.MAXARG_sBx = math.floor(luaP.MAXARG_Bx / 2) -- 'sBx' is signed
850
-
851
- luaP.MAXARG_A = math.ldexp(1, luaP.SIZE_A) - 1
852
- luaP.MAXARG_B = math.ldexp(1, luaP.SIZE_B) - 1
853
- luaP.MAXARG_C = math.ldexp(1, luaP.SIZE_C) - 1
854
-
855
- -- creates a mask with 'n' 1 bits at position 'p'
856
- -- MASK1(n,p) deleted, not required
857
- -- creates a mask with 'n' 0 bits at position 'p'
858
- -- MASK0(n,p) deleted, not required
859
-
860
- --[[--------------------------------------------------------------------
861
- Visual representation for reference:
862
-
863
- 31 | | | 0 bit position
864
- +-----+-----+-----+----------+
865
- | B | C | A | Opcode | iABC format
866
- +-----+-----+-----+----------+
867
- - 9 - 9 - 8 - 6 - field sizes
868
- +-----+-----+-----+----------+
869
- | [s]Bx | A | Opcode | iABx | iAsBx format
870
- +-----+-----+-----+----------+
871
-
872
- ----------------------------------------------------------------------]]
873
-
874
- ------------------------------------------------------------------------
875
- -- the following macros help to manipulate instructions
876
- -- * changed to a table object representation, very clean compared to
877
- -- the [nightmare] alternatives of using a number or a string
878
- -- * Bx is a separate element from B and C, since there is never a need
879
- -- to split Bx in the parser or code generator
880
- ------------------------------------------------------------------------
881
-
882
- -- these accept or return opcodes in the form of string names
883
- function luaP:GET_OPCODE(i)
884
- return self.ROpCode[i.OP]
885
- end
886
- function luaP:SET_OPCODE(i, o)
887
- i.OP = self.OpCode[o]
888
- end
889
-
890
- function luaP:GETARG_A(i)
891
- return i.A
892
- end
893
- function luaP:SETARG_A(i, u)
894
- i.A = u
895
- end
896
-
897
- function luaP:GETARG_B(i)
898
- return i.B
899
- end
900
- function luaP:SETARG_B(i, b)
901
- i.B = b
902
- end
903
-
904
- function luaP:GETARG_C(i)
905
- return i.C
906
- end
907
- function luaP:SETARG_C(i, b)
908
- i.C = b
909
- end
910
-
911
- function luaP:GETARG_Bx(i)
912
- return i.Bx
913
- end
914
- function luaP:SETARG_Bx(i, b)
915
- i.Bx = b
916
- end
917
-
918
- function luaP:GETARG_sBx(i)
919
- return i.Bx - self.MAXARG_sBx
920
- end
921
- function luaP:SETARG_sBx(i, b)
922
- i.Bx = b + self.MAXARG_sBx
923
- end
924
-
925
- function luaP:CREATE_ABC(o, a, b, c)
926
- return { OP = self.OpCode[o], A = a, B = b, C = c }
927
- end
928
-
929
- function luaP:CREATE_ABx(o, a, bc)
930
- return { OP = self.OpCode[o], A = a, Bx = bc }
931
- end
932
-
933
- ------------------------------------------------------------------------
934
- -- create an instruction from a number (for OP_SETLIST)
935
- ------------------------------------------------------------------------
936
- function luaP:CREATE_Inst(c)
937
- local o = c % 64
938
- c = (c - o) / 64
939
- local a = c % 256
940
- c = (c - a) / 256
941
- return self:CREATE_ABx(o, a, c)
942
- end
943
-
944
- ------------------------------------------------------------------------
945
- -- returns a 4-char string little-endian encoded form of an instruction
946
- ------------------------------------------------------------------------
947
- function luaP:Instruction(i)
948
- if i.Bx then
949
- -- change to OP/A/B/C format
950
- i.C = i.Bx % 512
951
- i.B = (i.Bx - i.C) / 512
952
- end
953
- local I = i.A * 64 + i.OP
954
- local c0 = I % 256
955
- I = i.C * 64 + (I - c0) / 256 -- 6 bits of A left
956
- local c1 = I % 256
957
- I = i.B * 128 + (I - c1) / 256 -- 7 bits of C left
958
- local c2 = I % 256
959
- local c3 = (I - c2) / 256
960
- return string.char(c0, c1, c2, c3)
961
- end
962
-
963
- ------------------------------------------------------------------------
964
- -- decodes a 4-char little-endian string into an instruction struct
965
- ------------------------------------------------------------------------
966
- function luaP:DecodeInst(x)
967
- local byte = string.byte
968
- local i = {}
969
- local I = byte(x, 1)
970
- local op = I % 64
971
- i.OP = op
972
- I = byte(x, 2) * 4 + (I - op) / 64 -- 2 bits of c0 left
973
- local a = I % 256
974
- i.A = a
975
- I = byte(x, 3) * 4 + (I - a) / 256 -- 2 bits of c1 left
976
- local c = I % 512
977
- i.C = c
978
- i.B = byte(x, 4) * 2 + (I - c) / 512 -- 1 bits of c2 left
979
- local opmode = self.OpMode[tonumber(string.sub(self.opmodes[op + 1], 7, 7))]
980
- if opmode ~= "iABC" then
981
- i.Bx = i.B * 512 + i.C
982
- end
983
- return i
984
- end
985
-
986
- ------------------------------------------------------------------------
987
- -- Macros to operate RK indices
988
- -- * these use arithmetic instead of bit ops
989
- ------------------------------------------------------------------------
990
-
991
- -- this bit 1 means constant (0 means register)
992
- luaP.BITRK = math.ldexp(1, luaP.SIZE_B - 1)
993
-
994
- -- test whether value is a constant
995
- function luaP:ISK(x)
996
- return x >= self.BITRK
997
- end
998
-
999
- -- gets the index of the constant
1000
- function luaP:INDEXK(r)
1001
- return x - self.BITRK
1002
- end
1003
-
1004
- luaP.MAXINDEXRK = luaP.BITRK - 1
1005
-
1006
- -- code a constant index as a RK value
1007
- function luaP:RKASK(x)
1008
- return x + self.BITRK
1009
- end
1010
-
1011
- ------------------------------------------------------------------------
1012
- -- invalid register that fits in 8 bits
1013
- ------------------------------------------------------------------------
1014
- luaP.NO_REG = luaP.MAXARG_A
1015
-
1016
- ------------------------------------------------------------------------
1017
- -- R(x) - register
1018
- -- Kst(x) - constant (in constant table)
1019
- -- RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
1020
- ------------------------------------------------------------------------
1021
-
1022
- ------------------------------------------------------------------------
1023
- -- grep "ORDER OP" if you change these enums
1024
- ------------------------------------------------------------------------
1025
-
1026
- --[[--------------------------------------------------------------------
1027
- Lua virtual machine opcodes (enum OpCode):
1028
- ------------------------------------------------------------------------
1029
- name args description
1030
- ------------------------------------------------------------------------
1031
- OP_MOVE A B R(A) := R(B)
1032
- OP_LOADK A Bx R(A) := Kst(Bx)
1033
- OP_LOADBOOL A B C R(A) := (Bool)B; if (C) pc++
1034
- OP_LOADNIL A B R(A) := ... := R(B) := nil
1035
- OP_GETUPVAL A B R(A) := UpValue[B]
1036
- OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)]
1037
- OP_GETTABLE A B C R(A) := R(B)[RK(C)]
1038
- OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A)
1039
- OP_SETUPVAL A B UpValue[B] := R(A)
1040
- OP_SETTABLE A B C R(A)[RK(B)] := RK(C)
1041
- OP_NEWTABLE A B C R(A) := {} (size = B,C)
1042
- OP_SELF A B C R(A+1) := R(B); R(A) := R(B)[RK(C)]
1043
- OP_ADD A B C R(A) := RK(B) + RK(C)
1044
- OP_SUB A B C R(A) := RK(B) - RK(C)
1045
- OP_MUL A B C R(A) := RK(B) * RK(C)
1046
- OP_DIV A B C R(A) := RK(B) / RK(C)
1047
- OP_MOD A B C R(A) := RK(B) % RK(C)
1048
- OP_POW A B C R(A) := RK(B) ^ RK(C)
1049
- OP_UNM A B R(A) := -R(B)
1050
- OP_NOT A B R(A) := not R(B)
1051
- OP_LEN A B R(A) := length of R(B)
1052
- OP_CONCAT A B C R(A) := R(B).. ... ..R(C)
1053
- OP_JMP sBx pc+=sBx
1054
- OP_EQ A B C if ((RK(B) == RK(C)) ~= A) then pc++
1055
- OP_LT A B C if ((RK(B) < RK(C)) ~= A) then pc++
1056
- OP_LE A B C if ((RK(B) <= RK(C)) ~= A) then pc++
1057
- OP_TEST A C if not (R(A) <=> C) then pc++
1058
- OP_TESTSET A B C if (R(B) <=> C) then R(A) := R(B) else pc++
1059
- OP_CALL A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))
1060
- OP_TAILCALL A B C return R(A)(R(A+1), ... ,R(A+B-1))
1061
- OP_RETURN A B return R(A), ... ,R(A+B-2) (see note)
1062
- OP_FORLOOP A sBx R(A)+=R(A+2);
1063
- if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
1064
- OP_FORPREP A sBx R(A)-=R(A+2); pc+=sBx
1065
- OP_TFORLOOP A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
1066
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++
1067
- OP_SETLIST A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
1068
- OP_CLOSE A close all variables in the stack up to (>=) R(A)
1069
- OP_CLOSURE A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))
1070
- OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg
1071
- ----------------------------------------------------------------------]]
1072
-
1073
- luaP.opnames = {} -- opcode names
1074
- luaP.OpCode = {} -- lookup name -> number
1075
- luaP.ROpCode = {} -- lookup number -> name
1076
-
1077
- ------------------------------------------------------------------------
1078
- -- ORDER OP
1079
- ------------------------------------------------------------------------
1080
- local i = 0
1081
- for v in
1082
- string.gmatch(
1083
- [[
1084
- MOVE LOADK LOADBOOL LOADNIL GETUPVAL
1085
- GETGLOBAL GETTABLE SETGLOBAL SETUPVAL SETTABLE
1086
- NEWTABLE SELF ADD SUB MUL
1087
- DIV MOD POW UNM NOT
1088
- LEN CONCAT JMP EQ LT
1089
- LE TEST TESTSET CALL TAILCALL
1090
- RETURN FORLOOP FORPREP TFORLOOP SETLIST
1091
- CLOSE CLOSURE VARARG
1092
- ]],
1093
- "%S+"
1094
- )
1095
- do
1096
- local n = "OP_" .. v
1097
- luaP.opnames[i] = v
1098
- luaP.OpCode[n] = i
1099
- luaP.ROpCode[i] = n
1100
- i = i + 1
1101
- end
1102
- luaP.NUM_OPCODES = i
1103
-
1104
- --[[
1105
- ===========================================================================
1106
- Notes:
1107
- (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
1108
- and can be 0: OP_CALL then sets 'top' to last_result+1, so
1109
- next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
1110
- (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
1111
- set top (like in OP_CALL with C == 0).
1112
- (*) In OP_RETURN, if (B == 0) then return up to 'top'
1113
- (*) In OP_SETLIST, if (B == 0) then B = 'top';
1114
- if (C == 0) then next 'instruction' is real C
1115
- (*) For comparisons, A specifies what condition the test should accept
1116
- (true or false).
1117
- (*) All 'skips' (pc++) assume that next instruction is a jump
1118
- ===========================================================================
1119
- --]]
1120
-
1121
- --[[--------------------------------------------------------------------
1122
- masks for instruction properties. The format is:
1123
- bits 0-1: op mode
1124
- bits 2-3: C arg mode
1125
- bits 4-5: B arg mode
1126
- bit 6: instruction set register A
1127
- bit 7: operator is a test
1128
-
1129
- for OpArgMask:
1130
- OpArgN - argument is not used
1131
- OpArgU - argument is used
1132
- OpArgR - argument is a register or a jump offset
1133
- OpArgK - argument is a constant or register/constant
1134
- ----------------------------------------------------------------------]]
1135
-
1136
- -- was enum OpArgMask
1137
- luaP.OpArgMask = { OpArgN = 0, OpArgU = 1, OpArgR = 2, OpArgK = 3 }
1138
-
1139
- ------------------------------------------------------------------------
1140
- -- e.g. to compare with symbols, luaP:getOpMode(...) == luaP.OpCode.iABC
1141
- -- * accepts opcode parameter as strings, e.g. "OP_MOVE"
1142
- ------------------------------------------------------------------------
1143
-
1144
- function luaP:getOpMode(m)
1145
- return self.opmodes[self.OpCode[m]] % 4
1146
- end
1147
-
1148
- function luaP:getBMode(m)
1149
- return math.floor(self.opmodes[self.OpCode[m]] / 16) % 4
1150
- end
1151
-
1152
- function luaP:getCMode(m)
1153
- return math.floor(self.opmodes[self.OpCode[m]] / 4) % 4
1154
- end
1155
-
1156
- function luaP:testAMode(m)
1157
- return math.floor(self.opmodes[self.OpCode[m]] / 64) % 2
1158
- end
1159
-
1160
- function luaP:testTMode(m)
1161
- return math.floor(self.opmodes[self.OpCode[m]] / 128)
1162
- end
1163
-
1164
- -- luaP_opnames[] is set above, as the luaP.opnames table
1165
-
1166
- -- number of list items to accumulate before a SETLIST instruction
1167
- luaP.LFIELDS_PER_FLUSH = 50
1168
-
1169
- ------------------------------------------------------------------------
1170
- -- build instruction properties array
1171
- -- * deliberately coded to look like the C equivalent
1172
- ------------------------------------------------------------------------
1173
- local function opmode(t, a, b, c, m)
1174
- local luaP = luaP
1175
- return t * 128 + a * 64 + luaP.OpArgMask[b] * 16 + luaP.OpArgMask[c] * 4 + luaP.OpMode[m]
1176
- end
1177
-
1178
- -- ORDER OP
1179
- luaP.opmodes = {
1180
- -- T A B C mode opcode
1181
- opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_LOADK
1182
- opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_LOADBOOL
1183
- opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LOADNIL
1184
- opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_GETUPVAL
1185
- opmode(0, 1, "OpArgK", "OpArgN", "iABx"), -- OP_GETGLOBAL
1186
- opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_GETTABLE
1187
- opmode(0, 0, "OpArgK", "OpArgN", "iABx"), -- OP_SETGLOBAL
1188
- opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_SETUPVAL
1189
- opmode(0, 0, "OpArgK", "OpArgK", "iABC"), -- OP_SETTABLE
1190
- opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_NEWTABLE
1191
- opmode(0, 1, "OpArgR", "OpArgK", "iABC"), -- OP_SELF
1192
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_ADD
1193
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_SUB
1194
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MUL
1195
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_DIV
1196
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_MOD
1197
- opmode(0, 1, "OpArgK", "OpArgK", "iABC"), -- OP_POW
1198
- opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_UNM
1199
- opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_NOT
1200
- opmode(0, 1, "OpArgR", "OpArgN", "iABC"), -- OP_LEN
1201
- opmode(0, 1, "OpArgR", "OpArgR", "iABC"), -- OP_CONCAT
1202
- opmode(0, 0, "OpArgR", "OpArgN", "iAsBx"), -- OP_JMP
1203
- opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_EQ
1204
- opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LT
1205
- opmode(1, 0, "OpArgK", "OpArgK", "iABC"), -- OP_LE
1206
- opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TEST
1207
- opmode(1, 1, "OpArgR", "OpArgU", "iABC"), -- OP_TESTSET
1208
- opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_CALL
1209
- opmode(0, 1, "OpArgU", "OpArgU", "iABC"), -- OP_TAILCALL
1210
- opmode(0, 0, "OpArgU", "OpArgN", "iABC"), -- OP_RETURN
1211
- opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORLOOP
1212
- opmode(0, 1, "OpArgR", "OpArgN", "iAsBx"), -- OP_FORPREP
1213
- opmode(1, 0, "OpArgN", "OpArgU", "iABC"), -- OP_TFORLOOP
1214
- opmode(0, 0, "OpArgU", "OpArgU", "iABC"), -- OP_SETLIST
1215
- opmode(0, 0, "OpArgN", "OpArgN", "iABC"), -- OP_CLOSE
1216
- opmode(0, 1, "OpArgU", "OpArgN", "iABx"), -- OP_CLOSURE
1217
- opmode(0, 1, "OpArgU", "OpArgN", "iABC"), -- OP_VARARG
1218
- }
1219
- -- an awkward way to set a zero-indexed table...
1220
- luaP.opmodes[0] = opmode(0, 1, "OpArgR", "OpArgN", "iABC") -- OP_MOVE
1221
-
1222
- --dofile("ldump.lua")
1223
-
1224
- --requires luaP
1225
-
1226
- -- mark for precompiled code ('<esc>Lua') (from lua.h)
1227
- luaU.LUA_SIGNATURE = "\27Lua"
1228
-
1229
- -- constants used by dumper (from lua.h)
1230
- luaU.LUA_TNUMBER = 3
1231
- luaU.LUA_TSTRING = 4
1232
- luaU.LUA_TNIL = 0
1233
- luaU.LUA_TBOOLEAN = 1
1234
- luaU.LUA_TNONE = -1
1235
-
1236
- -- constants for header of binary files (from lundump.h)
1237
- luaU.LUAC_VERSION = 0x51 -- this is Lua 5.1
1238
- luaU.LUAC_FORMAT = 0 -- this is the official format
1239
- luaU.LUAC_HEADERSIZE = 12 -- size of header of binary files
1240
-
1241
- --[[--------------------------------------------------------------------
1242
- -- Additional functions to handle chunk writing
1243
- -- * to use make_setS and make_setF, see test_ldump.lua elsewhere
1244
- ----------------------------------------------------------------------]]
1245
-
1246
- ------------------------------------------------------------------------
1247
- -- create a chunk writer that writes to a string
1248
- -- * returns the writer function and a table containing the string
1249
- -- * to get the final result, look in buff.data
1250
- ------------------------------------------------------------------------
1251
- function luaU:make_setS()
1252
- local buff = {}
1253
- buff.data = ""
1254
- local writer = function(s, buff) -- chunk writer
1255
- if not s then
1256
- return 0
1257
- end
1258
- buff.data = buff.data .. s
1259
- -- print (#buff.data, #s, string.byte(s,1,1), s)
1260
- return 0
1261
- end
1262
- return writer, buff
1263
- end
1264
-
1265
- ------------------------------------------------------------------------
1266
- -- create a chunk writer that writes to a file
1267
- -- * returns the writer function and a table containing the file handle
1268
- -- * if a nil is passed, then writer should close the open file
1269
- ------------------------------------------------------------------------
1270
- function luaU:make_setF(filename)
1271
- local buff = {}
1272
- buff.h = io.open(filename, "wb")
1273
- if not buff.h then
1274
- return nil
1275
- end
1276
- local writer = function(s, buff) -- chunk writer
1277
- if not buff.h then
1278
- return 0
1279
- end
1280
- if not s then
1281
- if buff.h:close() then
1282
- return 0
1283
- end
1284
- else
1285
- if buff.h:write(s) then
1286
- return 0
1287
- end
1288
- end
1289
- return 1
1290
- end
1291
- return writer, buff
1292
- end
1293
-
1294
- ------------------------------------------------------------------------
1295
- -- works like the lobject.h version except that TObject used in these
1296
- -- scripts only has a 'value' field, no 'tt' field (native types used)
1297
- ------------------------------------------------------------------------
1298
- function luaU:ttype(o)
1299
- local tt = type(o.value)
1300
- if tt == "number" then
1301
- return self.LUA_TNUMBER
1302
- elseif tt == "string" then
1303
- return self.LUA_TSTRING
1304
- elseif tt == "nil" then
1305
- return self.LUA_TNIL
1306
- elseif tt == "boolean" then
1307
- return self.LUA_TBOOLEAN
1308
- else
1309
- return self.LUA_TNONE -- the rest should not appear
1310
- end
1311
- end
1312
-
1313
- -----------------------------------------------------------------------
1314
- -- converts a IEEE754 double number to an 8-byte little-endian string
1315
- -- * luaU:from_double() and luaU:from_int() are adapted from ChunkBake
1316
- -- * supports +/- Infinity, but not denormals or NaNs
1317
- -----------------------------------------------------------------------
1318
- function luaU:from_double(x)
1319
- local function grab_byte(v)
1320
- local c = v % 256
1321
- return (v - c) / 256, string.char(c)
1322
- end
1323
- local sign = 0
1324
- if x < 0 then
1325
- sign = 1
1326
- x = -x
1327
- end
1328
- local mantissa, exponent = math.frexp(x)
1329
- if x == 0 then -- zero
1330
- mantissa, exponent = 0, 0
1331
- elseif x == 1 / 0 then
1332
- mantissa, exponent = 0, 2047
1333
- else
1334
- mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, 53)
1335
- exponent = exponent + 1022
1336
- end
1337
- local v, byte = "" -- convert to bytes
1338
- x = math.floor(mantissa)
1339
- for i = 1, 6 do
1340
- x, byte = grab_byte(x)
1341
- v = v .. byte -- 47:0
1342
- end
1343
- x, byte = grab_byte(exponent * 16 + x)
1344
- v = v .. byte -- 55:48
1345
- x, byte = grab_byte(sign * 128 + x)
1346
- v = v .. byte -- 63:56
1347
- return v
1348
- end
1349
-
1350
- -----------------------------------------------------------------------
1351
- -- converts a number to a little-endian 32-bit integer string
1352
- -- * input value assumed to not overflow, can be signed/unsigned
1353
- -----------------------------------------------------------------------
1354
- function luaU:from_int(x)
1355
- local v = ""
1356
- x = math.floor(x)
1357
- if x < 0 then
1358
- x = 4294967296 + x
1359
- end -- ULONG_MAX+1
1360
- for i = 1, 4 do
1361
- local c = x % 256
1362
- v = v .. string.char(c)
1363
- x = math.floor(x / 256)
1364
- end
1365
- return v
1366
- end
1367
-
1368
- --[[--------------------------------------------------------------------
1369
- -- Functions to make a binary chunk
1370
- -- * many functions have the size parameter removed, since output is
1371
- -- in the form of a string and some sizes are implicit or hard-coded
1372
- ----------------------------------------------------------------------]]
1373
-
1374
- --[[--------------------------------------------------------------------
1375
- -- struct DumpState:
1376
- -- L -- lua_State (not used in this script)
1377
- -- writer -- lua_Writer (chunk writer function)
1378
- -- data -- void* (chunk writer context or data already written)
1379
- -- strip -- if true, don't write any debug information
1380
- -- status -- if non-zero, an error has occured
1381
- ----------------------------------------------------------------------]]
1382
-
1383
- ------------------------------------------------------------------------
1384
- -- dumps a block of bytes
1385
- -- * lua_unlock(D.L), lua_lock(D.L) unused
1386
- ------------------------------------------------------------------------
1387
- function luaU:DumpBlock(b, D)
1388
- if D.status == 0 then
1389
- -- lua_unlock(D->L);
1390
- D.status = D.write(b, D.data)
1391
- -- lua_lock(D->L);
1392
- end
1393
- end
1394
-
1395
- ------------------------------------------------------------------------
1396
- -- dumps a char
1397
- ------------------------------------------------------------------------
1398
- function luaU:DumpChar(y, D)
1399
- self:DumpBlock(string.char(y), D)
1400
- end
1401
-
1402
- ------------------------------------------------------------------------
1403
- -- dumps a 32-bit signed or unsigned integer (for int) (hard-coded)
1404
- ------------------------------------------------------------------------
1405
- function luaU:DumpInt(x, D)
1406
- self:DumpBlock(self:from_int(x), D)
1407
- end
1408
-
1409
- ------------------------------------------------------------------------
1410
- -- dumps a 32-bit signed or unsigned integer (for int) (hard-coded)
1411
- ------------------------------------------------------------------------
1412
- function luaU:DumpSizeT(x, D)
1413
- self:DumpBlock(self:from_int(x), D)
1414
- if size_size_t == 8 then
1415
- self:DumpBlock(self:from_int(0), D)
1416
- end
1417
- end
1418
-
1419
- ------------------------------------------------------------------------
1420
- -- dumps a lua_Number (hard-coded as a double)
1421
- ------------------------------------------------------------------------
1422
- function luaU:DumpNumber(x, D)
1423
- self:DumpBlock(self:from_double(x), D)
1424
- end
1425
-
1426
- ------------------------------------------------------------------------
1427
- -- dumps a Lua string (size type is hard-coded)
1428
- ------------------------------------------------------------------------
1429
- function luaU:DumpString(s, D)
1430
- if s == nil then
1431
- self:DumpSizeT(0, D)
1432
- else
1433
- s = s .. "\0" -- include trailing '\0'
1434
- self:DumpSizeT(#s, D)
1435
- self:DumpBlock(s, D)
1436
- end
1437
- end
1438
-
1439
- ------------------------------------------------------------------------
1440
- -- dumps instruction block from function prototype
1441
- ------------------------------------------------------------------------
1442
- function luaU:DumpCode(f, D)
1443
- local n = f.sizecode
1444
- --was DumpVector
1445
- self:DumpInt(n, D)
1446
- for i = 0, n - 1 do
1447
- self:DumpBlock(luaP:Instruction(f.code[i]), D)
1448
- end
1449
- end
1450
-
1451
- ------------------------------------------------------------------------
1452
- -- dump constant pool from function prototype
1453
- -- * bvalue(o), nvalue(o) and rawtsvalue(o) macros removed
1454
- ------------------------------------------------------------------------
1455
- function luaU:DumpConstants(f, D)
1456
- local n = f.sizek
1457
- self:DumpInt(n, D)
1458
- for i = 0, n - 1 do
1459
- local o = f.k[i] -- TValue
1460
- local tt = self:ttype(o)
1461
- self:DumpChar(tt, D)
1462
- if tt == self.LUA_TNIL then
1463
- elseif tt == self.LUA_TBOOLEAN then
1464
- self:DumpChar(o.value and 1 or 0, D)
1465
- elseif tt == self.LUA_TNUMBER then
1466
- self:DumpNumber(o.value, D)
1467
- elseif tt == self.LUA_TSTRING then
1468
- self:DumpString(o.value, D)
1469
- else
1470
- --lua_assert(0) -- cannot happen
1471
- end
1472
- end
1473
- n = f.sizep
1474
- self:DumpInt(n, D)
1475
- for i = 0, n - 1 do
1476
- self:DumpFunction(f.p[i], f.source, D)
1477
- end
1478
- end
1479
-
1480
- ------------------------------------------------------------------------
1481
- -- dump debug information
1482
- ------------------------------------------------------------------------
1483
- function luaU:DumpDebug(f, D)
1484
- local n
1485
- n = D.strip and 0 or f.sizelineinfo -- dump line information
1486
- --was DumpVector
1487
- self:DumpInt(n, D)
1488
- for i = 0, n - 1 do
1489
- self:DumpInt(f.lineinfo[i], D)
1490
- end
1491
- n = D.strip and 0 or f.sizelocvars -- dump local information
1492
- self:DumpInt(n, D)
1493
- for i = 0, n - 1 do
1494
- self:DumpString(f.locvars[i].varname, D)
1495
- self:DumpInt(f.locvars[i].startpc, D)
1496
- self:DumpInt(f.locvars[i].endpc, D)
1497
- end
1498
- n = D.strip and 0 or f.sizeupvalues -- dump upvalue information
1499
- self:DumpInt(n, D)
1500
- for i = 0, n - 1 do
1501
- self:DumpString(f.upvalues[i], D)
1502
- end
1503
- end
1504
-
1505
- ------------------------------------------------------------------------
1506
- -- dump child function prototypes from function prototype
1507
- ------------------------------------------------------------------------
1508
- function luaU:DumpFunction(f, p, D)
1509
- local source = f.source
1510
- if source == p or D.strip then
1511
- source = nil
1512
- end
1513
- self:DumpString(source, D)
1514
- self:DumpInt(f.lineDefined, D)
1515
- self:DumpInt(f.lastlinedefined, D)
1516
- self:DumpChar(f.nups, D)
1517
- self:DumpChar(f.numparams, D)
1518
- self:DumpChar(f.is_vararg, D)
1519
- self:DumpChar(f.maxstacksize, D)
1520
- self:DumpCode(f, D)
1521
- self:DumpConstants(f, D)
1522
- self:DumpDebug(f, D)
1523
- end
1524
-
1525
- ------------------------------------------------------------------------
1526
- -- dump Lua header section (some sizes hard-coded)
1527
- ------------------------------------------------------------------------
1528
- function luaU:DumpHeader(D)
1529
- local h = self:header()
1530
- assert(#h == self.LUAC_HEADERSIZE) -- fixed buffer now an assert
1531
- self:DumpBlock(h, D)
1532
- end
1533
-
1534
- ------------------------------------------------------------------------
1535
- -- make header (from lundump.c)
1536
- -- returns the header string
1537
- ------------------------------------------------------------------------
1538
- function luaU:header()
1539
- local x = 1
1540
- return self.LUA_SIGNATURE
1541
- .. string.char(
1542
- self.LUAC_VERSION,
1543
- self.LUAC_FORMAT,
1544
- x, -- endianness (1=little)
1545
- 4, -- sizeof(int)
1546
- size_size_t, -- sizeof(size_t)
1547
- 4, -- sizeof(Instruction)
1548
- 8, -- sizeof(lua_Number)
1549
- 0
1550
- ) -- is lua_Number integral?
1551
- end
1552
-
1553
- ------------------------------------------------------------------------
1554
- -- dump Lua function as precompiled chunk
1555
- -- (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
1556
- -- * w, data are created from make_setS, make_setF
1557
- ------------------------------------------------------------------------
1558
- function luaU:dump(L, f, w, data, strip)
1559
- local D = {} -- DumpState
1560
- D.L = L
1561
- D.write = w
1562
- D.data = data
1563
- D.strip = strip
1564
- D.status = 0
1565
- self:DumpHeader(D)
1566
- self:DumpFunction(f, nil, D)
1567
- -- added: for a chunk writer writing to a file, this final call with
1568
- -- nil data is to indicate to the writer to close the file
1569
- D.write(nil, D.data)
1570
- return D.status
1571
- end
1572
-
1573
- --dofile("lcode.lua")
1574
-
1575
- ------------------------------------------------------------------------
1576
- -- constants used by code generator
1577
- ------------------------------------------------------------------------
1578
- -- maximum stack for a Lua function
1579
- luaK.MAXSTACK = 250 -- (from llimits.h)
1580
-
1581
- --[[--------------------------------------------------------------------
1582
- -- other functions
1583
- ----------------------------------------------------------------------]]
1584
-
1585
- ------------------------------------------------------------------------
1586
- -- emulation of TValue macros (these are from lobject.h)
1587
- -- * TValue is a table since lcode passes references around
1588
- -- * tt member field removed, using Lua's type() instead
1589
- -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
1590
- -- is used in an assert for testing, see checkliveness(g,obj)
1591
- ------------------------------------------------------------------------
1592
- function luaK:ttisnumber(o)
1593
- if o then
1594
- return type(o.value) == "number"
1595
- else
1596
- return false
1597
- end
1598
- end
1599
- function luaK:nvalue(o)
1600
- return o.value
1601
- end
1602
- function luaK:setnilvalue(o)
1603
- o.value = nil
1604
- end
1605
- function luaK:setsvalue(o, x)
1606
- o.value = x
1607
- end
1608
- luaK.setnvalue = luaK.setsvalue
1609
- luaK.sethvalue = luaK.setsvalue
1610
- luaK.setbvalue = luaK.setsvalue
1611
-
1612
- ------------------------------------------------------------------------
1613
- -- The luai_num* macros define the primitive operations over numbers.
1614
- -- * this is not the entire set of primitive operations from luaconf.h
1615
- -- * used in luaK:constfolding()
1616
- ------------------------------------------------------------------------
1617
- function luaK:numadd(a, b)
1618
- return a + b
1619
- end
1620
- function luaK:numsub(a, b)
1621
- return a - b
1622
- end
1623
- function luaK:nummul(a, b)
1624
- return a * b
1625
- end
1626
- function luaK:numdiv(a, b)
1627
- return a / b
1628
- end
1629
- function luaK:nummod(a, b)
1630
- return a % b
1631
- end
1632
- -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
1633
- function luaK:numpow(a, b)
1634
- return a ^ b
1635
- end
1636
- function luaK:numunm(a)
1637
- return -a
1638
- end
1639
- function luaK:numisnan(a)
1640
- return not a == a
1641
- end
1642
- -- a NaN cannot equal another NaN
1643
-
1644
- --[[--------------------------------------------------------------------
1645
- -- code generator functions
1646
- ----------------------------------------------------------------------]]
1647
-
1648
- ------------------------------------------------------------------------
1649
- -- Marks the end of a patch list. It is an invalid value both as an absolute
1650
- -- address, and as a list link (would link an element to itself).
1651
- ------------------------------------------------------------------------
1652
- luaK.NO_JUMP = -1
1653
-
1654
- ------------------------------------------------------------------------
1655
- -- grep "ORDER OPR" if you change these enums
1656
- ------------------------------------------------------------------------
1657
- luaK.BinOpr = {
1658
- OPR_ADD = 0,
1659
- OPR_SUB = 1,
1660
- OPR_MUL = 2,
1661
- OPR_DIV = 3,
1662
- OPR_MOD = 4,
1663
- OPR_POW = 5,
1664
- OPR_CONCAT = 6,
1665
- OPR_NE = 7,
1666
- OPR_EQ = 8,
1667
- OPR_LT = 9,
1668
- OPR_LE = 10,
1669
- OPR_GT = 11,
1670
- OPR_GE = 12,
1671
- OPR_AND = 13,
1672
- OPR_OR = 14,
1673
- OPR_NOBINOPR = 15,
1674
- }
1675
-
1676
- -- * UnOpr is used by luaK:prefix's op argument, but not directly used
1677
- -- because the function receives the symbols as strings, e.g. "OPR_NOT"
1678
- luaK.UnOpr = {
1679
- OPR_MINUS = 0,
1680
- OPR_NOT = 1,
1681
- OPR_LEN = 2,
1682
- OPR_NOUNOPR = 3,
1683
- }
1684
-
1685
- ------------------------------------------------------------------------
1686
- -- returns the instruction object for given e (expdesc), was a macro
1687
- ------------------------------------------------------------------------
1688
- function luaK:getcode(fs, e)
1689
- return fs.f.code[e.info]
1690
- end
1691
-
1692
- ------------------------------------------------------------------------
1693
- -- codes an instruction with a signed Bx (sBx) field, was a macro
1694
- -- * used in luaK:jump(), (lparser) luaY:forbody()
1695
- ------------------------------------------------------------------------
1696
- function luaK:codeAsBx(fs, o, A, sBx)
1697
- return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
1698
- end
1699
-
1700
- ------------------------------------------------------------------------
1701
- -- set the expdesc e instruction for multiple returns, was a macro
1702
- ------------------------------------------------------------------------
1703
- function luaK:setmultret(fs, e)
1704
- self:setreturns(fs, e, luaY.LUA_MULTRET)
1705
- end
1706
-
1707
- ------------------------------------------------------------------------
1708
- -- there is a jump if patch lists are not identical, was a macro
1709
- -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
1710
- ------------------------------------------------------------------------
1711
- function luaK:hasjumps(e)
1712
- return e.t ~= e.f
1713
- end
1714
-
1715
- ------------------------------------------------------------------------
1716
- -- true if the expression is a constant number (for constant folding)
1717
- -- * used in constfolding(), infix()
1718
- ------------------------------------------------------------------------
1719
- function luaK:isnumeral(e)
1720
- return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
1721
- end
1722
-
1723
- ------------------------------------------------------------------------
1724
- -- codes loading of nil, optimization done if consecutive locations
1725
- -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
1726
- ------------------------------------------------------------------------
1727
- function luaK:_nil(fs, from, n)
1728
- if fs.pc > fs.lasttarget then -- no jumps to current position?
1729
- if fs.pc == 0 then -- function start?
1730
- if from >= fs.nactvar then
1731
- return -- positions are already clean
1732
- end
1733
- else
1734
- local previous = fs.f.code[fs.pc - 1]
1735
- if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
1736
- local pfrom = luaP:GETARG_A(previous)
1737
- local pto = luaP:GETARG_B(previous)
1738
- if pfrom <= from and from <= pto + 1 then -- can connect both?
1739
- if from + n - 1 > pto then
1740
- luaP:SETARG_B(previous, from + n - 1)
1741
- end
1742
- return
1743
- end
1744
- end
1745
- end
1746
- end
1747
- self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
1748
- end
1749
-
1750
- ------------------------------------------------------------------------
1751
- --
1752
- -- * used in multiple locations
1753
- ------------------------------------------------------------------------
1754
- function luaK:jump(fs)
1755
- local jpc = fs.jpc -- save list of jumps to here
1756
- fs.jpc = self.NO_JUMP
1757
- local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
1758
- j = self:concat(fs, j, jpc) -- keep them on hold
1759
- return j
1760
- end
1761
-
1762
- ------------------------------------------------------------------------
1763
- -- codes a RETURN instruction
1764
- -- * used in luaY:close_func(), luaY:retstat()
1765
- ------------------------------------------------------------------------
1766
- function luaK:ret(fs, first, nret)
1767
- self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
1768
- end
1769
-
1770
- ------------------------------------------------------------------------
1771
- --
1772
- -- * used in luaK:jumponcond(), luaK:codecomp()
1773
- ------------------------------------------------------------------------
1774
- function luaK:condjump(fs, op, A, B, C)
1775
- self:codeABC(fs, op, A, B, C)
1776
- return self:jump(fs)
1777
- end
1778
-
1779
- ------------------------------------------------------------------------
1780
- --
1781
- -- * used in luaK:patchlistaux(), luaK:concat()
1782
- ------------------------------------------------------------------------
1783
- function luaK:fixjump(fs, pc, dest)
1784
- local jmp = fs.f.code[pc]
1785
- local offset = dest - (pc + 1)
1786
- lua_assert(dest ~= self.NO_JUMP)
1787
- if math.abs(offset) > luaP.MAXARG_sBx then
1788
- luaX:syntaxerror(fs.ls, "control structure too long")
1789
- end
1790
- luaP:SETARG_sBx(jmp, offset)
1791
- end
1792
-
1793
- ------------------------------------------------------------------------
1794
- -- returns current 'pc' and marks it as a jump target (to avoid wrong
1795
- -- optimizations with consecutive instructions not in the same basic block).
1796
- -- * used in multiple locations
1797
- -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
1798
- ------------------------------------------------------------------------
1799
- function luaK:getlabel(fs)
1800
- fs.lasttarget = fs.pc
1801
- return fs.pc
1802
- end
1803
-
1804
- ------------------------------------------------------------------------
1805
- --
1806
- -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
1807
- -- luaK:concat()
1808
- ------------------------------------------------------------------------
1809
- function luaK:getjump(fs, pc)
1810
- local offset = luaP:GETARG_sBx(fs.f.code[pc])
1811
- if offset == self.NO_JUMP then -- point to itself represents end of list
1812
- return self.NO_JUMP -- end of list
1813
- else
1814
- return (pc + 1) + offset -- turn offset into absolute position
1815
- end
1816
- end
1817
-
1818
- ------------------------------------------------------------------------
1819
- --
1820
- -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
1821
- ------------------------------------------------------------------------
1822
- function luaK:getjumpcontrol(fs, pc)
1823
- local pi = fs.f.code[pc]
1824
- local ppi = fs.f.code[pc - 1]
1825
- if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
1826
- return ppi
1827
- else
1828
- return pi
1829
- end
1830
- end
1831
-
1832
- ------------------------------------------------------------------------
1833
- -- check whether list has any jump that do not produce a value
1834
- -- (or produce an inverted value)
1835
- -- * return value changed to boolean
1836
- -- * used only in luaK:exp2reg()
1837
- ------------------------------------------------------------------------
1838
- function luaK:need_value(fs, list)
1839
- while list ~= self.NO_JUMP do
1840
- local i = self:getjumpcontrol(fs, list)
1841
- if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
1842
- return true
1843
- end
1844
- list = self:getjump(fs, list)
1845
- end
1846
- return false -- not found
1847
- end
1848
-
1849
- ------------------------------------------------------------------------
1850
- --
1851
- -- * used in luaK:removevalues(), luaK:patchlistaux()
1852
- ------------------------------------------------------------------------
1853
- function luaK:patchtestreg(fs, node, reg)
1854
- local i = self:getjumpcontrol(fs, node)
1855
- if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
1856
- return false -- cannot patch other instructions
1857
- end
1858
- if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
1859
- luaP:SETARG_A(i, reg)
1860
- else -- no register to put value or register already has the value
1861
- -- due to use of a table as i, i cannot be replaced by another table
1862
- -- so the following is required; there is no change to ARG_C
1863
- luaP:SET_OPCODE(i, "OP_TEST")
1864
- local b = luaP:GETARG_B(i)
1865
- luaP:SETARG_A(i, b)
1866
- luaP:SETARG_B(i, 0)
1867
- -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
1868
- end
1869
- return true
1870
- end
1871
-
1872
- ------------------------------------------------------------------------
1873
- --
1874
- -- * used only in luaK:codenot()
1875
- ------------------------------------------------------------------------
1876
- function luaK:removevalues(fs, list)
1877
- while list ~= self.NO_JUMP do
1878
- self:patchtestreg(fs, list, luaP.NO_REG)
1879
- list = self:getjump(fs, list)
1880
- end
1881
- end
1882
-
1883
- ------------------------------------------------------------------------
1884
- --
1885
- -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
1886
- ------------------------------------------------------------------------
1887
- function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
1888
- while list ~= self.NO_JUMP do
1889
- local _next = self:getjump(fs, list)
1890
- if self:patchtestreg(fs, list, reg) then
1891
- self:fixjump(fs, list, vtarget)
1892
- else
1893
- self:fixjump(fs, list, dtarget) -- jump to default target
1894
- end
1895
- list = _next
1896
- end
1897
- end
1898
-
1899
- ------------------------------------------------------------------------
1900
- --
1901
- -- * used only in luaK:code()
1902
- ------------------------------------------------------------------------
1903
- function luaK:dischargejpc(fs)
1904
- self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
1905
- fs.jpc = self.NO_JUMP
1906
- end
1907
-
1908
- ------------------------------------------------------------------------
1909
- --
1910
- -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
1911
- ------------------------------------------------------------------------
1912
- function luaK:patchlist(fs, list, target)
1913
- if target == fs.pc then
1914
- self:patchtohere(fs, list)
1915
- else
1916
- lua_assert(target < fs.pc)
1917
- self:patchlistaux(fs, list, target, luaP.NO_REG, target)
1918
- end
1919
- end
1920
-
1921
- ------------------------------------------------------------------------
1922
- --
1923
- -- * used in multiple locations
1924
- ------------------------------------------------------------------------
1925
- function luaK:patchtohere(fs, list)
1926
- self:getlabel(fs)
1927
- fs.jpc = self:concat(fs, fs.jpc, list)
1928
- end
1929
-
1930
- ------------------------------------------------------------------------
1931
- -- * l1 was a pointer, now l1 is returned and callee assigns the value
1932
- -- * used in multiple locations
1933
- ------------------------------------------------------------------------
1934
- function luaK:concat(fs, l1, l2)
1935
- if l2 == self.NO_JUMP then
1936
- return l1
1937
- elseif l1 == self.NO_JUMP then
1938
- return l2
1939
- else
1940
- local list = l1
1941
- local _next = self:getjump(fs, list)
1942
- while _next ~= self.NO_JUMP do -- find last element
1943
- list = _next
1944
- _next = self:getjump(fs, list)
1945
- end
1946
- self:fixjump(fs, list, l2)
1947
- end
1948
- return l1
1949
- end
1950
-
1951
- ------------------------------------------------------------------------
1952
- --
1953
- -- * used in luaK:reserveregs(), (lparser) luaY:forlist()
1954
- ------------------------------------------------------------------------
1955
- function luaK:checkstack(fs, n)
1956
- local newstack = fs.freereg + n
1957
- if newstack > fs.f.maxstacksize then
1958
- if newstack >= self.MAXSTACK then
1959
- luaX:syntaxerror(fs.ls, "function or expression too complex")
1960
- end
1961
- fs.f.maxstacksize = newstack
1962
- end
1963
- end
1964
-
1965
- ------------------------------------------------------------------------
1966
- --
1967
- -- * used in multiple locations
1968
- ------------------------------------------------------------------------
1969
- function luaK:reserveregs(fs, n)
1970
- self:checkstack(fs, n)
1971
- fs.freereg = fs.freereg + n
1972
- end
1973
-
1974
- ------------------------------------------------------------------------
1975
- --
1976
- -- * used in luaK:freeexp(), luaK:dischargevars()
1977
- ------------------------------------------------------------------------
1978
- function luaK:freereg(fs, reg)
1979
- if not luaP:ISK(reg) and reg >= fs.nactvar then
1980
- fs.freereg = fs.freereg - 1
1981
- lua_assert(reg == fs.freereg)
1982
- end
1983
- end
1984
-
1985
- ------------------------------------------------------------------------
1986
- --
1987
- -- * used in multiple locations
1988
- ------------------------------------------------------------------------
1989
- function luaK:freeexp(fs, e)
1990
- if e.k == "VNONRELOC" then
1991
- self:freereg(fs, e.info)
1992
- end
1993
- end
1994
-
1995
- ------------------------------------------------------------------------
1996
- -- * TODO NOTE implementation is not 100% correct, since the assert fails
1997
- -- * luaH_set, setobj deleted; direct table access used instead
1998
- -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
1999
- ------------------------------------------------------------------------
2000
- function luaK:addk(fs, k, v)
2001
- local L = fs.L
2002
- local idx = fs.h[k.value]
2003
- --TValue *idx = luaH_set(L, fs->h, k); /* C */
2004
- local f = fs.f
2005
- if self:ttisnumber(idx) then
2006
- --TODO this assert currently FAILS (last tested for 5.0.2)
2007
- --lua_assert(fs.f.k[self:nvalue(idx)] == v)
2008
- --lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
2009
- return self:nvalue(idx)
2010
- else -- constant not found; create a new entry
2011
- idx = {}
2012
- self:setnvalue(idx, fs.nk)
2013
- fs.h[k.value] = idx
2014
- -- setnvalue(idx, cast_num(fs->nk)); /* C */
2015
- luaY:growvector(L, f.k, fs.nk, f.sizek, nil, luaP.MAXARG_Bx, "constant table overflow")
2016
- -- loop to initialize empty f.k positions not required
2017
- f.k[fs.nk] = v
2018
- -- setobj(L, &f->k[fs->nk], v); /* C */
2019
- -- luaC_barrier(L, f, v); /* GC */
2020
- local nk = fs.nk
2021
- fs.nk = fs.nk + 1
2022
- return nk
2023
- end
2024
- end
2025
-
2026
- ------------------------------------------------------------------------
2027
- -- creates and sets a string object
2028
- -- * used in (lparser) luaY:codestring(), luaY:singlevar()
2029
- ------------------------------------------------------------------------
2030
- function luaK:stringK(fs, s)
2031
- local o = {} -- TValue
2032
- self:setsvalue(o, s)
2033
- return self:addk(fs, o, o)
2034
- end
2035
-
2036
- ------------------------------------------------------------------------
2037
- -- creates and sets a number object
2038
- -- * used in luaK:prefix() for negative (or negation of) numbers
2039
- -- * used in (lparser) luaY:simpleexp(), luaY:fornum()
2040
- ------------------------------------------------------------------------
2041
- function luaK:numberK(fs, r)
2042
- local o = {} -- TValue
2043
- self:setnvalue(o, r)
2044
- return self:addk(fs, o, o)
2045
- end
2046
-
2047
- ------------------------------------------------------------------------
2048
- -- creates and sets a boolean object
2049
- -- * used only in luaK:exp2RK()
2050
- ------------------------------------------------------------------------
2051
- function luaK:boolK(fs, b)
2052
- local o = {} -- TValue
2053
- self:setbvalue(o, b)
2054
- return self:addk(fs, o, o)
2055
- end
2056
-
2057
- ------------------------------------------------------------------------
2058
- -- creates and sets a nil object
2059
- -- * used only in luaK:exp2RK()
2060
- ------------------------------------------------------------------------
2061
- function luaK:nilK(fs)
2062
- local k, v = {}, {} -- TValue
2063
- self:setnilvalue(v)
2064
- -- cannot use nil as key; instead use table itself to represent nil
2065
- self:sethvalue(k, fs.h)
2066
- return self:addk(fs, k, v)
2067
- end
2068
-
2069
- ------------------------------------------------------------------------
2070
- --
2071
- -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
2072
- ------------------------------------------------------------------------
2073
- function luaK:setreturns(fs, e, nresults)
2074
- if e.k == "VCALL" then -- expression is an open function call?
2075
- luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
2076
- elseif e.k == "VVARARG" then
2077
- luaP:SETARG_B(self:getcode(fs, e), nresults + 1)
2078
- luaP:SETARG_A(self:getcode(fs, e), fs.freereg)
2079
- luaK:reserveregs(fs, 1)
2080
- end
2081
- end
2082
-
2083
- ------------------------------------------------------------------------
2084
- --
2085
- -- * used in luaK:dischargevars(), (lparser) luaY:assignment()
2086
- ------------------------------------------------------------------------
2087
- function luaK:setoneret(fs, e)
2088
- if e.k == "VCALL" then -- expression is an open function call?
2089
- e.k = "VNONRELOC"
2090
- e.info = luaP:GETARG_A(self:getcode(fs, e))
2091
- elseif e.k == "VVARARG" then
2092
- luaP:SETARG_B(self:getcode(fs, e), 2)
2093
- e.k = "VRELOCABLE" -- can relocate its simple result
2094
- end
2095
- end
2096
-
2097
- ------------------------------------------------------------------------
2098
- --
2099
- -- * used in multiple locations
2100
- ------------------------------------------------------------------------
2101
- function luaK:dischargevars(fs, e)
2102
- local k = e.k
2103
- if k == "VLOCAL" then
2104
- e.k = "VNONRELOC"
2105
- elseif k == "VUPVAL" then
2106
- e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
2107
- e.k = "VRELOCABLE"
2108
- elseif k == "VGLOBAL" then
2109
- e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
2110
- e.k = "VRELOCABLE"
2111
- elseif k == "VINDEXED" then
2112
- self:freereg(fs, e.aux)
2113
- self:freereg(fs, e.info)
2114
- e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
2115
- e.k = "VRELOCABLE"
2116
- elseif k == "VVARARG" or k == "VCALL" then
2117
- self:setoneret(fs, e)
2118
- else
2119
- -- there is one value available (somewhere)
2120
- end
2121
- end
2122
-
2123
- ------------------------------------------------------------------------
2124
- --
2125
- -- * used only in luaK:exp2reg()
2126
- ------------------------------------------------------------------------
2127
- function luaK:code_label(fs, A, b, jump)
2128
- self:getlabel(fs) -- those instructions may be jump targets
2129
- return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
2130
- end
2131
-
2132
- ------------------------------------------------------------------------
2133
- --
2134
- -- * used in luaK:discharge2anyreg(), luaK:exp2reg()
2135
- ------------------------------------------------------------------------
2136
- function luaK:discharge2reg(fs, e, reg)
2137
- self:dischargevars(fs, e)
2138
- local k = e.k
2139
- if k == "VNIL" then
2140
- self:_nil(fs, reg, 1)
2141
- elseif k == "VFALSE" or k == "VTRUE" then
2142
- self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
2143
- elseif k == "VK" then
2144
- self:codeABx(fs, "OP_LOADK", reg, e.info)
2145
- elseif k == "VKNUM" then
2146
- self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
2147
- elseif k == "VRELOCABLE" then
2148
- local pc = self:getcode(fs, e)
2149
- luaP:SETARG_A(pc, reg)
2150
- elseif k == "VNONRELOC" then
2151
- if reg ~= e.info then
2152
- self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
2153
- end
2154
- else
2155
- lua_assert(e.k == "VVOID" or e.k == "VJMP")
2156
- return -- nothing to do...
2157
- end
2158
- e.info = reg
2159
- e.k = "VNONRELOC"
2160
- end
2161
-
2162
- ------------------------------------------------------------------------
2163
- --
2164
- -- * used in luaK:jumponcond(), luaK:codenot()
2165
- ------------------------------------------------------------------------
2166
- function luaK:discharge2anyreg(fs, e)
2167
- if e.k ~= "VNONRELOC" then
2168
- self:reserveregs(fs, 1)
2169
- self:discharge2reg(fs, e, fs.freereg - 1)
2170
- end
2171
- end
2172
-
2173
- ------------------------------------------------------------------------
2174
- --
2175
- -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
2176
- ------------------------------------------------------------------------
2177
- function luaK:exp2reg(fs, e, reg)
2178
- self:discharge2reg(fs, e, reg)
2179
- if e.k == "VJMP" then
2180
- e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
2181
- end
2182
- if self:hasjumps(e) then
2183
- local final -- position after whole expression
2184
- local p_f = self.NO_JUMP -- position of an eventual LOAD false
2185
- local p_t = self.NO_JUMP -- position of an eventual LOAD true
2186
- if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
2187
- local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
2188
- p_f = self:code_label(fs, reg, 0, 1)
2189
- p_t = self:code_label(fs, reg, 1, 0)
2190
- self:patchtohere(fs, fj)
2191
- end
2192
- final = self:getlabel(fs)
2193
- self:patchlistaux(fs, e.f, final, reg, p_f)
2194
- self:patchlistaux(fs, e.t, final, reg, p_t)
2195
- end
2196
- e.f, e.t = self.NO_JUMP, self.NO_JUMP
2197
- e.info = reg
2198
- e.k = "VNONRELOC"
2199
- end
2200
-
2201
- ------------------------------------------------------------------------
2202
- --
2203
- -- * used in multiple locations
2204
- ------------------------------------------------------------------------
2205
- function luaK:exp2nextreg(fs, e)
2206
- self:dischargevars(fs, e)
2207
- self:freeexp(fs, e)
2208
- self:reserveregs(fs, 1)
2209
- self:exp2reg(fs, e, fs.freereg - 1)
2210
- end
2211
-
2212
- ------------------------------------------------------------------------
2213
- --
2214
- -- * used in multiple locations
2215
- ------------------------------------------------------------------------
2216
- function luaK:exp2anyreg(fs, e)
2217
- self:dischargevars(fs, e)
2218
- if e.k == "VNONRELOC" then
2219
- if not self:hasjumps(e) then -- exp is already in a register
2220
- return e.info
2221
- end
2222
- if e.info >= fs.nactvar then -- reg. is not a local?
2223
- self:exp2reg(fs, e, e.info) -- put value on it
2224
- return e.info
2225
- end
2226
- end
2227
- self:exp2nextreg(fs, e) -- default
2228
- return e.info
2229
- end
2230
-
2231
- ------------------------------------------------------------------------
2232
- --
2233
- -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
2234
- -- * used in (lparser) luaY:yindex()
2235
- ------------------------------------------------------------------------
2236
- function luaK:exp2val(fs, e)
2237
- if self:hasjumps(e) then
2238
- self:exp2anyreg(fs, e)
2239
- else
2240
- self:dischargevars(fs, e)
2241
- end
2242
- end
2243
-
2244
- ------------------------------------------------------------------------
2245
- --
2246
- -- * used in multiple locations
2247
- ------------------------------------------------------------------------
2248
- function luaK:exp2RK(fs, e)
2249
- self:exp2val(fs, e)
2250
- local k = e.k
2251
- if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
2252
- if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand?
2253
- -- converted from a 2-deep ternary operator expression
2254
- if e.k == "VNIL" then
2255
- e.info = self:nilK(fs)
2256
- else
2257
- e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval) or self:boolK(fs, e.k == "VTRUE")
2258
- end
2259
- e.k = "VK"
2260
- return luaP:RKASK(e.info)
2261
- end
2262
- elseif k == "VK" then
2263
- if e.info <= luaP.MAXINDEXRK then -- constant fit in argC?
2264
- return luaP:RKASK(e.info)
2265
- end
2266
- else
2267
- -- default
2268
- end
2269
- -- not a constant in the right range: put it in a register
2270
- return self:exp2anyreg(fs, e)
2271
- end
2272
-
2273
- ------------------------------------------------------------------------
2274
- --
2275
- -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
2276
- ------------------------------------------------------------------------
2277
- function luaK:storevar(fs, var, ex)
2278
- local k = var.k
2279
- if k == "VLOCAL" then
2280
- self:freeexp(fs, ex)
2281
- self:exp2reg(fs, ex, var.info)
2282
- return
2283
- elseif k == "VUPVAL" then
2284
- local e = self:exp2anyreg(fs, ex)
2285
- self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
2286
- elseif k == "VGLOBAL" then
2287
- local e = self:exp2anyreg(fs, ex)
2288
- self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
2289
- elseif k == "VINDEXED" then
2290
- local e = self:exp2RK(fs, ex)
2291
- self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
2292
- else
2293
- lua_assert(0) -- invalid var kind to store
2294
- end
2295
- self:freeexp(fs, ex)
2296
- end
2297
-
2298
- ------------------------------------------------------------------------
2299
- --
2300
- -- * used only in (lparser) luaY:primaryexp()
2301
- ------------------------------------------------------------------------
2302
- function luaK:_self(fs, e, key)
2303
- self:exp2anyreg(fs, e)
2304
- self:freeexp(fs, e)
2305
- local func = fs.freereg
2306
- self:reserveregs(fs, 2)
2307
- self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
2308
- self:freeexp(fs, key)
2309
- e.info = func
2310
- e.k = "VNONRELOC"
2311
- end
2312
-
2313
- ------------------------------------------------------------------------
2314
- --
2315
- -- * used in luaK:goiftrue(), luaK:codenot()
2316
- ------------------------------------------------------------------------
2317
- function luaK:invertjump(fs, e)
2318
- local pc = self:getjumpcontrol(fs, e.info)
2319
- lua_assert(
2320
- luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0
2321
- and luaP:GET_OPCODE(pc) ~= "OP_TESTSET"
2322
- and luaP:GET_OPCODE(pc) ~= "OP_TEST"
2323
- )
2324
- luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
2325
- end
2326
-
2327
- ------------------------------------------------------------------------
2328
- --
2329
- -- * used in luaK:goiftrue(), luaK:goiffalse()
2330
- ------------------------------------------------------------------------
2331
- function luaK:jumponcond(fs, e, cond)
2332
- if e.k == "VRELOCABLE" then
2333
- local ie = self:getcode(fs, e)
2334
- if luaP:GET_OPCODE(ie) == "OP_NOT" then
2335
- fs.pc = fs.pc - 1 -- remove previous OP_NOT
2336
- return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
2337
- end
2338
- -- else go through
2339
- end
2340
- self:discharge2anyreg(fs, e)
2341
- self:freeexp(fs, e)
2342
- return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
2343
- end
2344
-
2345
- ------------------------------------------------------------------------
2346
- --
2347
- -- * used in luaK:infix(), (lparser) luaY:cond()
2348
- ------------------------------------------------------------------------
2349
- function luaK:goiftrue(fs, e)
2350
- local pc -- pc of last jump
2351
- self:dischargevars(fs, e)
2352
- local k = e.k
2353
- if k == "VK" or k == "VKNUM" or k == "VTRUE" then
2354
- pc = self.NO_JUMP -- always true; do nothing
2355
- elseif k == "VFALSE" then
2356
- pc = self:jump(fs) -- always jump
2357
- elseif k == "VJMP" then
2358
- self:invertjump(fs, e)
2359
- pc = e.info
2360
- else
2361
- pc = self:jumponcond(fs, e, false)
2362
- end
2363
- e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list
2364
- self:patchtohere(fs, e.t)
2365
- e.t = self.NO_JUMP
2366
- end
2367
-
2368
- ------------------------------------------------------------------------
2369
- --
2370
- -- * used in luaK:infix()
2371
- ------------------------------------------------------------------------
2372
- function luaK:goiffalse(fs, e)
2373
- local pc -- pc of last jump
2374
- self:dischargevars(fs, e)
2375
- local k = e.k
2376
- if k == "VNIL" or k == "VFALSE" then
2377
- pc = self.NO_JUMP -- always false; do nothing
2378
- elseif k == "VTRUE" then
2379
- pc = self:jump(fs) -- always jump
2380
- elseif k == "VJMP" then
2381
- pc = e.info
2382
- else
2383
- pc = self:jumponcond(fs, e, true)
2384
- end
2385
- e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list
2386
- self:patchtohere(fs, e.f)
2387
- e.f = self.NO_JUMP
2388
- end
2389
-
2390
- ------------------------------------------------------------------------
2391
- --
2392
- -- * used only in luaK:prefix()
2393
- ------------------------------------------------------------------------
2394
- function luaK:codenot(fs, e)
2395
- self:dischargevars(fs, e)
2396
- local k = e.k
2397
- if k == "VNIL" or k == "VFALSE" then
2398
- e.k = "VTRUE"
2399
- elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
2400
- e.k = "VFALSE"
2401
- elseif k == "VJMP" then
2402
- self:invertjump(fs, e)
2403
- elseif k == "VRELOCABLE" or k == "VNONRELOC" then
2404
- self:discharge2anyreg(fs, e)
2405
- self:freeexp(fs, e)
2406
- e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
2407
- e.k = "VRELOCABLE"
2408
- else
2409
- lua_assert(0) -- cannot happen
2410
- end
2411
- -- interchange true and false lists
2412
- e.f, e.t = e.t, e.f
2413
- self:removevalues(fs, e.f)
2414
- self:removevalues(fs, e.t)
2415
- end
2416
-
2417
- ------------------------------------------------------------------------
2418
- --
2419
- -- * used in (lparser) luaY:field(), luaY:primaryexp()
2420
- ------------------------------------------------------------------------
2421
- function luaK:indexed(fs, t, k)
2422
- t.aux = self:exp2RK(fs, k)
2423
- t.k = "VINDEXED"
2424
- end
2425
-
2426
- ------------------------------------------------------------------------
2427
- --
2428
- -- * used only in luaK:codearith()
2429
- ------------------------------------------------------------------------
2430
- function luaK:constfolding(op, e1, e2)
2431
- local r
2432
- if not self:isnumeral(e1) or not self:isnumeral(e2) then
2433
- return false
2434
- end
2435
- local v1 = e1.nval
2436
- local v2 = e2.nval
2437
- if op == "OP_ADD" then
2438
- r = self:numadd(v1, v2)
2439
- elseif op == "OP_SUB" then
2440
- r = self:numsub(v1, v2)
2441
- elseif op == "OP_MUL" then
2442
- r = self:nummul(v1, v2)
2443
- elseif op == "OP_DIV" then
2444
- if v2 == 0 then
2445
- return false
2446
- end -- do not attempt to divide by 0
2447
- r = self:numdiv(v1, v2)
2448
- elseif op == "OP_MOD" then
2449
- if v2 == 0 then
2450
- return false
2451
- end -- do not attempt to divide by 0
2452
- r = self:nummod(v1, v2)
2453
- elseif op == "OP_POW" then
2454
- r = self:numpow(v1, v2)
2455
- elseif op == "OP_UNM" then
2456
- r = self:numunm(v1)
2457
- elseif op == "OP_LEN" then
2458
- return false -- no constant folding for 'len'
2459
- else
2460
- lua_assert(0)
2461
- r = 0
2462
- end
2463
- if self:numisnan(r) then
2464
- return false
2465
- end -- do not attempt to produce NaN
2466
- e1.nval = r
2467
- return true
2468
- end
2469
-
2470
- ------------------------------------------------------------------------
2471
- --
2472
- -- * used in luaK:prefix(), luaK:posfix()
2473
- ------------------------------------------------------------------------
2474
- function luaK:codearith(fs, op, e1, e2)
2475
- if self:constfolding(op, e1, e2) then
2476
- return
2477
- else
2478
- local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
2479
- local o1 = self:exp2RK(fs, e1)
2480
- if o1 > o2 then
2481
- self:freeexp(fs, e1)
2482
- self:freeexp(fs, e2)
2483
- else
2484
- self:freeexp(fs, e2)
2485
- self:freeexp(fs, e1)
2486
- end
2487
- e1.info = self:codeABC(fs, op, 0, o1, o2)
2488
- e1.k = "VRELOCABLE"
2489
- end
2490
- end
2491
-
2492
- ------------------------------------------------------------------------
2493
- --
2494
- -- * used only in luaK:posfix()
2495
- ------------------------------------------------------------------------
2496
- function luaK:codecomp(fs, op, cond, e1, e2)
2497
- local o1 = self:exp2RK(fs, e1)
2498
- local o2 = self:exp2RK(fs, e2)
2499
- self:freeexp(fs, e2)
2500
- self:freeexp(fs, e1)
2501
- if cond == 0 and op ~= "OP_EQ" then
2502
- -- exchange args to replace by `<' or `<='
2503
- o1, o2 = o2, o1 -- o1 <==> o2
2504
- cond = 1
2505
- end
2506
- e1.info = self:condjump(fs, op, cond, o1, o2)
2507
- e1.k = "VJMP"
2508
- end
2509
-
2510
- ------------------------------------------------------------------------
2511
- --
2512
- -- * used only in (lparser) luaY:subexpr()
2513
- ------------------------------------------------------------------------
2514
- function luaK:prefix(fs, op, e)
2515
- local e2 = {} -- expdesc
2516
- e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
2517
- e2.k = "VKNUM"
2518
- e2.nval = 0
2519
- if op == "OPR_MINUS" then
2520
- if not self:isnumeral(e) then
2521
- self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants
2522
- end
2523
- self:codearith(fs, "OP_UNM", e, e2)
2524
- elseif op == "OPR_NOT" then
2525
- self:codenot(fs, e)
2526
- elseif op == "OPR_LEN" then
2527
- self:exp2anyreg(fs, e) -- cannot operate on constants
2528
- self:codearith(fs, "OP_LEN", e, e2)
2529
- else
2530
- lua_assert(0)
2531
- end
2532
- end
2533
-
2534
- ------------------------------------------------------------------------
2535
- --
2536
- -- * used only in (lparser) luaY:subexpr()
2537
- ------------------------------------------------------------------------
2538
- function luaK:infix(fs, op, v)
2539
- if op == "OPR_AND" then
2540
- self:goiftrue(fs, v)
2541
- elseif op == "OPR_OR" then
2542
- self:goiffalse(fs, v)
2543
- elseif op == "OPR_CONCAT" then
2544
- self:exp2nextreg(fs, v) -- operand must be on the 'stack'
2545
- elseif
2546
- op == "OPR_ADD"
2547
- or op == "OPR_SUB"
2548
- or op == "OPR_MUL"
2549
- or op == "OPR_DIV"
2550
- or op == "OPR_MOD"
2551
- or op == "OPR_POW"
2552
- then
2553
- if not self:isnumeral(v) then
2554
- self:exp2RK(fs, v)
2555
- end
2556
- else
2557
- self:exp2RK(fs, v)
2558
- end
2559
- end
2560
-
2561
- ------------------------------------------------------------------------
2562
- --
2563
- -- * used only in (lparser) luaY:subexpr()
2564
- ------------------------------------------------------------------------
2565
- -- table lookups to simplify testing
2566
- luaK.arith_op = {
2567
- OPR_ADD = "OP_ADD",
2568
- OPR_SUB = "OP_SUB",
2569
- OPR_MUL = "OP_MUL",
2570
- OPR_DIV = "OP_DIV",
2571
- OPR_MOD = "OP_MOD",
2572
- OPR_POW = "OP_POW",
2573
- }
2574
- luaK.comp_op = {
2575
- OPR_EQ = "OP_EQ",
2576
- OPR_NE = "OP_EQ",
2577
- OPR_LT = "OP_LT",
2578
- OPR_LE = "OP_LE",
2579
- OPR_GT = "OP_LT",
2580
- OPR_GE = "OP_LE",
2581
- }
2582
- luaK.comp_cond = {
2583
- OPR_EQ = 1,
2584
- OPR_NE = 0,
2585
- OPR_LT = 1,
2586
- OPR_LE = 1,
2587
- OPR_GT = 0,
2588
- OPR_GE = 0,
2589
- }
2590
- function luaK:posfix(fs, op, e1, e2)
2591
- -- needed because e1 = e2 doesn't copy values...
2592
- -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
2593
- -- but here, all elements are copied for completeness' sake
2594
- local function copyexp(e1, e2)
2595
- e1.k = e2.k
2596
- e1.info = e2.info
2597
- e1.aux = e2.aux
2598
- e1.nval = e2.nval
2599
- e1.t = e2.t
2600
- e1.f = e2.f
2601
- end
2602
- if op == "OPR_AND" then
2603
- lua_assert(e1.t == self.NO_JUMP) -- list must be closed
2604
- self:dischargevars(fs, e2)
2605
- e2.f = self:concat(fs, e2.f, e1.f)
2606
- copyexp(e1, e2)
2607
- elseif op == "OPR_OR" then
2608
- lua_assert(e1.f == self.NO_JUMP) -- list must be closed
2609
- self:dischargevars(fs, e2)
2610
- e2.t = self:concat(fs, e2.t, e1.t)
2611
- copyexp(e1, e2)
2612
- elseif op == "OPR_CONCAT" then
2613
- self:exp2val(fs, e2)
2614
- if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
2615
- lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
2616
- self:freeexp(fs, e1)
2617
- luaP:SETARG_B(self:getcode(fs, e2), e1.info)
2618
- e1.k = "VRELOCABLE"
2619
- e1.info = e2.info
2620
- else
2621
- self:exp2nextreg(fs, e2) -- operand must be on the 'stack'
2622
- self:codearith(fs, "OP_CONCAT", e1, e2)
2623
- end
2624
- else
2625
- -- the following uses a table lookup in place of conditionals
2626
- local arith = self.arith_op[op]
2627
- if arith then
2628
- self:codearith(fs, arith, e1, e2)
2629
- else
2630
- local comp = self.comp_op[op]
2631
- if comp then
2632
- self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
2633
- else
2634
- lua_assert(0)
2635
- end
2636
- end --if arith
2637
- end --if op
2638
- end
2639
-
2640
- ------------------------------------------------------------------------
2641
- -- adjusts debug information for last instruction written, in order to
2642
- -- change the line where item comes into existence
2643
- -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
2644
- ------------------------------------------------------------------------
2645
- function luaK:fixline(fs, line)
2646
- fs.f.lineinfo[fs.pc - 1] = line
2647
- end
2648
-
2649
- ------------------------------------------------------------------------
2650
- -- general function to write an instruction into the instruction buffer,
2651
- -- sets debug information too
2652
- -- * used in luaK:codeABC(), luaK:codeABx()
2653
- -- * called directly by (lparser) luaY:whilestat()
2654
- ------------------------------------------------------------------------
2655
- function luaK:code(fs, i, line)
2656
- local f = fs.f
2657
- self:dischargejpc(fs) -- 'pc' will change
2658
- -- put new instruction in code array
2659
- luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, luaY.MAX_INT, "code size overflow")
2660
- f.code[fs.pc] = i
2661
- -- save corresponding line information
2662
- luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, luaY.MAX_INT, "code size overflow")
2663
- f.lineinfo[fs.pc] = line
2664
- local pc = fs.pc
2665
- fs.pc = fs.pc + 1
2666
- return pc
2667
- end
2668
-
2669
- ------------------------------------------------------------------------
2670
- -- writes an instruction of type ABC
2671
- -- * calls luaK:code()
2672
- ------------------------------------------------------------------------
2673
- function luaK:codeABC(fs, o, a, b, c)
2674
- lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
2675
- lua_assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
2676
- lua_assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
2677
- return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
2678
- end
2679
-
2680
- ------------------------------------------------------------------------
2681
- -- writes an instruction of type ABx
2682
- -- * calls luaK:code(), called by luaK:codeAsBx()
2683
- ------------------------------------------------------------------------
2684
- function luaK:codeABx(fs, o, a, bc)
2685
- lua_assert(luaP:getOpMode(o) == luaP.OpMode.iABx or luaP:getOpMode(o) == luaP.OpMode.iAsBx)
2686
- lua_assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
2687
- return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
2688
- end
2689
-
2690
- ------------------------------------------------------------------------
2691
- --
2692
- -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
2693
- ------------------------------------------------------------------------
2694
- function luaK:setlist(fs, base, nelems, tostore)
2695
- local c = math.floor((nelems - 1) / luaP.LFIELDS_PER_FLUSH) + 1
2696
- local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
2697
- lua_assert(tostore ~= 0)
2698
- if c <= luaP.MAXARG_C then
2699
- self:codeABC(fs, "OP_SETLIST", base, b, c)
2700
- else
2701
- self:codeABC(fs, "OP_SETLIST", base, b, 0)
2702
- self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
2703
- end
2704
- fs.freereg = base + 1 -- free registers with list values
2705
- end
2706
-
2707
- --dofile("lparser.lua")
2708
-
2709
- --[[--------------------------------------------------------------------
2710
- -- Expression descriptor
2711
- -- * expkind changed to string constants; luaY:assignment was the only
2712
- -- function to use a relational operator with this enumeration
2713
- -- VVOID -- no value
2714
- -- VNIL -- no value
2715
- -- VTRUE -- no value
2716
- -- VFALSE -- no value
2717
- -- VK -- info = index of constant in 'k'
2718
- -- VKNUM -- nval = numerical value
2719
- -- VLOCAL -- info = local register
2720
- -- VUPVAL, -- info = index of upvalue in 'upvalues'
2721
- -- VGLOBAL -- info = index of table; aux = index of global name in 'k'
2722
- -- VINDEXED -- info = table register; aux = index register (or 'k')
2723
- -- VJMP -- info = instruction pc
2724
- -- VRELOCABLE -- info = instruction pc
2725
- -- VNONRELOC -- info = result register
2726
- -- VCALL -- info = instruction pc
2727
- -- VVARARG -- info = instruction pc
2728
- } ----------------------------------------------------------------------]]
2729
-
2730
- --[[--------------------------------------------------------------------
2731
- -- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
2732
- -- implementation ignores all instances of u and s usage
2733
- -- struct expdesc:
2734
- -- k -- (enum: expkind)
2735
- -- info, aux -- (int, int)
2736
- -- nval -- (lua_Number)
2737
- -- t -- patch list of 'exit when true'
2738
- -- f -- patch list of 'exit when false'
2739
- ----------------------------------------------------------------------]]
2740
-
2741
- --[[--------------------------------------------------------------------
2742
- -- struct upvaldesc:
2743
- -- k -- (lu_byte)
2744
- -- info -- (lu_byte)
2745
- ----------------------------------------------------------------------]]
2746
-
2747
- --[[--------------------------------------------------------------------
2748
- -- state needed to generate code for a given function
2749
- -- struct FuncState:
2750
- -- f -- current function header (table: Proto)
2751
- -- h -- table to find (and reuse) elements in 'k' (table: Table)
2752
- -- prev -- enclosing function (table: FuncState)
2753
- -- ls -- lexical state (table: LexState)
2754
- -- L -- copy of the Lua state (table: lua_State)
2755
- -- bl -- chain of current blocks (table: BlockCnt)
2756
- -- pc -- next position to code (equivalent to 'ncode')
2757
- -- lasttarget -- 'pc' of last 'jump target'
2758
- -- jpc -- list of pending jumps to 'pc'
2759
- -- freereg -- first free register
2760
- -- nk -- number of elements in 'k'
2761
- -- np -- number of elements in 'p'
2762
- -- nlocvars -- number of elements in 'locvars'
2763
- -- nactvar -- number of active local variables
2764
- -- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc)
2765
- -- actvar[LUAI_MAXVARS] -- declared-variable stack
2766
- ----------------------------------------------------------------------]]
2767
-
2768
- ------------------------------------------------------------------------
2769
- -- constants used by parser
2770
- -- * picks up duplicate values from luaX if required
2771
- ------------------------------------------------------------------------
2772
- luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h)
2773
-
2774
- luaY.SHRT_MAX = 32767 -- (from <limits.h>)
2775
- luaY.LUAI_MAXVARS = 200 -- (luaconf.h)
2776
- luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h)
2777
- luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h)
2778
- -- * INT_MAX-2 for 32-bit systems
2779
- luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h)
2780
-
2781
- luaY.VARARG_HASARG = 1 -- (from lobject.h)
2782
- -- NOTE: HASARG_MASK is value-specific
2783
- luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
2784
- luaY.VARARG_ISVARARG = 2
2785
- -- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
2786
- luaY.VARARG_NEEDSARG = 4
2787
-
2788
- luaY.LUA_MULTRET = -1 -- (lua.h)
2789
-
2790
- --[[--------------------------------------------------------------------
2791
- -- other functions
2792
- ----------------------------------------------------------------------]]
2793
-
2794
- ------------------------------------------------------------------------
2795
- -- LUA_QL describes how error messages quote program elements.
2796
- -- CHANGE it if you want a different appearance. (from luaconf.h)
2797
- ------------------------------------------------------------------------
2798
- function luaY:LUA_QL(x)
2799
- return "'" .. x .. "'"
2800
- end
2801
-
2802
- ------------------------------------------------------------------------
2803
- -- this is a stripped-down luaM_growvector (from lmem.h) which is a
2804
- -- macro based on luaM_growaux (in lmem.c); all the following does is
2805
- -- reproduce the size limit checking logic of the original function
2806
- -- so that error behaviour is identical; all arguments preserved for
2807
- -- convenience, even those which are unused
2808
- -- * set the t field to nil, since this originally does a sizeof(t)
2809
- -- * size (originally a pointer) is never updated, their final values
2810
- -- are set by luaY:close_func(), so overall things should still work
2811
- ------------------------------------------------------------------------
2812
- function luaY:growvector(L, v, nelems, size, t, limit, e)
2813
- if nelems >= limit then
2814
- error(e) -- was luaG_runerror
2815
- end
2816
- end
2817
-
2818
- ------------------------------------------------------------------------
2819
- -- initialize a new function prototype structure (from lfunc.c)
2820
- -- * used only in open_func()
2821
- ------------------------------------------------------------------------
2822
- function luaY:newproto(L)
2823
- local f = {} -- Proto
2824
- -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
2825
- f.k = {}
2826
- f.sizek = 0
2827
- f.p = {}
2828
- f.sizep = 0
2829
- f.code = {}
2830
- f.sizecode = 0
2831
- f.sizelineinfo = 0
2832
- f.sizeupvalues = 0
2833
- f.nups = 0
2834
- f.upvalues = {}
2835
- f.numparams = 0
2836
- f.is_vararg = 0
2837
- f.maxstacksize = 0
2838
- f.lineinfo = {}
2839
- f.sizelocvars = 0
2840
- f.locvars = {}
2841
- f.lineDefined = 0
2842
- f.lastlinedefined = 0
2843
- f.source = nil
2844
- return f
2845
- end
2846
-
2847
- ------------------------------------------------------------------------
2848
- -- converts an integer to a "floating point byte", represented as
2849
- -- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
2850
- -- eeeee != 0 and (xxx) otherwise.
2851
- ------------------------------------------------------------------------
2852
- function luaY:int2fb(x)
2853
- local e = 0 -- exponent
2854
- while x >= 16 do
2855
- x = math.floor((x + 1) / 2)
2856
- e = e + 1
2857
- end
2858
- if x < 8 then
2859
- return x
2860
- else
2861
- return ((e + 1) * 8) + (x - 8)
2862
- end
2863
- end
2864
-
2865
- --[[--------------------------------------------------------------------
2866
- -- parser functions
2867
- ----------------------------------------------------------------------]]
2868
-
2869
- ------------------------------------------------------------------------
2870
- -- true of the kind of expression produces multiple return values
2871
- ------------------------------------------------------------------------
2872
- function luaY:hasmultret(k)
2873
- return k == "VCALL" or k == "VVARARG"
2874
- end
2875
-
2876
- ------------------------------------------------------------------------
2877
- -- convenience function to access active local i, returns entry
2878
- ------------------------------------------------------------------------
2879
- function luaY:getlocvar(fs, i)
2880
- return fs.f.locvars[fs.actvar[i]]
2881
- end
2882
-
2883
- ------------------------------------------------------------------------
2884
- -- check a limit, string m provided as an error message
2885
- ------------------------------------------------------------------------
2886
- function luaY:checklimit(fs, v, l, m)
2887
- if v > l then
2888
- self:errorlimit(fs, l, m)
2889
- end
2890
- end
2891
-
2892
- --[[--------------------------------------------------------------------
2893
- -- nodes for block list (list of active blocks)
2894
- -- struct BlockCnt:
2895
- -- previous -- chain (table: BlockCnt)
2896
- -- breaklist -- list of jumps out of this loop
2897
- -- nactvar -- # active local variables outside the breakable structure
2898
- -- upval -- true if some variable in the block is an upvalue (boolean)
2899
- -- isbreakable -- true if 'block' is a loop (boolean)
2900
- ----------------------------------------------------------------------]]
2901
-
2902
- ------------------------------------------------------------------------
2903
- -- prototypes for recursive non-terminal functions
2904
- ------------------------------------------------------------------------
2905
- -- prototypes deleted; not required in Lua
2906
-
2907
- ------------------------------------------------------------------------
2908
- -- reanchor if last token is has a constant string, see close_func()
2909
- -- * used only in close_func()
2910
- ------------------------------------------------------------------------
2911
- function luaY:anchor_token(ls)
2912
- if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
2913
- -- not relevant to Lua implementation of parser
2914
- -- local ts = ls.t.seminfo
2915
- -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
2916
- end
2917
- end
2918
-
2919
- ------------------------------------------------------------------------
2920
- -- throws a syntax error if token expected is not there
2921
- ------------------------------------------------------------------------
2922
- function luaY:error_expected(ls, token)
2923
- luaX:syntaxerror(ls, string.format(self.LUA_QS .. " expected", luaX:token2str(ls, token)))
2924
- end
2925
-
2926
- ------------------------------------------------------------------------
2927
- -- prepares error message for display, for limits exceeded
2928
- -- * used only in checklimit()
2929
- ------------------------------------------------------------------------
2930
- function luaY:errorlimit(fs, limit, what)
2931
- local msg = (fs.f.linedefined == 0) and string.format("main function has more than %d %s", limit, what)
2932
- or string.format("function at line %d has more than %d %s", fs.f.linedefined, limit, what)
2933
- luaX:lexerror(fs.ls, msg, 0)
2934
- end
2935
-
2936
- ------------------------------------------------------------------------
2937
- -- tests for a token, returns outcome
2938
- -- * return value changed to boolean
2939
- ------------------------------------------------------------------------
2940
- function luaY:testnext(ls, c)
2941
- if ls.t.token == c then
2942
- luaX:next(ls)
2943
- return true
2944
- else
2945
- return false
2946
- end
2947
- end
2948
-
2949
- ------------------------------------------------------------------------
2950
- -- check for existence of a token, throws error if not found
2951
- ------------------------------------------------------------------------
2952
- function luaY:check(ls, c)
2953
- if ls.t.token ~= c then
2954
- self:error_expected(ls, c)
2955
- end
2956
- end
2957
-
2958
- ------------------------------------------------------------------------
2959
- -- verify existence of a token, then skip it
2960
- ------------------------------------------------------------------------
2961
- function luaY:checknext(ls, c)
2962
- self:check(ls, c)
2963
- luaX:next(ls)
2964
- end
2965
-
2966
- ------------------------------------------------------------------------
2967
- -- throws error if condition not matched
2968
- ------------------------------------------------------------------------
2969
- function luaY:check_condition(ls, c, msg)
2970
- if not c then
2971
- luaX:syntaxerror(ls, msg)
2972
- end
2973
- end
2974
-
2975
- ------------------------------------------------------------------------
2976
- -- verifies token conditions are met or else throw error
2977
- ------------------------------------------------------------------------
2978
- function luaY:check_match(ls, what, who, where)
2979
- if not self:testnext(ls, what) then
2980
- if where == ls.linenumber then
2981
- self:error_expected(ls, what)
2982
- else
2983
- luaX:syntaxerror(
2984
- ls,
2985
- string.format(
2986
- self.LUA_QS .. " expected (to close " .. self.LUA_QS .. " at line %d)",
2987
- luaX:token2str(ls, what),
2988
- luaX:token2str(ls, who),
2989
- where
2990
- )
2991
- )
2992
- end
2993
- end
2994
- end
2995
-
2996
- ------------------------------------------------------------------------
2997
- -- expect that token is a name, return the name
2998
- ------------------------------------------------------------------------
2999
- function luaY:str_checkname(ls)
3000
- self:check(ls, "TK_NAME")
3001
- local ts = ls.t.seminfo
3002
- luaX:next(ls)
3003
- return ts
3004
- end
3005
-
3006
- ------------------------------------------------------------------------
3007
- -- initialize a struct expdesc, expression description data structure
3008
- ------------------------------------------------------------------------
3009
- function luaY:init_exp(e, k, i)
3010
- e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
3011
- e.k = k
3012
- e.info = i
3013
- end
3014
-
3015
- ------------------------------------------------------------------------
3016
- -- adds given string s in string pool, sets e as VK
3017
- ------------------------------------------------------------------------
3018
- function luaY:codestring(ls, e, s)
3019
- self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
3020
- end
3021
-
3022
- ------------------------------------------------------------------------
3023
- -- consume a name token, adds it to string pool, sets e as VK
3024
- ------------------------------------------------------------------------
3025
- function luaY:checkname(ls, e)
3026
- self:codestring(ls, e, self:str_checkname(ls))
3027
- end
3028
-
3029
- ------------------------------------------------------------------------
3030
- -- creates struct entry for a local variable
3031
- -- * used only in new_localvar()
3032
- ------------------------------------------------------------------------
3033
- function luaY:registerlocalvar(ls, varname)
3034
- local fs = ls.fs
3035
- local f = fs.f
3036
- self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars, nil, self.SHRT_MAX, "too many local variables")
3037
- -- loop to initialize empty f.locvar positions not required
3038
- f.locvars[fs.nlocvars] = {} -- LocVar
3039
- f.locvars[fs.nlocvars].varname = varname
3040
- -- luaC_objbarrier(ls.L, f, varname) /* GC */
3041
- local nlocvars = fs.nlocvars
3042
- fs.nlocvars = fs.nlocvars + 1
3043
- return nlocvars
3044
- end
3045
-
3046
- ------------------------------------------------------------------------
3047
- -- creates a new local variable given a name and an offset from nactvar
3048
- -- * used in fornum(), forlist(), parlist(), body()
3049
- ------------------------------------------------------------------------
3050
- function luaY:new_localvarliteral(ls, v, n)
3051
- self:new_localvar(ls, v, n)
3052
- end
3053
-
3054
- ------------------------------------------------------------------------
3055
- -- register a local variable, set in active variable list
3056
- ------------------------------------------------------------------------
3057
- function luaY:new_localvar(ls, name, n)
3058
- local fs = ls.fs
3059
- self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
3060
- fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
3061
- end
3062
-
3063
- ------------------------------------------------------------------------
3064
- -- adds nvars number of new local variables, set debug information
3065
- ------------------------------------------------------------------------
3066
- function luaY:adjustlocalvars(ls, nvars)
3067
- local fs = ls.fs
3068
- fs.nactvar = fs.nactvar + nvars
3069
- for i = nvars, 1, -1 do
3070
- self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
3071
- end
3072
- end
3073
-
3074
- ------------------------------------------------------------------------
3075
- -- removes a number of locals, set debug information
3076
- ------------------------------------------------------------------------
3077
- function luaY:removevars(ls, tolevel)
3078
- local fs = ls.fs
3079
- while fs.nactvar > tolevel do
3080
- fs.nactvar = fs.nactvar - 1
3081
- self:getlocvar(fs, fs.nactvar).endpc = fs.pc
3082
- end
3083
- end
3084
-
3085
- ------------------------------------------------------------------------
3086
- -- returns an existing upvalue index based on the given name, or
3087
- -- creates a new upvalue struct entry and returns the new index
3088
- -- * used only in singlevaraux()
3089
- ------------------------------------------------------------------------
3090
- function luaY:indexupvalue(fs, name, v)
3091
- local f = fs.f
3092
- for i = 0, f.nups - 1 do
3093
- if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
3094
- lua_assert(f.upvalues[i] == name)
3095
- return i
3096
- end
3097
- end
3098
- -- new one
3099
- self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
3100
- self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues, nil, self.MAX_INT, "")
3101
- -- loop to initialize empty f.upvalues positions not required
3102
- f.upvalues[f.nups] = name
3103
- -- luaC_objbarrier(fs->L, f, name); /* GC */
3104
- lua_assert(v.k == "VLOCAL" or v.k == "VUPVAL")
3105
- -- this is a partial copy; only k & info fields used
3106
- fs.upvalues[f.nups] = { k = v.k, info = v.info }
3107
- local nups = f.nups
3108
- f.nups = f.nups + 1
3109
- return nups
3110
- end
3111
-
3112
- ------------------------------------------------------------------------
3113
- -- search the local variable namespace of the given fs for a match
3114
- -- * used only in singlevaraux()
3115
- ------------------------------------------------------------------------
3116
- function luaY:searchvar(fs, n)
3117
- for i = fs.nactvar - 1, 0, -1 do
3118
- if n == self:getlocvar(fs, i).varname then
3119
- return i
3120
- end
3121
- end
3122
- return -1 -- not found
3123
- end
3124
-
3125
- ------------------------------------------------------------------------
3126
- -- * mark upvalue flags in function states up to a given level
3127
- -- * used only in singlevaraux()
3128
- ------------------------------------------------------------------------
3129
- function luaY:markupval(fs, level)
3130
- local bl = fs.bl
3131
- while bl and bl.nactvar > level do
3132
- bl = bl.previous
3133
- end
3134
- if bl then
3135
- bl.upval = true
3136
- end
3137
- end
3138
-
3139
- ------------------------------------------------------------------------
3140
- -- handle locals, globals and upvalues and related processing
3141
- -- * search mechanism is recursive, calls itself to search parents
3142
- -- * used only in singlevar()
3143
- ------------------------------------------------------------------------
3144
- function luaY:singlevaraux(fs, n, var, base)
3145
- if fs == nil then -- no more levels?
3146
- self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
3147
- return "VGLOBAL"
3148
- else
3149
- local v = self:searchvar(fs, n) -- look up at current level
3150
- if v >= 0 then
3151
- self:init_exp(var, "VLOCAL", v)
3152
- if base == 0 then
3153
- self:markupval(fs, v) -- local will be used as an upval
3154
- end
3155
- return "VLOCAL"
3156
- else -- not found at current level; try upper one
3157
- if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
3158
- return "VGLOBAL"
3159
- end
3160
- var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL
3161
- var.k = "VUPVAL" -- upvalue in this level
3162
- return "VUPVAL"
3163
- end --if v
3164
- end --if fs
3165
- end
3166
-
3167
- ------------------------------------------------------------------------
3168
- -- consume a name token, creates a variable (global|local|upvalue)
3169
- -- * used in prefixexp(), funcname()
3170
- ------------------------------------------------------------------------
3171
- function luaY:singlevar(ls, var)
3172
- local varname = self:str_checkname(ls)
3173
- local fs = ls.fs
3174
- if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
3175
- var.info = luaK:stringK(fs, varname) -- info points to global name
3176
- end
3177
- end
3178
-
3179
- ------------------------------------------------------------------------
3180
- -- adjust RHS to match LHS in an assignment
3181
- -- * used in assignment(), forlist(), localstat()
3182
- ------------------------------------------------------------------------
3183
- function luaY:adjust_assign(ls, nvars, nexps, e)
3184
- local fs = ls.fs
3185
- local extra = nvars - nexps
3186
- if self:hasmultret(e.k) then
3187
- extra = extra + 1 -- includes call itself
3188
- if extra <= 0 then
3189
- extra = 0
3190
- end
3191
- luaK:setreturns(fs, e, extra) -- last exp. provides the difference
3192
- if extra > 1 then
3193
- luaK:reserveregs(fs, extra - 1)
3194
- end
3195
- else
3196
- if e.k ~= "VVOID" then
3197
- luaK:exp2nextreg(fs, e)
3198
- end -- close last expression
3199
- if extra > 0 then
3200
- local reg = fs.freereg
3201
- luaK:reserveregs(fs, extra)
3202
- luaK:_nil(fs, reg, extra)
3203
- end
3204
- end
3205
- end
3206
-
3207
- ------------------------------------------------------------------------
3208
- -- tracks and limits parsing depth, assert check at end of parsing
3209
- ------------------------------------------------------------------------
3210
- function luaY:enterlevel(ls)
3211
- ls.L.nCcalls = ls.L.nCcalls + 1
3212
- if ls.L.nCcalls > self.LUAI_MAXCCALLS then
3213
- luaX:lexerror(ls, "chunk has too many syntax levels", 0)
3214
- end
3215
- end
3216
-
3217
- ------------------------------------------------------------------------
3218
- -- tracks parsing depth, a pair with luaY:enterlevel()
3219
- ------------------------------------------------------------------------
3220
- function luaY:leavelevel(ls)
3221
- ls.L.nCcalls = ls.L.nCcalls - 1
3222
- end
3223
-
3224
- ------------------------------------------------------------------------
3225
- -- enters a code unit, initializes elements
3226
- ------------------------------------------------------------------------
3227
- function luaY:enterblock(fs, bl, isbreakable)
3228
- bl.breaklist = luaK.NO_JUMP
3229
- bl.isbreakable = isbreakable
3230
- bl.nactvar = fs.nactvar
3231
- bl.upval = false
3232
- bl.previous = fs.bl
3233
- fs.bl = bl
3234
- lua_assert(fs.freereg == fs.nactvar)
3235
- end
3236
-
3237
- ------------------------------------------------------------------------
3238
- -- leaves a code unit, close any upvalues
3239
- ------------------------------------------------------------------------
3240
- function luaY:leaveblock(fs)
3241
- local bl = fs.bl
3242
- fs.bl = bl.previous
3243
- self:removevars(fs.ls, bl.nactvar)
3244
- if bl.upval then
3245
- luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
3246
- end
3247
- -- a block either controls scope or breaks (never both)
3248
- lua_assert(not bl.isbreakable or not bl.upval)
3249
- lua_assert(bl.nactvar == fs.nactvar)
3250
- fs.freereg = fs.nactvar -- free registers
3251
- luaK:patchtohere(fs, bl.breaklist)
3252
- end
3253
-
3254
- ------------------------------------------------------------------------
3255
- -- implement the instantiation of a function prototype, append list of
3256
- -- upvalues after the instantiation instruction
3257
- -- * used only in body()
3258
- ------------------------------------------------------------------------
3259
- function luaY:pushclosure(ls, func, v)
3260
- local fs = ls.fs
3261
- local f = fs.f
3262
- self:growvector(ls.L, f.p, fs.np, f.sizep, nil, luaP.MAXARG_Bx, "constant table overflow")
3263
- -- loop to initialize empty f.p positions not required
3264
- f.p[fs.np] = func.f
3265
- fs.np = fs.np + 1
3266
- -- luaC_objbarrier(ls->L, f, func->f); /* C */
3267
- self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
3268
- for i = 0, func.f.nups - 1 do
3269
- local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
3270
- luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
3271
- end
3272
- end
3273
-
3274
- ------------------------------------------------------------------------
3275
- -- opening of a function
3276
- ------------------------------------------------------------------------
3277
- function luaY:open_func(ls, fs)
3278
- local L = ls.L
3279
- local f = self:newproto(ls.L)
3280
- fs.f = f
3281
- fs.prev = ls.fs -- linked list of funcstates
3282
- fs.ls = ls
3283
- fs.L = L
3284
- ls.fs = fs
3285
- fs.pc = 0
3286
- fs.lasttarget = -1
3287
- fs.jpc = luaK.NO_JUMP
3288
- fs.freereg = 0
3289
- fs.nk = 0
3290
- fs.np = 0
3291
- fs.nlocvars = 0
3292
- fs.nactvar = 0
3293
- fs.bl = nil
3294
- f.source = ls.source
3295
- f.maxstacksize = 2 -- registers 0/1 are always valid
3296
- fs.h = {} -- constant table; was luaH_new call
3297
- -- anchor table of constants and prototype (to avoid being collected)
3298
- -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
3299
- -- setptvalue2s(L, L->top, f); incr_top(L);
3300
- end
3301
-
3302
- ------------------------------------------------------------------------
3303
- -- closing of a function
3304
- ------------------------------------------------------------------------
3305
- function luaY:close_func(ls)
3306
- local L = ls.L
3307
- local fs = ls.fs
3308
- local f = fs.f
3309
- self:removevars(ls, 0)
3310
- luaK:ret(fs, 0, 0) -- final return
3311
- -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
3312
- -- f->locvars, f->upvalues; not required for Lua table arrays
3313
- f.sizecode = fs.pc
3314
- f.sizelineinfo = fs.pc
3315
- f.sizek = fs.nk
3316
- f.sizep = fs.np
3317
- f.sizelocvars = fs.nlocvars
3318
- f.sizeupvalues = f.nups
3319
- --lua_assert(luaG_checkcode(f)) -- currently not implemented
3320
- lua_assert(fs.bl == nil)
3321
- ls.fs = fs.prev
3322
- -- the following is not required for this implementation; kept here
3323
- -- for completeness
3324
- -- L->top -= 2; /* remove table and prototype from the stack */
3325
- -- last token read was anchored in defunct function; must reanchor it
3326
- if fs then
3327
- self:anchor_token(ls)
3328
- end
3329
- end
3330
-
3331
- ------------------------------------------------------------------------
3332
- -- parser initialization function
3333
- -- * note additional sub-tables needed for LexState, FuncState
3334
- ------------------------------------------------------------------------
3335
- function luaY:parser(L, z, buff, name)
3336
- local lexstate = {} -- LexState
3337
- lexstate.t = {}
3338
- lexstate.lookahead = {}
3339
- local funcstate = {} -- FuncState
3340
- funcstate.upvalues = {}
3341
- funcstate.actvar = {}
3342
- -- the following nCcalls initialization added for convenience
3343
- L.nCcalls = 0
3344
- lexstate.buff = buff
3345
- luaX:setinput(L, lexstate, z, name)
3346
- self:open_func(lexstate, funcstate)
3347
- funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg
3348
- luaX:next(lexstate) -- read first token
3349
- self:chunk(lexstate)
3350
- self:check(lexstate, "TK_EOS")
3351
- self:close_func(lexstate)
3352
- lua_assert(funcstate.prev == nil)
3353
- lua_assert(funcstate.f.nups == 0)
3354
- lua_assert(lexstate.fs == nil)
3355
- return funcstate.f
3356
- end
3357
-
3358
- --[[--------------------------------------------------------------------
3359
- -- GRAMMAR RULES
3360
- ----------------------------------------------------------------------]]
3361
-
3362
- ------------------------------------------------------------------------
3363
- -- parse a function name suffix, for function call specifications
3364
- -- * used in primaryexp(), funcname()
3365
- ------------------------------------------------------------------------
3366
- function luaY:field(ls, v)
3367
- -- field -> ['.' | ':'] NAME
3368
- local fs = ls.fs
3369
- local key = {} -- expdesc
3370
- luaK:exp2anyreg(fs, v)
3371
- luaX:next(ls) -- skip the dot or colon
3372
- self:checkname(ls, key)
3373
- luaK:indexed(fs, v, key)
3374
- end
3375
-
3376
- ------------------------------------------------------------------------
3377
- -- parse a table indexing suffix, for constructors, expressions
3378
- -- * used in recfield(), primaryexp()
3379
- ------------------------------------------------------------------------
3380
- function luaY:yindex(ls, v)
3381
- -- index -> '[' expr ']'
3382
- luaX:next(ls) -- skip the '['
3383
- self:expr(ls, v)
3384
- luaK:exp2val(ls.fs, v)
3385
- self:checknext(ls, "]")
3386
- end
3387
-
3388
- --[[--------------------------------------------------------------------
3389
- -- Rules for Constructors
3390
- ----------------------------------------------------------------------]]
3391
-
3392
- --[[--------------------------------------------------------------------
3393
- -- struct ConsControl:
3394
- -- v -- last list item read (table: struct expdesc)
3395
- -- t -- table descriptor (table: struct expdesc)
3396
- -- nh -- total number of 'record' elements
3397
- -- na -- total number of array elements
3398
- -- tostore -- number of array elements pending to be stored
3399
- ----------------------------------------------------------------------]]
3400
-
3401
- ------------------------------------------------------------------------
3402
- -- parse a table record (hash) field
3403
- -- * used in constructor()
3404
- ------------------------------------------------------------------------
3405
- function luaY:recfield(ls, cc)
3406
- -- recfield -> (NAME | '['exp1']') = exp1
3407
- local fs = ls.fs
3408
- local reg = ls.fs.freereg
3409
- local key, val = {}, {} -- expdesc
3410
- if ls.t.token == "TK_NAME" then
3411
- self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
3412
- self:checkname(ls, key)
3413
- else -- ls->t.token == '['
3414
- self:yindex(ls, key)
3415
- end
3416
- cc.nh = cc.nh + 1
3417
- self:checknext(ls, "=")
3418
- local rkkey = luaK:exp2RK(fs, key)
3419
- self:expr(ls, val)
3420
- luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
3421
- fs.freereg = reg -- free registers
3422
- end
3423
-
3424
- ------------------------------------------------------------------------
3425
- -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
3426
- -- * used in constructor()
3427
- ------------------------------------------------------------------------
3428
- function luaY:closelistfield(fs, cc)
3429
- if cc.v.k == "VVOID" then
3430
- return
3431
- end -- there is no list item
3432
- luaK:exp2nextreg(fs, cc.v)
3433
- cc.v.k = "VVOID"
3434
- if cc.tostore == luaP.LFIELDS_PER_FLUSH then
3435
- luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush
3436
- cc.tostore = 0 -- no more items pending
3437
- end
3438
- end
3439
-
3440
- ------------------------------------------------------------------------
3441
- -- emit a set list instruction at the end of parsing list constructor
3442
- -- * used in constructor()
3443
- ------------------------------------------------------------------------
3444
- function luaY:lastlistfield(fs, cc)
3445
- if cc.tostore == 0 then
3446
- return
3447
- end
3448
- if self:hasmultret(cc.v.k) then
3449
- luaK:setmultret(fs, cc.v)
3450
- luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
3451
- cc.na = cc.na - 1 -- do not count last expression (unknown number of elements)
3452
- else
3453
- if cc.v.k ~= "VVOID" then
3454
- luaK:exp2nextreg(fs, cc.v)
3455
- end
3456
- luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
3457
- end
3458
- end
3459
-
3460
- ------------------------------------------------------------------------
3461
- -- parse a table list (array) field
3462
- -- * used in constructor()
3463
- ------------------------------------------------------------------------
3464
- function luaY:listfield(ls, cc)
3465
- self:expr(ls, cc.v)
3466
- self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
3467
- cc.na = cc.na + 1
3468
- cc.tostore = cc.tostore + 1
3469
- end
3470
-
3471
- ------------------------------------------------------------------------
3472
- -- parse a table constructor
3473
- -- * used in funcargs(), simpleexp()
3474
- ------------------------------------------------------------------------
3475
- function luaY:constructor(ls, t)
3476
- -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
3477
- -- field -> recfield | listfield
3478
- -- fieldsep -> ',' | ';'
3479
- local fs = ls.fs
3480
- local line = ls.linenumber
3481
- local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
3482
- local cc = {} -- ConsControl
3483
- cc.v = {}
3484
- cc.na, cc.nh, cc.tostore = 0, 0, 0
3485
- cc.t = t
3486
- self:init_exp(t, "VRELOCABLE", pc)
3487
- self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
3488
- luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
3489
- self:checknext(ls, "{")
3490
- repeat
3491
- lua_assert(cc.v.k == "VVOID" or cc.tostore > 0)
3492
- if ls.t.token == "}" then
3493
- break
3494
- end
3495
- self:closelistfield(fs, cc)
3496
- local c = ls.t.token
3497
-
3498
- if c == "TK_NAME" then -- may be listfields or recfields
3499
- luaX:lookahead(ls)
3500
- if ls.lookahead.token ~= "=" then -- expression?
3501
- self:listfield(ls, cc)
3502
- else
3503
- self:recfield(ls, cc)
3504
- end
3505
- elseif c == "[" then -- constructor_item -> recfield
3506
- self:recfield(ls, cc)
3507
- else -- constructor_part -> listfield
3508
- self:listfield(ls, cc)
3509
- end
3510
- until not self:testnext(ls, ",") and not self:testnext(ls, ";")
3511
- self:check_match(ls, "}", "{", line)
3512
- self:lastlistfield(fs, cc)
3513
- luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
3514
- luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
3515
- end
3516
-
3517
- -- }======================================================================
3518
-
3519
- ------------------------------------------------------------------------
3520
- -- parse the arguments (parameters) of a function declaration
3521
- -- * used in body()
3522
- ------------------------------------------------------------------------
3523
- function luaY:parlist(ls)
3524
- -- parlist -> [ param { ',' param } ]
3525
- local fs = ls.fs
3526
- local f = fs.f
3527
- local nparams = 0
3528
- f.is_vararg = 0
3529
- if ls.t.token ~= ")" then -- is 'parlist' not empty?
3530
- repeat
3531
- local c = ls.t.token
3532
- if c == "TK_NAME" then -- param -> NAME
3533
- self:new_localvar(ls, self:str_checkname(ls), nparams)
3534
- nparams = nparams + 1
3535
- elseif c == "TK_DOTS" then -- param -> `...'
3536
- luaX:next(ls)
3537
- -- [[
3538
- -- #if defined(LUA_COMPAT_VARARG)
3539
- -- use `arg' as default name
3540
- self:new_localvarliteral(ls, "arg", nparams)
3541
- nparams = nparams + 1
3542
- f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
3543
- -- #endif
3544
- --]]
3545
- f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
3546
- else
3547
- luaX:syntaxerror(ls, "<name> or " .. self:LUA_QL("...") .. " expected")
3548
- end
3549
- until f.is_vararg ~= 0 or not self:testnext(ls, ",")
3550
- end --if
3551
- self:adjustlocalvars(ls, nparams)
3552
- -- NOTE: the following works only when HASARG_MASK is 2!
3553
- f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
3554
- luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
3555
- end
3556
-
3557
- ------------------------------------------------------------------------
3558
- -- parse function declaration body
3559
- -- * used in simpleexp(), localfunc(), funcstat()
3560
- ------------------------------------------------------------------------
3561
- function luaY:body(ls, e, needself, line)
3562
- -- body -> '(' parlist ')' chunk END
3563
- local new_fs = {} -- FuncState
3564
- new_fs.upvalues = {}
3565
- new_fs.actvar = {}
3566
- self:open_func(ls, new_fs)
3567
- new_fs.f.lineDefined = line
3568
- self:checknext(ls, "(")
3569
- if needself then
3570
- self:new_localvarliteral(ls, "self", 0)
3571
- self:adjustlocalvars(ls, 1)
3572
- end
3573
- self:parlist(ls)
3574
- self:checknext(ls, ")")
3575
- self:chunk(ls)
3576
- new_fs.f.lastlinedefined = ls.linenumber
3577
- self:check_match(ls, "TK_END", "TK_FUNCTION", line)
3578
- self:close_func(ls)
3579
- self:pushclosure(ls, new_fs, e)
3580
- end
3581
-
3582
- ------------------------------------------------------------------------
3583
- -- parse a list of comma-separated expressions
3584
- -- * used is multiple locations
3585
- ------------------------------------------------------------------------
3586
- function luaY:explist1(ls, v)
3587
- -- explist1 -> expr { ',' expr }
3588
- local n = 1 -- at least one expression
3589
- self:expr(ls, v)
3590
- while self:testnext(ls, ",") do
3591
- luaK:exp2nextreg(ls.fs, v)
3592
- self:expr(ls, v)
3593
- n = n + 1
3594
- end
3595
- return n
3596
- end
3597
-
3598
- ------------------------------------------------------------------------
3599
- -- parse the parameters of a function call
3600
- -- * contrast with parlist(), used in function declarations
3601
- -- * used in primaryexp()
3602
- ------------------------------------------------------------------------
3603
- function luaY:funcargs(ls, f)
3604
- local fs = ls.fs
3605
- local args = {} -- expdesc
3606
- local nparams
3607
- local line = ls.linenumber
3608
- local c = ls.t.token
3609
- if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
3610
- if line ~= ls.lastline then
3611
- luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
3612
- end
3613
- luaX:next(ls)
3614
- if ls.t.token == ")" then -- arg list is empty?
3615
- args.k = "VVOID"
3616
- else
3617
- self:explist1(ls, args)
3618
- luaK:setmultret(fs, args)
3619
- end
3620
- self:check_match(ls, ")", "(", line)
3621
- elseif c == "{" then -- funcargs -> constructor
3622
- self:constructor(ls, args)
3623
- elseif c == "TK_STRING" then -- funcargs -> STRING
3624
- self:codestring(ls, args, ls.t.seminfo)
3625
- luaX:next(ls) -- must use 'seminfo' before 'next'
3626
- else
3627
- luaX:syntaxerror(ls, "function arguments expected")
3628
- return
3629
- end
3630
- lua_assert(f.k == "VNONRELOC")
3631
- local base = f.info -- base register for call
3632
- if self:hasmultret(args.k) then
3633
- nparams = self.LUA_MULTRET -- open call
3634
- else
3635
- if args.k ~= "VVOID" then
3636
- luaK:exp2nextreg(fs, args) -- close last argument
3637
- end
3638
- nparams = fs.freereg - (base + 1)
3639
- end
3640
- self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
3641
- luaK:fixline(fs, line)
3642
- fs.freereg = base + 1 -- call remove function and arguments and leaves
3643
- -- (unless changed) one result
3644
- end
3645
-
3646
- --[[--------------------------------------------------------------------
3647
- -- Expression parsing
3648
- ----------------------------------------------------------------------]]
3649
-
3650
- ------------------------------------------------------------------------
3651
- -- parses an expression in parentheses or a single variable
3652
- -- * used in primaryexp()
3653
- ------------------------------------------------------------------------
3654
- function luaY:prefixexp(ls, v)
3655
- -- prefixexp -> NAME | '(' expr ')'
3656
- local c = ls.t.token
3657
- if c == "(" then
3658
- local line = ls.linenumber
3659
- luaX:next(ls)
3660
- self:expr(ls, v)
3661
- self:check_match(ls, ")", "(", line)
3662
- luaK:dischargevars(ls.fs, v)
3663
- elseif c == "TK_NAME" then
3664
- self:singlevar(ls, v)
3665
- else
3666
- luaX:syntaxerror(ls, "unexpected symbol")
3667
- end --if c
3668
- return
3669
- end
3670
-
3671
- ------------------------------------------------------------------------
3672
- -- parses a prefixexp (an expression in parentheses or a single variable)
3673
- -- or a function call specification
3674
- -- * used in simpleexp(), assignment(), exprstat()
3675
- ------------------------------------------------------------------------
3676
- function luaY:primaryexp(ls, v)
3677
- -- primaryexp ->
3678
- -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
3679
- local fs = ls.fs
3680
- self:prefixexp(ls, v)
3681
- while true do
3682
- local c = ls.t.token
3683
- if c == "." then -- field
3684
- self:field(ls, v)
3685
- elseif c == "[" then -- '[' exp1 ']'
3686
- local key = {} -- expdesc
3687
- luaK:exp2anyreg(fs, v)
3688
- self:yindex(ls, key)
3689
- luaK:indexed(fs, v, key)
3690
- elseif c == ":" then -- ':' NAME funcargs
3691
- local key = {} -- expdesc
3692
- luaX:next(ls)
3693
- self:checkname(ls, key)
3694
- luaK:_self(fs, v, key)
3695
- self:funcargs(ls, v)
3696
- elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
3697
- luaK:exp2nextreg(fs, v)
3698
- self:funcargs(ls, v)
3699
- else
3700
- return
3701
- end --if c
3702
- end --while
3703
- end
3704
-
3705
- ------------------------------------------------------------------------
3706
- -- parses general expression types, constants handled here
3707
- -- * used in subexpr()
3708
- ------------------------------------------------------------------------
3709
- function luaY:simpleexp(ls, v)
3710
- -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
3711
- -- constructor | FUNCTION body | primaryexp
3712
- local c = ls.t.token
3713
- if c == "TK_NUMBER" then
3714
- self:init_exp(v, "VKNUM", 0)
3715
- v.nval = ls.t.seminfo
3716
- elseif c == "TK_STRING" then
3717
- self:codestring(ls, v, ls.t.seminfo)
3718
- elseif c == "TK_NIL" then
3719
- self:init_exp(v, "VNIL", 0)
3720
- elseif c == "TK_TRUE" then
3721
- self:init_exp(v, "VTRUE", 0)
3722
- elseif c == "TK_FALSE" then
3723
- self:init_exp(v, "VFALSE", 0)
3724
- elseif c == "TK_DOTS" then -- vararg
3725
- local fs = ls.fs
3726
- self:check_condition(
3727
- ls,
3728
- fs.f.is_vararg ~= 0,
3729
- "cannot use " .. self:LUA_QL("...") .. " outside a vararg function"
3730
- )
3731
- -- NOTE: the following substitutes for a bitop, but is value-specific
3732
- local is_vararg = fs.f.is_vararg
3733
- if is_vararg >= self.VARARG_NEEDSARG then
3734
- fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg'
3735
- end
3736
- self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
3737
- elseif c == "{" then -- constructor
3738
- self:constructor(ls, v)
3739
- return
3740
- elseif c == "TK_FUNCTION" then
3741
- luaX:next(ls)
3742
- self:body(ls, v, false, ls.linenumber)
3743
- return
3744
- else
3745
- self:primaryexp(ls, v)
3746
- return
3747
- end --if c
3748
- luaX:next(ls)
3749
- end
3750
-
3751
- ------------------------------------------------------------------------
3752
- -- Translates unary operators tokens if found, otherwise returns
3753
- -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
3754
- -- * used in subexpr()
3755
- ------------------------------------------------------------------------
3756
- function luaY:getunopr(op)
3757
- if op == "TK_NOT" then
3758
- return "OPR_NOT"
3759
- elseif op == "-" then
3760
- return "OPR_MINUS"
3761
- elseif op == "#" then
3762
- return "OPR_LEN"
3763
- else
3764
- return "OPR_NOUNOPR"
3765
- end
3766
- end
3767
-
3768
- ------------------------------------------------------------------------
3769
- -- Translates binary operator tokens if found, otherwise returns
3770
- -- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
3771
- -- * used in subexpr()
3772
- ------------------------------------------------------------------------
3773
- luaY.getbinopr_table = {
3774
- ["+"] = "OPR_ADD",
3775
- ["-"] = "OPR_SUB",
3776
- ["*"] = "OPR_MUL",
3777
- ["/"] = "OPR_DIV",
3778
- ["%"] = "OPR_MOD",
3779
- ["^"] = "OPR_POW",
3780
- ["TK_CONCAT"] = "OPR_CONCAT",
3781
- ["TK_NE"] = "OPR_NE",
3782
- ["TK_EQ"] = "OPR_EQ",
3783
- ["<"] = "OPR_LT",
3784
- ["TK_LE"] = "OPR_LE",
3785
- [">"] = "OPR_GT",
3786
- ["TK_GE"] = "OPR_GE",
3787
- ["TK_AND"] = "OPR_AND",
3788
- ["TK_OR"] = "OPR_OR",
3789
- }
3790
- function luaY:getbinopr(op)
3791
- local opr = self.getbinopr_table[op]
3792
- if opr then
3793
- return opr
3794
- else
3795
- return "OPR_NOBINOPR"
3796
- end
3797
- end
3798
-
3799
- ------------------------------------------------------------------------
3800
- -- the following priority table consists of pairs of left/right values
3801
- -- for binary operators (was a static const struct); grep for ORDER OPR
3802
- -- * the following struct is replaced:
3803
- -- static const struct {
3804
- -- lu_byte left; /* left priority for each binary operator */
3805
- -- lu_byte right; /* right priority */
3806
- -- } priority[] = { /* ORDER OPR */
3807
- ------------------------------------------------------------------------
3808
- luaY.priority = {
3809
- { 6, 6 },
3810
- { 6, 6 },
3811
- { 7, 7 },
3812
- { 7, 7 },
3813
- { 7, 7 }, -- `+' `-' `/' `%'
3814
- { 10, 9 },
3815
- { 5, 4 }, -- power and concat (right associative)
3816
- { 3, 3 },
3817
- { 3, 3 }, -- equality
3818
- { 3, 3 },
3819
- { 3, 3 },
3820
- { 3, 3 },
3821
- { 3, 3 }, -- order
3822
- { 2, 2 },
3823
- { 1, 1 }, -- logical (and/or)
3824
- }
3825
-
3826
- luaY.UNARY_PRIORITY = 8 -- priority for unary operators
3827
-
3828
- ------------------------------------------------------------------------
3829
- -- Parse subexpressions. Includes handling of unary operators and binary
3830
- -- operators. A subexpr is given the rhs priority level of the operator
3831
- -- immediately left of it, if any (limit is -1 if none,) and if a binop
3832
- -- is found, limit is compared with the lhs priority level of the binop
3833
- -- in order to determine which executes first.
3834
- ------------------------------------------------------------------------
3835
-
3836
- ------------------------------------------------------------------------
3837
- -- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
3838
- -- where 'binop' is any binary operator with a priority higher than 'limit'
3839
- -- * for priority lookups with self.priority[], 1=left and 2=right
3840
- -- * recursively called
3841
- -- * used in expr()
3842
- ------------------------------------------------------------------------
3843
- function luaY:subexpr(ls, v, limit)
3844
- self:enterlevel(ls)
3845
- local uop = self:getunopr(ls.t.token)
3846
- if uop ~= "OPR_NOUNOPR" then
3847
- luaX:next(ls)
3848
- self:subexpr(ls, v, self.UNARY_PRIORITY)
3849
- luaK:prefix(ls.fs, uop, v)
3850
- else
3851
- self:simpleexp(ls, v)
3852
- end
3853
- -- expand while operators have priorities higher than 'limit'
3854
- local op = self:getbinopr(ls.t.token)
3855
- while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
3856
- local v2 = {} -- expdesc
3857
- luaX:next(ls)
3858
- luaK:infix(ls.fs, op, v)
3859
- -- read sub-expression with higher priority
3860
- local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
3861
- luaK:posfix(ls.fs, op, v, v2)
3862
- op = nextop
3863
- end
3864
- self:leavelevel(ls)
3865
- return op -- return first untreated operator
3866
- end
3867
-
3868
- ------------------------------------------------------------------------
3869
- -- Expression parsing starts here. Function subexpr is entered with the
3870
- -- left operator (which is non-existent) priority of -1, which is lower
3871
- -- than all actual operators. Expr information is returned in parm v.
3872
- -- * used in multiple locations
3873
- ------------------------------------------------------------------------
3874
- function luaY:expr(ls, v)
3875
- self:subexpr(ls, v, 0)
3876
- end
3877
-
3878
- -- }====================================================================
3879
-
3880
- --[[--------------------------------------------------------------------
3881
- -- Rules for Statements
3882
- ----------------------------------------------------------------------]]
3883
-
3884
- ------------------------------------------------------------------------
3885
- -- checks next token, used as a look-ahead
3886
- -- * returns boolean instead of 0|1
3887
- -- * used in retstat(), chunk()
3888
- ------------------------------------------------------------------------
3889
- function luaY:block_follow(token)
3890
- if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END" or token == "TK_UNTIL" or token == "TK_EOS" then
3891
- return true
3892
- else
3893
- return false
3894
- end
3895
- end
3896
-
3897
- ------------------------------------------------------------------------
3898
- -- parse a code block or unit
3899
- -- * used in multiple functions
3900
- ------------------------------------------------------------------------
3901
- function luaY:block(ls)
3902
- -- block -> chunk
3903
- local fs = ls.fs
3904
- local bl = {} -- BlockCnt
3905
- self:enterblock(fs, bl, false)
3906
- self:chunk(ls)
3907
- lua_assert(bl.breaklist == luaK.NO_JUMP)
3908
- self:leaveblock(fs)
3909
- end
3910
-
3911
- ------------------------------------------------------------------------
3912
- -- structure to chain all variables in the left-hand side of an
3913
- -- assignment
3914
- -- struct LHS_assign:
3915
- -- prev -- (table: struct LHS_assign)
3916
- -- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
3917
- ------------------------------------------------------------------------
3918
-
3919
- ------------------------------------------------------------------------
3920
- -- check whether, in an assignment to a local variable, the local variable
3921
- -- is needed in a previous assignment (to a table). If so, save original
3922
- -- local value in a safe place and use this safe copy in the previous
3923
- -- assignment.
3924
- -- * used in assignment()
3925
- ------------------------------------------------------------------------
3926
- function luaY:check_conflict(ls, lh, v)
3927
- local fs = ls.fs
3928
- local extra = fs.freereg -- eventual position to save local variable
3929
- local conflict = false
3930
- while lh do
3931
- if lh.v.k == "VINDEXED" then
3932
- if lh.v.info == v.info then -- conflict?
3933
- conflict = true
3934
- lh.v.info = extra -- previous assignment will use safe copy
3935
- end
3936
- if lh.v.aux == v.info then -- conflict?
3937
- conflict = true
3938
- lh.v.aux = extra -- previous assignment will use safe copy
3939
- end
3940
- end
3941
- lh = lh.prev
3942
- end
3943
- if conflict then
3944
- luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
3945
- luaK:reserveregs(fs, 1)
3946
- end
3947
- end
3948
-
3949
- ------------------------------------------------------------------------
3950
- -- parse a variable assignment sequence
3951
- -- * recursively called
3952
- -- * used in exprstat()
3953
- ------------------------------------------------------------------------
3954
- function luaY:assignment(ls, lh, nvars)
3955
- local e = {} -- expdesc
3956
- -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
3957
- local c = lh.v.k
3958
- self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL" or c == "VINDEXED", "syntax error")
3959
- if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
3960
- local nv = {} -- LHS_assign
3961
- nv.v = {}
3962
- nv.prev = lh
3963
- self:primaryexp(ls, nv.v)
3964
- if nv.v.k == "VLOCAL" then
3965
- self:check_conflict(ls, lh, nv.v)
3966
- end
3967
- self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls, "variables in assignment")
3968
- self:assignment(ls, nv, nvars + 1)
3969
- else -- assignment -> '=' explist1
3970
- self:checknext(ls, "=")
3971
- local nexps = self:explist1(ls, e)
3972
- if nexps ~= nvars then
3973
- self:adjust_assign(ls, nvars, nexps, e)
3974
- if nexps > nvars then
3975
- ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
3976
- end
3977
- else
3978
- luaK:setoneret(ls.fs, e) -- close last expression
3979
- luaK:storevar(ls.fs, lh.v, e)
3980
- return -- avoid default
3981
- end
3982
- end
3983
- self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
3984
- luaK:storevar(ls.fs, lh.v, e)
3985
- end
3986
-
3987
- ------------------------------------------------------------------------
3988
- -- parse condition in a repeat statement or an if control structure
3989
- -- * used in repeatstat(), test_then_block()
3990
- ------------------------------------------------------------------------
3991
- function luaY:cond(ls)
3992
- -- cond -> exp
3993
- local v = {} -- expdesc
3994
- self:expr(ls, v) -- read condition
3995
- if v.k == "VNIL" then
3996
- v.k = "VFALSE"
3997
- end -- 'falses' are all equal here
3998
- luaK:goiftrue(ls.fs, v)
3999
- return v.f
4000
- end
4001
-
4002
- ------------------------------------------------------------------------
4003
- -- parse a break statement
4004
- -- * used in statements()
4005
- ------------------------------------------------------------------------
4006
- function luaY:breakstat(ls)
4007
- -- stat -> BREAK
4008
- local fs = ls.fs
4009
- local bl = fs.bl
4010
- local upval = false
4011
- while bl and not bl.isbreakable do
4012
- if bl.upval then
4013
- upval = true
4014
- end
4015
- bl = bl.previous
4016
- end
4017
- if not bl then
4018
- luaX:syntaxerror(ls, "no loop to break")
4019
- end
4020
- if upval then
4021
- luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
4022
- end
4023
- bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
4024
- end
4025
-
4026
- ------------------------------------------------------------------------
4027
- -- parse a while-do control structure, body processed by block()
4028
- -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
4029
- -- the function's implementation can be removed
4030
- -- * used in statements()
4031
- ------------------------------------------------------------------------
4032
- function luaY:whilestat(ls, line)
4033
- -- whilestat -> WHILE cond DO block END
4034
- local fs = ls.fs
4035
- local bl = {} -- BlockCnt
4036
- luaX:next(ls) -- skip WHILE
4037
- local whileinit = luaK:getlabel(fs)
4038
- local condexit = self:cond(ls)
4039
- self:enterblock(fs, bl, true)
4040
- self:checknext(ls, "TK_DO")
4041
- self:block(ls)
4042
- luaK:patchlist(fs, luaK:jump(fs), whileinit)
4043
- self:check_match(ls, "TK_END", "TK_WHILE", line)
4044
- self:leaveblock(fs)
4045
- luaK:patchtohere(fs, condexit) -- false conditions finish the loop
4046
- end
4047
-
4048
- ------------------------------------------------------------------------
4049
- -- parse a repeat-until control structure, body parsed by chunk()
4050
- -- * used in statements()
4051
- ------------------------------------------------------------------------
4052
- function luaY:repeatstat(ls, line)
4053
- -- repeatstat -> REPEAT block UNTIL cond
4054
- local fs = ls.fs
4055
- local repeat_init = luaK:getlabel(fs)
4056
- local bl1, bl2 = {}, {} -- BlockCnt
4057
- self:enterblock(fs, bl1, true) -- loop block
4058
- self:enterblock(fs, bl2, false) -- scope block
4059
- luaX:next(ls) -- skip REPEAT
4060
- self:chunk(ls)
4061
- self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
4062
- local condexit = self:cond(ls) -- read condition (inside scope block)
4063
- if not bl2.upval then -- no upvalues?
4064
- self:leaveblock(fs) -- finish scope
4065
- luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop
4066
- else -- complete semantics when there are upvalues
4067
- self:breakstat(ls) -- if condition then break
4068
- luaK:patchtohere(ls.fs, condexit) -- else...
4069
- self:leaveblock(fs) -- finish scope...
4070
- luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat
4071
- end
4072
- self:leaveblock(fs) -- finish loop
4073
- end
4074
-
4075
- ------------------------------------------------------------------------
4076
- -- parse the single expressions needed in numerical for loops
4077
- -- * used in fornum()
4078
- ------------------------------------------------------------------------
4079
- function luaY:exp1(ls)
4080
- local e = {} -- expdesc
4081
- self:expr(ls, e)
4082
- local k = e.k
4083
- luaK:exp2nextreg(ls.fs, e)
4084
- return k
4085
- end
4086
-
4087
- ------------------------------------------------------------------------
4088
- -- parse a for loop body for both versions of the for loop
4089
- -- * used in fornum(), forlist()
4090
- ------------------------------------------------------------------------
4091
- function luaY:forbody(ls, base, line, nvars, isnum)
4092
- -- forbody -> DO block
4093
- local bl = {} -- BlockCnt
4094
- local fs = ls.fs
4095
- self:adjustlocalvars(ls, 3) -- control variables
4096
- self:checknext(ls, "TK_DO")
4097
- local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP) or luaK:jump(fs)
4098
- self:enterblock(fs, bl, false) -- scope for declared variables
4099
- self:adjustlocalvars(ls, nvars)
4100
- luaK:reserveregs(fs, nvars)
4101
- self:block(ls)
4102
- self:leaveblock(fs) -- end of scope for declared variables
4103
- luaK:patchtohere(fs, prep)
4104
- local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
4105
- or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
4106
- luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop
4107
- luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
4108
- end
4109
-
4110
- ------------------------------------------------------------------------
4111
- -- parse a numerical for loop, calls forbody()
4112
- -- * used in forstat()
4113
- ------------------------------------------------------------------------
4114
- function luaY:fornum(ls, varname, line)
4115
- -- fornum -> NAME = exp1,exp1[,exp1] forbody
4116
- local fs = ls.fs
4117
- local base = fs.freereg
4118
- self:new_localvarliteral(ls, "(for index)", 0)
4119
- self:new_localvarliteral(ls, "(for limit)", 1)
4120
- self:new_localvarliteral(ls, "(for step)", 2)
4121
- self:new_localvar(ls, varname, 3)
4122
- self:checknext(ls, "=")
4123
- self:exp1(ls) -- initial value
4124
- self:checknext(ls, ",")
4125
- self:exp1(ls) -- limit
4126
- if self:testnext(ls, ",") then
4127
- self:exp1(ls) -- optional step
4128
- else -- default step = 1
4129
- luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
4130
- luaK:reserveregs(fs, 1)
4131
- end
4132
- self:forbody(ls, base, line, 1, true)
4133
- end
4134
-
4135
- ------------------------------------------------------------------------
4136
- -- parse a generic for loop, calls forbody()
4137
- -- * used in forstat()
4138
- ------------------------------------------------------------------------
4139
- function luaY:forlist(ls, indexname)
4140
- -- forlist -> NAME {,NAME} IN explist1 forbody
4141
- local fs = ls.fs
4142
- local e = {} -- expdesc
4143
- local nvars = 0
4144
- local base = fs.freereg
4145
- -- create control variables
4146
- self:new_localvarliteral(ls, "(for generator)", nvars)
4147
- nvars = nvars + 1
4148
- self:new_localvarliteral(ls, "(for state)", nvars)
4149
- nvars = nvars + 1
4150
- self:new_localvarliteral(ls, "(for control)", nvars)
4151
- nvars = nvars + 1
4152
- -- create declared variables
4153
- self:new_localvar(ls, indexname, nvars)
4154
- nvars = nvars + 1
4155
- while self:testnext(ls, ",") do
4156
- self:new_localvar(ls, self:str_checkname(ls), nvars)
4157
- nvars = nvars + 1
4158
- end
4159
- self:checknext(ls, "TK_IN")
4160
- local line = ls.linenumber
4161
- self:adjust_assign(ls, 3, self:explist1(ls, e), e)
4162
- luaK:checkstack(fs, 3) -- extra space to call generator
4163
- self:forbody(ls, base, line, nvars - 3, false)
4164
- end
4165
-
4166
- ------------------------------------------------------------------------
4167
- -- initial parsing for a for loop, calls fornum() or forlist()
4168
- -- * used in statements()
4169
- ------------------------------------------------------------------------
4170
- function luaY:forstat(ls, line)
4171
- -- forstat -> FOR (fornum | forlist) END
4172
- local fs = ls.fs
4173
- local bl = {} -- BlockCnt
4174
- self:enterblock(fs, bl, true) -- scope for loop and control variables
4175
- luaX:next(ls) -- skip `for'
4176
- local varname = self:str_checkname(ls) -- first variable name
4177
- local c = ls.t.token
4178
- if c == "=" then
4179
- self:fornum(ls, varname, line)
4180
- elseif c == "," or c == "TK_IN" then
4181
- self:forlist(ls, varname)
4182
- else
4183
- luaX:syntaxerror(ls, self:LUA_QL("=") .. " or " .. self:LUA_QL("in") .. " expected")
4184
- end
4185
- self:check_match(ls, "TK_END", "TK_FOR", line)
4186
- self:leaveblock(fs) -- loop scope (`break' jumps to this point)
4187
- end
4188
-
4189
- ------------------------------------------------------------------------
4190
- -- parse part of an if control structure, including the condition
4191
- -- * used in ifstat()
4192
- ------------------------------------------------------------------------
4193
- function luaY:test_then_block(ls)
4194
- -- test_then_block -> [IF | ELSEIF] cond THEN block
4195
- luaX:next(ls) -- skip IF or ELSEIF
4196
- local condexit = self:cond(ls)
4197
- self:checknext(ls, "TK_THEN")
4198
- self:block(ls) -- `then' part
4199
- return condexit
4200
- end
4201
-
4202
- ------------------------------------------------------------------------
4203
- -- parse an if control structure
4204
- -- * used in statements()
4205
- ------------------------------------------------------------------------
4206
- function luaY:ifstat(ls, line)
4207
- -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
4208
- local fs = ls.fs
4209
- local escapelist = luaK.NO_JUMP
4210
- local flist = self:test_then_block(ls) -- IF cond THEN block
4211
- while ls.t.token == "TK_ELSEIF" do
4212
- escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
4213
- luaK:patchtohere(fs, flist)
4214
- flist = self:test_then_block(ls) -- ELSEIF cond THEN block
4215
- end
4216
- if ls.t.token == "TK_ELSE" then
4217
- escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
4218
- luaK:patchtohere(fs, flist)
4219
- luaX:next(ls) -- skip ELSE (after patch, for correct line info)
4220
- self:block(ls) -- 'else' part
4221
- else
4222
- escapelist = luaK:concat(fs, escapelist, flist)
4223
- end
4224
- luaK:patchtohere(fs, escapelist)
4225
- self:check_match(ls, "TK_END", "TK_IF", line)
4226
- end
4227
-
4228
- ------------------------------------------------------------------------
4229
- -- parse a local function statement
4230
- -- * used in statements()
4231
- ------------------------------------------------------------------------
4232
- function luaY:localfunc(ls)
4233
- local v, b = {}, {} -- expdesc
4234
- local fs = ls.fs
4235
- self:new_localvar(ls, self:str_checkname(ls), 0)
4236
- self:init_exp(v, "VLOCAL", fs.freereg)
4237
- luaK:reserveregs(fs, 1)
4238
- self:adjustlocalvars(ls, 1)
4239
- self:body(ls, b, false, ls.linenumber)
4240
- luaK:storevar(fs, v, b)
4241
- -- debug information will only see the variable after this point!
4242
- self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
4243
- end
4244
-
4245
- ------------------------------------------------------------------------
4246
- -- parse a local variable declaration statement
4247
- -- * used in statements()
4248
- ------------------------------------------------------------------------
4249
- function luaY:localstat(ls)
4250
- -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
4251
- local nvars = 0
4252
- local nexps
4253
- local e = {} -- expdesc
4254
- repeat
4255
- self:new_localvar(ls, self:str_checkname(ls), nvars)
4256
- nvars = nvars + 1
4257
- until not self:testnext(ls, ",")
4258
- if self:testnext(ls, "=") then
4259
- nexps = self:explist1(ls, e)
4260
- else
4261
- e.k = "VVOID"
4262
- nexps = 0
4263
- end
4264
- self:adjust_assign(ls, nvars, nexps, e)
4265
- self:adjustlocalvars(ls, nvars)
4266
- end
4267
-
4268
- ------------------------------------------------------------------------
4269
- -- parse a function name specification
4270
- -- * used in funcstat()
4271
- ------------------------------------------------------------------------
4272
- function luaY:funcname(ls, v)
4273
- -- funcname -> NAME {field} [':' NAME]
4274
- local needself = false
4275
- self:singlevar(ls, v)
4276
- while ls.t.token == "." do
4277
- self:field(ls, v)
4278
- end
4279
- if ls.t.token == ":" then
4280
- needself = true
4281
- self:field(ls, v)
4282
- end
4283
- return needself
4284
- end
4285
-
4286
- ------------------------------------------------------------------------
4287
- -- parse a function statement
4288
- -- * used in statements()
4289
- ------------------------------------------------------------------------
4290
- function luaY:funcstat(ls, line)
4291
- -- funcstat -> FUNCTION funcname body
4292
- local v, b = {}, {} -- expdesc
4293
- luaX:next(ls) -- skip FUNCTION
4294
- local needself = self:funcname(ls, v)
4295
- self:body(ls, b, needself, line)
4296
- luaK:storevar(ls.fs, v, b)
4297
- luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
4298
- end
4299
-
4300
- ------------------------------------------------------------------------
4301
- -- parse a function call with no returns or an assignment statement
4302
- -- * used in statements()
4303
- ------------------------------------------------------------------------
4304
- function luaY:exprstat(ls)
4305
- -- stat -> func | assignment
4306
- local fs = ls.fs
4307
- local v = {} -- LHS_assign
4308
- v.v = {}
4309
- self:primaryexp(ls, v.v)
4310
- if v.v.k == "VCALL" then -- stat -> func
4311
- luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results
4312
- else -- stat -> assignment
4313
- v.prev = nil
4314
- self:assignment(ls, v, 1)
4315
- end
4316
- end
4317
-
4318
- ------------------------------------------------------------------------
4319
- -- parse a return statement
4320
- -- * used in statements()
4321
- ------------------------------------------------------------------------
4322
- function luaY:retstat(ls)
4323
- -- stat -> RETURN explist
4324
- local fs = ls.fs
4325
- local e = {} -- expdesc
4326
- local first, nret -- registers with returned values
4327
- luaX:next(ls) -- skip RETURN
4328
- if self:block_follow(ls.t.token) or ls.t.token == ";" then
4329
- first, nret = 0, 0 -- return no values
4330
- else
4331
- nret = self:explist1(ls, e) -- optional return values
4332
- if self:hasmultret(e.k) then
4333
- luaK:setmultret(fs, e)
4334
- if e.k == "VCALL" and nret == 1 then -- tail call?
4335
- luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
4336
- lua_assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
4337
- end
4338
- first = fs.nactvar
4339
- nret = self.LUA_MULTRET -- return all values
4340
- else
4341
- if nret == 1 then -- only one single value?
4342
- first = luaK:exp2anyreg(fs, e)
4343
- else
4344
- luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
4345
- first = fs.nactvar -- return all 'active' values
4346
- lua_assert(nret == fs.freereg - first)
4347
- end
4348
- end --if
4349
- end --if
4350
- luaK:ret(fs, first, nret)
4351
- end
4352
-
4353
- ------------------------------------------------------------------------
4354
- -- initial parsing for statements, calls a lot of functions
4355
- -- * returns boolean instead of 0|1
4356
- -- * used in chunk()
4357
- ------------------------------------------------------------------------
4358
- function luaY:statement(ls)
4359
- local line = ls.linenumber -- may be needed for error messages
4360
- local c = ls.t.token
4361
- if c == "TK_IF" then -- stat -> ifstat
4362
- self:ifstat(ls, line)
4363
- return false
4364
- elseif c == "TK_WHILE" then -- stat -> whilestat
4365
- self:whilestat(ls, line)
4366
- return false
4367
- elseif c == "TK_DO" then -- stat -> DO block END
4368
- luaX:next(ls) -- skip DO
4369
- self:block(ls)
4370
- self:check_match(ls, "TK_END", "TK_DO", line)
4371
- return false
4372
- elseif c == "TK_FOR" then -- stat -> forstat
4373
- self:forstat(ls, line)
4374
- return false
4375
- elseif c == "TK_REPEAT" then -- stat -> repeatstat
4376
- self:repeatstat(ls, line)
4377
- return false
4378
- elseif c == "TK_FUNCTION" then -- stat -> funcstat
4379
- self:funcstat(ls, line)
4380
- return false
4381
- elseif c == "TK_LOCAL" then -- stat -> localstat
4382
- luaX:next(ls) -- skip LOCAL
4383
- if self:testnext(ls, "TK_FUNCTION") then -- local function?
4384
- self:localfunc(ls)
4385
- else
4386
- self:localstat(ls)
4387
- end
4388
- return false
4389
- elseif c == "TK_RETURN" then -- stat -> retstat
4390
- self:retstat(ls)
4391
- return true -- must be last statement
4392
- elseif c == "TK_BREAK" then -- stat -> breakstat
4393
- luaX:next(ls) -- skip BREAK
4394
- self:breakstat(ls)
4395
- return true -- must be last statement
4396
- else
4397
- self:exprstat(ls)
4398
- return false -- to avoid warnings
4399
- end --if c
4400
- end
4401
-
4402
- ------------------------------------------------------------------------
4403
- -- parse a chunk, which consists of a bunch of statements
4404
- -- * used in parser(), body(), block(), repeatstat()
4405
- ------------------------------------------------------------------------
4406
- function luaY:chunk(ls)
4407
- -- chunk -> { stat [';'] }
4408
- local islast = false
4409
- self:enterlevel(ls)
4410
- while not islast and not self:block_follow(ls.t.token) do
4411
- islast = self:statement(ls)
4412
- self:testnext(ls, ";")
4413
- lua_assert(ls.fs.f.maxstacksize >= ls.fs.freereg and ls.fs.freereg >= ls.fs.nactvar)
4414
- ls.fs.freereg = ls.fs.nactvar -- free registers
4415
- end
4416
- self:leavelevel(ls)
4417
- end
4418
-
4419
- -- }======================================================================
4420
-
4421
- luaX:init() -- required by llex
4422
- local LuaState = {} -- dummy, not actually used, but retained since
4423
- -- the intention is to complete a straight port
4424
-
4425
- ------------------------------------------------------------------------
4426
- -- interfacing to yueliang
4427
- ------------------------------------------------------------------------
4428
-
4429
- return function(source, name)
4430
- name = name or "compiled-lua"
4431
- -- luaZ:make_getF returns a file chunk reader
4432
- -- luaZ:init returns a zio input stream
4433
- local zio = luaZ:init(luaZ:make_getF(source), nil)
4434
- if not zio then
4435
- return
4436
- end
4437
- -- luaY:parser parses the input stream
4438
- -- func is the function prototype in tabular form; in C, func can
4439
- -- now be used directly by the VM, this can't be done in Lua
4440
-
4441
- local func = luaY:parser(LuaState, zio, nil, "@" .. name)
4442
- -- luaU:make_setS returns a string chunk writer
4443
- local writer, buff = luaU:make_setS()
4444
- -- luaU:dump builds a binary chunk
4445
- luaU:dump(LuaState, func, writer, buff)
4446
- -- a string.dump equivalent in returned
4447
-
4448
- return buff.data
4449
- end