PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/source/Parser.ooc

http://github.com/fperrad/ooc-lua
Unknown | 2234 lines | 1936 code | 298 blank | 0 comment | 0 complexity | a8a9aa5862e8ac43d17a84cb129ccde3 MD5 | raw file
  1. import math
  2. import structs/ArrayList
  3. import Lexer
  4. import Types
  5. import Opcodes
  6. ExpKind: enum {
  7. VVOID, /* no value */
  8. VNIL,
  9. VTRUE,
  10. VFALSE,
  11. VK, /* info = index of constant in `k' */
  12. VKNUM, /* nval = numerical value */
  13. VNONRELOC, /* info = result register */
  14. VLOCAL, /* info = local register */
  15. VUPVAL, /* info = index of upvalue in 'upvalues' */
  16. VINDEXED, /* t = table register/upvalue; idx = index R/K */
  17. VJMP, /* info = instruction pc */
  18. VRELOCABLE, /* info = instruction pc */
  19. VCALL, /* info = instruction pc */
  20. VVARARG /* info = instruction pc */
  21. vkisvar: inline func -> Bool {
  22. return (ExpKind VLOCAL <= this) && (this <= ExpKind VINDEXED)
  23. }
  24. vkisinreg: inline func -> Bool {
  25. return (this == ExpKind VNONRELOC) || (this == ExpKind VLOCAL)
  26. }
  27. hasmultret: inline func -> Bool {
  28. return (this == ExpKind VCALL) || (this == ExpKind VVARARG)
  29. }
  30. }
  31. ExpDesc: cover {
  32. k: ExpKind
  33. ind_idx: Int16 /* index (R/K) */
  34. ind_t: UInt8 /* table (register or upvalue) */
  35. ind_vt: ExpKind /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
  36. info: Int /* for generic use */
  37. nval: Double /* for VKNUM lua_Number */
  38. t: Int /* patch list of `exit when true' */
  39. f: Int /* patch list of `exit when false' */
  40. isnumeral: inline func -> Bool {
  41. return k == ExpKind VKNUM && t == NO_JUMP && f == NO_JUMP
  42. }
  43. hasjumps: inline func -> Bool {
  44. return t != f
  45. }
  46. }
  47. init_exp: inline func(e: ExpDesc@, k: ExpKind, info: Int) {
  48. e k = k
  49. e info = info
  50. e ind_idx = 0
  51. e ind_t = 0
  52. e ind_vt = ExpKind VVOID
  53. e f = NO_JUMP
  54. e t = NO_JUMP
  55. }
  56. /* state needed to generate code for a given function */
  57. FuncState: final class {
  58. f: LuaProto /* current function header */
  59. h: Table /* table to find (and reuse) elements in `k' */
  60. prev: FuncState /* enclosing function */
  61. ls: Parser /* lexical state */
  62. bl: BlockCnt* /* chain of current blocks */
  63. lasttarget: Int /* `pc' of last `jump target' */
  64. jpc: Int /* list of pending jumps to `pc' */
  65. freereg: Int /* first free register */
  66. firstlocal: Int /* index of first local var of this function */
  67. nactvar: Short /* number of active local variables */
  68. init: func(=ls, =prev) {
  69. f = LuaProto new()
  70. f source = ls source
  71. f maxstacksize = 2 /* registers 0/1 are always valid */
  72. h = Table new(0, 0)
  73. bl = null
  74. lasttarget = 0
  75. jpc = NO_JUMP
  76. freereg = 0
  77. firstlocal = ls actvar getSize()
  78. nactvar = 0
  79. }
  80. finalize: func -> FuncState {
  81. luaK_ret(0, 0) /* final return */
  82. removevars(0)
  83. version(debug) {
  84. assert(! bl)
  85. }
  86. return prev
  87. }
  88. getlocvar: func(i: Int) -> LocVar* {
  89. idx := ls actvar get(firstlocal + i)
  90. version(debug) {
  91. assert(idx < f locvars getSize())
  92. }
  93. return f locvars data as LocVar* + idx
  94. }
  95. enterblock: func(_bl: BlockCnt@, _isbreakable: Bool) {
  96. _bl breaklist = NO_JUMP
  97. _bl isbreakable = _isbreakable
  98. _bl nactvar = nactvar
  99. _bl upval = false
  100. _bl previous = bl
  101. bl = _bl&
  102. version(debug) {
  103. assert(freereg == nactvar)
  104. }
  105. }
  106. leaveblock: func {
  107. _bl := bl
  108. bl = _bl@ previous
  109. removevars(_bl@ nactvar)
  110. if (_bl@ upval)
  111. luaK_codeABC(OpCode OP_CLOSE, _bl@ nactvar, 0, 0)
  112. version(debug) {
  113. /* a block either controls scope or breaks (never both) */
  114. assert(!_bl@ isbreakable || !_bl@ upval)
  115. assert(_bl@ nactvar == nactvar)
  116. }
  117. freereg = nactvar /* free registers */
  118. luaK_patchtohere(_bl@ breaklist)
  119. }
  120. removevars: func(tolevel: Int) {
  121. pc := f code getSize()
  122. actvar := ls actvar
  123. while (nactvar > tolevel) {
  124. nactvar -= 1
  125. pvar := getlocvar(nactvar)
  126. pvar@ endpc = pc
  127. actvar removeAt(actvar lastIndex())
  128. }
  129. }
  130. searchupvalue: func(name: String) -> Int {
  131. up := f upvalues
  132. for (i in 0 .. up getSize())
  133. if (up get(i) name equals?(name))
  134. return i
  135. return -1 /* not found */
  136. }
  137. newupvalue: func(name: String, v: ExpDesc@) -> Int {
  138. up := f upvalues
  139. idx := up getSize()
  140. up add(UpvalDesc new(name, v k == ExpKind VLOCAL, v info))
  141. return idx
  142. }
  143. searchvar: func(n: String) -> Int {
  144. i := nactvar - 1
  145. while (i >= 0) {
  146. pvar := getlocvar(i)
  147. if (pvar@ varname equals?(n))
  148. return i
  149. i -= 1
  150. }
  151. return -1; /* not found */
  152. }
  153. /*
  154. Mark block where variable at given level was defined
  155. (to emit OP_CLOSE later).
  156. */
  157. markupval: func(level: Int) {
  158. _bl := bl
  159. while (_bl) {
  160. if (!(_bl@ nactvar > level))
  161. break
  162. _bl = _bl@ previous
  163. }
  164. if (_bl)
  165. _bl@ upval = true
  166. }
  167. /*
  168. Find variable with given name 'n'. If it is an upvalue, add this
  169. upvalue into all intermediate functions.
  170. */
  171. singlevaraux: func(n: String, var: ExpDesc@, base: Int) -> ExpKind {
  172. v := searchvar(n) /* look up locals at current level */
  173. if (v >= 0) { /* found? */
  174. init_exp(var&, ExpKind VLOCAL, v) /* variable is local */
  175. if (!base)
  176. markupval(v) /* local will be used as an upval */
  177. return ExpKind VLOCAL
  178. }
  179. else { /* not found as local at current level; try upvalues */
  180. idx := searchupvalue(n) /* try existing upvalues */
  181. if (idx < 0) { /* not found? */
  182. if (! prev || /* no more levels */
  183. prev singlevaraux(n, var&, 0) == ExpKind VVOID) /* try upper levels */
  184. return ExpKind VVOID; /* not found; is a global */
  185. /* else was LOCAL or UPVAL */
  186. idx = newupvalue(n, var&) /* will be a new upvalue */
  187. }
  188. init_exp(var&, ExpKind VUPVAL, idx)
  189. return ExpKind VUPVAL
  190. }
  191. }
  192. luaK_nil: func(_from, n: Int) {
  193. pc := f code getSize()
  194. if (pc > lasttarget) { /* no jumps to current position? */
  195. previous := f code data as Instruction* + pc - 1
  196. if (previous@ getOpcode() == OpCode OP_LOADNIL) {
  197. pfrom := previous@ getarg_A()
  198. pto := previous@ getarg_B()
  199. if (pfrom <= _from && _from <= pto + 1) { /* can connect both? */
  200. if (_from + n - 1 > pto)
  201. previous@ = previous@ setarg_B(_from + n - 1)
  202. return
  203. }
  204. }
  205. }
  206. luaK_codeABC(OpCode OP_LOADNIL, _from, _from + n - 1, 0) /* else no optimization */
  207. }
  208. luaK_jump: func -> Int {
  209. save := jpc /* save list of jumps to here */
  210. jpc = NO_JUMP
  211. j := luaK_codeABx(OpCode OP_JMP, 0, NO_JUMP + MAXARG_sBx)
  212. luaK_concat(j&, save) /* keep them on hold */
  213. return j
  214. }
  215. luaK_ret: func(first, nret: Int) {
  216. luaK_codeABC(OpCode OP_RETURN, first, nret+1, 0)
  217. }
  218. _condjump: func(op: OpCode, A, B, C: Int) -> Int {
  219. luaK_codeABC(op, A, B, C)
  220. return luaK_jump()
  221. }
  222. _fixjump: func(pc, dest: Int) {
  223. jmp := f code data as Instruction* + pc
  224. offset := dest - (pc + 1)
  225. version(debug) {
  226. assert(dest != NO_JUMP)
  227. }
  228. if (offset abs() > MAXARG_sBx)
  229. ls syntaxError("control structure too long")
  230. jmp@ = jmp@ setarg_sBx(offset)
  231. }
  232. /*
  233. ** returns current `pc' and marks it as a jump target (to avoid wrong
  234. ** optimizations with consecutive instructions not in the same basic block).
  235. */
  236. luaK_getlabel: func -> Int {
  237. lasttarget = f code getSize()
  238. return lasttarget
  239. }
  240. _getjump: func(pc: Int) -> Int {
  241. offset := f code get(pc) getarg_sBx()
  242. if (offset == NO_JUMP) /* point to itself represents end of list */
  243. return NO_JUMP /* end of list */
  244. else
  245. return pc + 1 + offset /* turn offset into absolute position */
  246. }
  247. _getjumpcontrol: func(pc: Int) -> Instruction* {
  248. pi := f code data as Instruction* + pc
  249. if (pc >= 1 && (pi-1)@ getOpcode() testTMode())
  250. return pi - 1
  251. else
  252. return pi
  253. }
  254. /*
  255. ** check whether list has any jump that do not produce a value
  256. ** (or produce an inverted value)
  257. */
  258. _need_value: func(list: Int) -> Bool {
  259. while (list != NO_JUMP) {
  260. i := _getjumpcontrol(list)@
  261. if (i getOpcode() != OpCode OP_TESTSET)
  262. return true
  263. list = _getjump(list)
  264. }
  265. return false /* not found */
  266. }
  267. _patchtestreg: func(node, reg: Int) -> Int {
  268. i := _getjumpcontrol(node)
  269. if (i@ getOpcode() != OpCode OP_TESTSET)
  270. return 0; /* cannot patch other instructions */
  271. if (reg != NO_REG && reg != i@ getarg_B())
  272. i@ = i@ setarg_A(reg)
  273. else /* no register to put value or register already has the value */
  274. i@ = Instruction createABC(OpCode OP_TEST, i@ getarg_B(), 0, i@ getarg_C())
  275. return 1
  276. }
  277. _removevalues: func(list: Int) {
  278. while (list != NO_JUMP) {
  279. _patchtestreg(list, NO_REG)
  280. list = _getjump(list)
  281. }
  282. }
  283. _patchlistaux: func(list, vtarget, reg, dtarget: Int) {
  284. while (list != NO_JUMP) {
  285. next := _getjump(list)
  286. if (_patchtestreg(list, reg))
  287. _fixjump(list, vtarget)
  288. else
  289. _fixjump(list, dtarget) /* jump to default target */
  290. list = next
  291. }
  292. }
  293. _dischargejpc: func {
  294. pc := f code getSize()
  295. _patchlistaux(jpc, pc, NO_REG, pc)
  296. jpc = NO_JUMP
  297. }
  298. luaK_patchlist: func(list, target: Int) {
  299. pc := f code getSize()
  300. if (target == pc)
  301. luaK_patchtohere(list)
  302. else {
  303. version(debug) {
  304. assert(target < pc)
  305. }
  306. _patchlistaux(list, target, NO_REG, target)
  307. }
  308. }
  309. luaK_patchtohere: func(list: Int) {
  310. luaK_getlabel()
  311. luaK_concat(jpc&, list)
  312. }
  313. luaK_concat: func(l1: Int*, l2: Int) {
  314. if (l2 == NO_JUMP)
  315. return
  316. else if (l1@ == NO_JUMP)
  317. l1@ = l2
  318. else {
  319. list := l1@
  320. next := _getjump(list)
  321. while (next != NO_JUMP) { /* find last element */
  322. list = next
  323. next = _getjump(next)
  324. }
  325. _fixjump(list, l2)
  326. }
  327. }
  328. luaK_code: func(i: Instruction) -> Int{
  329. _dischargejpc() /* `pc' will change */
  330. pc := f code getSize()
  331. /* put new instruction in code array */
  332. f code add(i)
  333. /* save corresponding line information */
  334. f lineinfo add(ls lastline)
  335. return pc
  336. }
  337. luaK_codeABC: func(o: OpCode, a, b, c: Int) -> Int {
  338. version(debug) {
  339. assert(o getOpMode() == OpMode iABC)
  340. assert(o getBMode() != OpArgMask OpArgN || b == 0)
  341. assert(o getCMode() != OpArgMask OpArgN || c == 0)
  342. assert(a <= MAXARG_A)
  343. assert(b <= MAXARG_B)
  344. assert(c <= MAXARG_C)
  345. }
  346. return luaK_code(Instruction createABC(o, a, b, c))
  347. }
  348. luaK_codeABx: func(o: OpCode, a: Int, bc: UInt) -> Int {
  349. version(debug) {
  350. assert(o getOpMode() == OpMode iABx || o getOpMode() == OpMode iAsBx)
  351. assert(o getCMode() == OpArgMask OpArgN)
  352. assert(a <= MAXARG_A)
  353. assert(bc <= MAXARG_Bx)
  354. }
  355. return luaK_code(Instruction createABx(o, a, bc))
  356. }
  357. luaK_codeABxX: func(o: OpCode, reg, k: Int) -> Int {
  358. if (k < MAXARG_Bx)
  359. return luaK_codeABx(o, reg, k + 1)
  360. else {
  361. p := luaK_codeABx(o, reg, 0)
  362. version(debug) {
  363. assert(k <= MAXARG_Ax)
  364. }
  365. luaK_code(Instruction createAx(OpCode OP_EXTRAARG, k))
  366. return p
  367. }
  368. }
  369. luaK_checkstack: func(n: Int) {
  370. newstack := freereg + n
  371. if (newstack > f maxstacksize) {
  372. if (newstack >= MAXSTACK)
  373. ls syntaxError("function or expression too complex")
  374. f maxstacksize = newstack
  375. }
  376. }
  377. luaK_reserveregs: func(n: Int) {
  378. luaK_checkstack(n)
  379. freereg += n
  380. }
  381. _freereg: func(reg: Int) {
  382. if (!(reg & BITRK) && reg >= nactvar) {
  383. freereg -= 1
  384. version(debug) {
  385. assert(reg == freereg)
  386. }
  387. }
  388. }
  389. _freeexp: func(e: ExpDesc@) {
  390. if (e k == ExpKind VNONRELOC)
  391. _freereg(e info)
  392. }
  393. _addk: func(key, v: LuaAny) -> Int {
  394. n := h get(key)
  395. if (n) {
  396. k := n as LuaNumber v as Int
  397. if (f k get(k) eq(v))
  398. return k
  399. /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
  400. go through and create a new entry for this value */
  401. }
  402. /* constant not found; create a new entry */
  403. nk := f k getSize()
  404. h set(key, LuaNumber new(nk))
  405. f k add(v)
  406. return nk
  407. }
  408. luaK_stringK: func(s: String) -> Int {
  409. o := LuaString new(s)
  410. return _addk(o, o)
  411. }
  412. luaK_numberK: func(r: Double) -> Int {
  413. o := LuaNumber new(r)
  414. if (r == 0 || !(r == r)) { /* handle -0 and NaN */
  415. /* use raw representation as key to avoid numeric problems */
  416. k := LuaString new(r toString())
  417. return _addk(k, o)
  418. }
  419. else
  420. return _addk(o, o) /* regular case */
  421. }
  422. _boolK: func(b: Bool) -> Int {
  423. o := LuaBoolean new(b)
  424. return _addk(o, o)
  425. }
  426. _nilK: func -> Int {
  427. o := LuaNil new()
  428. return _addk(o, o)
  429. }
  430. luaK_setreturns: func(e: ExpDesc@, nresults: Int) {
  431. pi := f code data as Instruction* + e info
  432. if (e k == ExpKind VCALL) { /* expression is an open function call? */
  433. pi@ = pi@ setarg_C(nresults + 1)
  434. }
  435. else if (e k == ExpKind VVARARG) {
  436. pi@ = pi@ setarg_B(nresults + 1)
  437. pi@ = pi@ setarg_A(freereg)
  438. luaK_reserveregs(1)
  439. }
  440. }
  441. luaK_setoneret: func(e: ExpDesc@) {
  442. pi := f code data as Instruction* + e info
  443. if (e k == ExpKind VCALL) { /* expression is an open function call? */
  444. e k = ExpKind VNONRELOC
  445. e info = pi@ getarg_A()
  446. }
  447. else if (e k == ExpKind VVARARG) {
  448. pi@ = pi@ setarg_B(2)
  449. e k = ExpKind VRELOCABLE /* can relocate its simple result */
  450. }
  451. }
  452. luaK_dischargevars: func(e: ExpDesc@) {
  453. k := e k
  454. match {
  455. case k == ExpKind VLOCAL =>
  456. e k = ExpKind VNONRELOC
  457. case k == ExpKind VUPVAL =>
  458. e info = luaK_codeABC(OpCode OP_GETUPVAL, 0, e info, 0)
  459. e k = ExpKind VRELOCABLE
  460. case k == ExpKind VINDEXED =>
  461. op := OpCode OP_GETTABUP /* assume 't' is in an upvalue */
  462. _freereg(e ind_idx)
  463. if (e ind_vt == ExpKind VLOCAL) { /* 't' is in a register? */
  464. _freereg(e ind_t)
  465. op = OpCode OP_GETTABLE
  466. }
  467. e info = luaK_codeABC(op, 0, e ind_t, e ind_idx)
  468. e k = ExpKind VRELOCABLE
  469. case k == ExpKind VVARARG ||
  470. k == ExpKind VCALL =>
  471. luaK_setoneret(e&)
  472. }
  473. }
  474. _code_label: func(A, b, jump: Int) -> Int {
  475. luaK_getlabel() /* those instructions may be jump targets */
  476. return luaK_codeABC(OpCode OP_LOADBOOL, A, b, jump)
  477. }
  478. _discharge2reg: func(e: ExpDesc@, reg: Int) {
  479. luaK_dischargevars(e&)
  480. match (e k) {
  481. case ExpKind VNIL =>
  482. luaK_nil(reg, 1)
  483. case ExpKind VFALSE =>
  484. luaK_codeABC(OpCode OP_LOADBOOL, reg, 0, 0)
  485. case ExpKind VTRUE =>
  486. luaK_codeABC(OpCode OP_LOADBOOL, reg, 1, 0)
  487. case ExpKind VK =>
  488. luaK_codeABxX(OpCode OP_LOADK, reg, e info)
  489. case ExpKind VKNUM =>
  490. luaK_codeABxX(OpCode OP_LOADK, reg, luaK_numberK(e nval))
  491. case ExpKind VRELOCABLE =>
  492. pc := f code data as Instruction* + e info
  493. pc@ = pc@ setarg_A(reg)
  494. case ExpKind VNONRELOC =>
  495. if (reg != e info)
  496. luaK_codeABC(OpCode OP_MOVE, reg, e info, 0)
  497. case =>
  498. version(debug) {
  499. assert(e k == ExpKind VVOID || e k == ExpKind VJMP)
  500. }
  501. return /* nothing to do... */
  502. }
  503. e info = reg
  504. e k = ExpKind VNONRELOC
  505. }
  506. _discharge2anyreg: func(e: ExpDesc@) {
  507. if (e k != ExpKind VNONRELOC) {
  508. luaK_reserveregs(1)
  509. _discharge2reg(e&, freereg-1)
  510. }
  511. }
  512. _exp2reg: func(e: ExpDesc@, reg: Int) {
  513. _discharge2reg(e&, reg)
  514. if (e k == ExpKind VJMP)
  515. luaK_concat(e t&, e info) /* put this jump in `t' list */
  516. if (e hasjumps()) {
  517. p_f := NO_JUMP /* position of an eventual LOAD false */
  518. p_t := NO_JUMP /* position of an eventual LOAD true */
  519. if (_need_value(e t) || _need_value(e f)) {
  520. fj := (e k == ExpKind VJMP) ? NO_JUMP : luaK_jump()
  521. p_f = _code_label(reg, 0, 1)
  522. p_t = _code_label(reg, 1, 0)
  523. luaK_patchtohere(fj)
  524. }
  525. _final := luaK_getlabel() /* position after whole expression */
  526. _patchlistaux(e f, _final, reg, p_f)
  527. _patchlistaux(e t, _final, reg, p_t)
  528. }
  529. e f = NO_JUMP
  530. e t = NO_JUMP
  531. e info = reg
  532. e k = ExpKind VNONRELOC
  533. }
  534. luaK_exp2nextreg: func(e: ExpDesc@) {
  535. luaK_dischargevars(e&)
  536. _freeexp(e&)
  537. luaK_reserveregs(1)
  538. _exp2reg(e&, freereg - 1)
  539. }
  540. luaK_exp2anyreg: func(e: ExpDesc@) -> Int {
  541. luaK_dischargevars(e&)
  542. if (e k == ExpKind VNONRELOC) {
  543. if (! e hasjumps())
  544. return e info /* exp is already in a register */
  545. if (e info >= nactvar) { /* reg. is not a local? */
  546. _exp2reg(e&, e info) /* put value on it */
  547. return e info
  548. }
  549. }
  550. luaK_exp2nextreg(e&) /* default */
  551. return e info
  552. }
  553. luaK_exp2anyregup: func(e: ExpDesc@) {
  554. if (e k != ExpKind VUPVAL || e hasjumps())
  555. luaK_exp2anyreg(e&)
  556. }
  557. luaK_exp2val: func(e: ExpDesc@) {
  558. if (e hasjumps())
  559. luaK_exp2anyreg(e&)
  560. else
  561. luaK_dischargevars(e&)
  562. }
  563. luaK_exp2RK: func(e: ExpDesc@) -> Int {
  564. luaK_exp2val(e&)
  565. k := e k
  566. nk := f k getSize()
  567. match {
  568. case k == ExpKind VTRUE ||
  569. k == ExpKind VFALSE ||
  570. k == ExpKind VNIL =>
  571. if (nk <= MAXINDEXRK) { /* constant fits in RK operand? */
  572. e info = (e k == ExpKind VNIL) ? _nilK() : _boolK(e k == ExpKind VTRUE)
  573. e k = ExpKind VK
  574. return e info | BITRK
  575. }
  576. case k == ExpKind VKNUM =>
  577. e info = luaK_numberK(e nval)
  578. e k = ExpKind VK
  579. if (e info <= MAXINDEXRK) /* constant fits in argC? */
  580. return e info | BITRK
  581. case k == ExpKind VK =>
  582. if (e info <= MAXINDEXRK) /* constant fits in argC? */
  583. return e info | BITRK
  584. }
  585. /* not a constant in the right range: put it in a register */
  586. return luaK_exp2anyreg(e&)
  587. }
  588. luaK_storevar: func(var, ex: ExpDesc@) {
  589. match (var k) {
  590. case ExpKind VLOCAL =>
  591. _freeexp(ex&)
  592. _exp2reg(ex&, var info)
  593. case ExpKind VUPVAL =>
  594. e := luaK_exp2anyreg(ex&)
  595. luaK_codeABC(OpCode OP_SETUPVAL, e, var info, 0)
  596. case ExpKind VINDEXED =>
  597. op := (var ind_vt == ExpKind VLOCAL) ? OpCode OP_SETTABLE : OpCode OP_SETTABUP
  598. e := luaK_exp2RK(ex&)
  599. luaK_codeABC(op, var ind_t, var ind_idx, e)
  600. case =>
  601. version(debug) {
  602. assert(false) /* invalid var kind to store */
  603. }
  604. }
  605. _freeexp(ex&)
  606. }
  607. luaK_self: func(e, key: ExpDesc@) {
  608. luaK_exp2anyreg(e&)
  609. _freeexp(e&)
  610. _func := freereg
  611. luaK_codeABC(OpCode OP_SELF, _func, e info, luaK_exp2RK(key&))
  612. _freeexp(key&)
  613. luaK_reserveregs(2)
  614. e info = _func
  615. e k = ExpKind VNONRELOC
  616. }
  617. _invertjump: func(e: ExpDesc@) {
  618. pc := _getjumpcontrol(e info)
  619. version(debug) {
  620. op := pc@ getOpcode()
  621. assert(op testTMode())
  622. assert(op != OpCode OP_TESTSET)
  623. assert(op != OpCode OP_TEST)
  624. }
  625. pc@ = pc@ setarg_A(pc@ getarg_A() == 0 ? 1 : 0)
  626. }
  627. _jumponcond: func(e: ExpDesc@, cond: Int) -> Int {
  628. if (e k == ExpKind VRELOCABLE) {
  629. ie := f code get(e info)
  630. if (ie getOpcode() == OpCode OP_NOT) {
  631. f code removeAt(f code lastIndex()) /* remove previous OP_NOT */
  632. return _condjump(OpCode OP_TEST, ie getarg_B(), 0, cond == 0 ? 1 : 0)
  633. }
  634. /* else go through */
  635. }
  636. _discharge2anyreg(e&)
  637. _freeexp(e&)
  638. return _condjump(OpCode OP_TESTSET, NO_REG, e info, cond)
  639. }
  640. luaK_goiftrue: func(e: ExpDesc@) {
  641. pc: Int /* pc of last jump */
  642. luaK_dischargevars(e&)
  643. k := e k
  644. match {
  645. case k == ExpKind VK ||
  646. k == ExpKind VKNUM ||
  647. k == ExpKind VTRUE =>
  648. pc = NO_JUMP /* always true; do nothing */
  649. case k == ExpKind VJMP =>
  650. _invertjump(e&)
  651. pc = e info
  652. case k == ExpKind VFALSE =>
  653. if (! e hasjumps())
  654. pc = luaK_jump() /* always jump */
  655. else
  656. pc = _jumponcond(e&, 0)
  657. case =>
  658. pc = _jumponcond(e&, 0)
  659. }
  660. luaK_concat(e f&, pc) /* insert last jump in `f' list */
  661. luaK_patchtohere(e t)
  662. e t = NO_JUMP
  663. }
  664. luaK_goiffalse: func(e: ExpDesc@) {
  665. pc: Int /* pc of last jump */
  666. luaK_dischargevars(e&)
  667. k := e k
  668. match {
  669. case k == ExpKind VNIL ||
  670. k == ExpKind VFALSE =>
  671. pc = NO_JUMP /* always false; do nothing */
  672. case k == ExpKind VJMP =>
  673. pc = e info
  674. case k == ExpKind VTRUE =>
  675. if (! e hasjumps())
  676. pc = luaK_jump() /* always jump */
  677. else
  678. pc = _jumponcond(e&, 1)
  679. case =>
  680. pc = _jumponcond(e&, 1)
  681. }
  682. luaK_concat(e t&, pc) /* insert last jump in `t' list */
  683. luaK_patchtohere(e f)
  684. e f = NO_JUMP
  685. }
  686. _codenot: func(e: ExpDesc@) {
  687. luaK_dischargevars(e&)
  688. k := e k
  689. match {
  690. case k == ExpKind VNIL ||
  691. k == ExpKind VFALSE =>
  692. e k = ExpKind VTRUE
  693. case k == ExpKind VK ||
  694. k == ExpKind VKNUM ||
  695. k == ExpKind VTRUE =>
  696. e k = ExpKind VFALSE
  697. case k == ExpKind VJMP =>
  698. _invertjump(e&)
  699. case k == ExpKind VRELOCABLE ||
  700. k == ExpKind VNONRELOC =>
  701. _discharge2anyreg(e&)
  702. _freeexp(e&)
  703. e info = luaK_codeABC(OpCode OP_NOT, 0, e info, 0)
  704. e k = ExpKind VRELOCABLE
  705. case =>
  706. version(debug) {
  707. assert(false) /* cannot happen */
  708. }
  709. }
  710. /* interchange true and false lists */
  711. temp := e f; e f = e t; e t = temp
  712. _removevalues(e f)
  713. _removevalues(e t)
  714. }
  715. luaK_indexed: func(t, k: ExpDesc@) {
  716. version(debug) {
  717. assert(! t hasjumps())
  718. }
  719. t ind_t = t info
  720. t ind_idx = luaK_exp2RK(k&)
  721. version(debug) {
  722. if (t k != ExpKind VUPVAL)
  723. assert(t k vkisinreg())
  724. }
  725. t ind_vt = (t k == ExpKind VUPVAL) ? ExpKind VUPVAL : ExpKind VLOCAL
  726. t k = ExpKind VINDEXED
  727. }
  728. _constfolding: func(op: OpCode, e1, e2: ExpDesc@) -> Bool {
  729. if (! e1 isnumeral() || ! e2 isnumeral())
  730. return false
  731. if ((op == OpCode OP_DIV || op == OpCode OP_MOD) && e2 nval == 0)
  732. return false /* do not attempt to divide by 0 */
  733. match (op) {
  734. case OpCode OP_ADD =>
  735. e1 nval = e1 nval + e2 nval
  736. case OpCode OP_SUB =>
  737. e1 nval = e1 nval - e2 nval
  738. case OpCode OP_MUL =>
  739. e1 nval = e1 nval * e2 nval
  740. case OpCode OP_DIV =>
  741. e1 nval = e1 nval / e2 nval
  742. case OpCode OP_MOD =>
  743. e1 nval = e1 nval - (e1 nval / e2 nval) floor() * e2 nval
  744. case OpCode OP_POW =>
  745. e1 nval = e1 nval pow(e2 nval)
  746. case =>
  747. assert(false)
  748. }
  749. return true
  750. }
  751. _codearith: func(op: OpCode, e1, e2: ExpDesc@, line: Int) {
  752. if (_constfolding(op, e1&, e2&))
  753. return
  754. else {
  755. o2 := (op != OpCode OP_UNM && op != OpCode OP_LEN) ? luaK_exp2RK(e2&) : 0
  756. o1 := luaK_exp2RK(e1&)
  757. if (o1 > o2) {
  758. _freeexp(e1&)
  759. _freeexp(e2&)
  760. }
  761. else {
  762. _freeexp(e2&)
  763. _freeexp(e1&)
  764. }
  765. e1 info = luaK_codeABC(op, 0, o1, o2)
  766. e1 k = ExpKind VRELOCABLE
  767. luaK_fixline(line)
  768. }
  769. }
  770. _codecomp: func(op: OpCode, cond: Int, e1, e2: ExpDesc@) {
  771. o1 := luaK_exp2RK(e1&)
  772. o2 := luaK_exp2RK(e2&)
  773. _freeexp(e2&)
  774. _freeexp(e1&)
  775. if (! cond && op != OpCode OP_EQ) {
  776. /* exchange args to replace by `<' or `<=' */
  777. temp := o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
  778. cond = 1
  779. }
  780. e1 info = _condjump(op, cond, o1, o2)
  781. e1 k = ExpKind VJMP
  782. }
  783. luaK_prefix: func(op: UnOpr, e: ExpDesc@, line: Int) {
  784. e2: ExpDesc
  785. e2 t = NO_JUMP
  786. e2 f = NO_JUMP
  787. e2 k = ExpKind VKNUM
  788. e2 nval = 0
  789. match (op) {
  790. case UnOpr OPR_MINUS =>
  791. if (e isnumeral()) /* minus constant? */
  792. e nval = - e nval /* fold it */
  793. else {
  794. luaK_exp2anyreg(e&)
  795. _codearith(OpCode OP_UNM, e&, e2&, line)
  796. }
  797. case UnOpr OPR_NOT =>
  798. _codenot(e&)
  799. case UnOpr OPR_LEN =>
  800. luaK_exp2anyreg(e&) /* cannot operate on constants */
  801. _codearith(OpCode OP_LEN, e&, e2&, line)
  802. case =>
  803. version(debug) {
  804. assert(false)
  805. }
  806. }
  807. }
  808. luaK_infix: func(op: BinOpr, v: ExpDesc@) {
  809. match {
  810. case op == BinOpr OPR_AND =>
  811. luaK_goiftrue(v&)
  812. case op == BinOpr OPR_OR =>
  813. luaK_goiffalse(v&)
  814. case op == BinOpr OPR_CONCAT =>
  815. luaK_exp2nextreg(v&) /* operand must be on the `stack' */
  816. case op == BinOpr OPR_ADD ||
  817. op == BinOpr OPR_SUB ||
  818. op == BinOpr OPR_MUL ||
  819. op == BinOpr OPR_DIV ||
  820. op == BinOpr OPR_MOD ||
  821. op == BinOpr OPR_POW =>
  822. if (! v isnumeral())
  823. luaK_exp2RK(v&)
  824. case =>
  825. luaK_exp2RK(v&)
  826. }
  827. }
  828. luaK_posfix: func(op: BinOpr, e1, e2: ExpDesc@, line: Int) {
  829. match {
  830. case op == BinOpr OPR_AND =>
  831. version(debug) {
  832. assert(e1 t == NO_JUMP) /* list must be closed */
  833. }
  834. luaK_dischargevars(e2&)
  835. luaK_concat(e2 f&, e1 f)
  836. e1 = e2
  837. case op == BinOpr OPR_OR =>
  838. version(debug) {
  839. assert(e1 f == NO_JUMP) /* list must be closed */
  840. }
  841. luaK_dischargevars(e2&)
  842. luaK_concat(e2 t&, e1 t)
  843. e1 = e2
  844. case op == BinOpr OPR_CONCAT =>
  845. luaK_exp2val(e2&)
  846. pi := f code data as Instruction* + e2 info
  847. if (e2 k == ExpKind VRELOCABLE && pi@ getOpcode() == OpCode OP_CONCAT) {
  848. version(debug) {
  849. assert(e1 info == pi@ getarg_B() - 1)
  850. }
  851. _freeexp(e1&)
  852. pi@ = pi@ setarg_B(e1 info)
  853. e1 k = ExpKind VRELOCABLE
  854. e1 info = e2 info
  855. }
  856. else {
  857. luaK_exp2nextreg(e2&) /* operand must be on the 'stack' */
  858. _codearith(OpCode OP_CONCAT, e1&, e2&, line)
  859. }
  860. case op == BinOpr OPR_ADD =>
  861. _codearith(OpCode OP_ADD, e1&, e2&, line)
  862. case op == BinOpr OPR_SUB =>
  863. _codearith(OpCode OP_SUB, e1&, e2&, line)
  864. case op == BinOpr OPR_MUL =>
  865. _codearith(OpCode OP_MUL, e1&, e2&, line)
  866. case op == BinOpr OPR_DIV =>
  867. _codearith(OpCode OP_DIV, e1&, e2&, line)
  868. case op == BinOpr OPR_MOD =>
  869. _codearith(OpCode OP_MOD, e1&, e2&, line)
  870. case op == BinOpr OPR_POW =>
  871. _codearith(OpCode OP_POW, e1&, e2&, line)
  872. case op == BinOpr OPR_EQ =>
  873. _codecomp(OpCode OP_EQ, 1, e1&, e2&)
  874. case op == BinOpr OPR_LT =>
  875. _codecomp(OpCode OP_LT, 1, e1&, e2&)
  876. case op == BinOpr OPR_LE =>
  877. _codecomp(OpCode OP_LE, 1, e1&, e2&)
  878. case op == BinOpr OPR_NE =>
  879. _codecomp(OpCode OP_EQ, 0, e1&, e2&)
  880. case op == BinOpr OPR_GT =>
  881. _codecomp(OpCode OP_LT, 0, e1&, e2&)
  882. case op == BinOpr OPR_GE =>
  883. _codecomp(OpCode OP_LE, 0, e1&, e2&)
  884. case =>
  885. version(debug) {
  886. assert(false)
  887. }
  888. }
  889. }
  890. luaK_fixline: func(line: Int) {
  891. f lineinfo set(f code getSize() - 1, line)
  892. }
  893. luaK_setlist: func(base, nelems, tostore: Int) {
  894. c := (nelems - 1)/LFIELDS_PER_FLUSH + 1
  895. b := (tostore == LUA_MULTRET) ? 0 : tostore
  896. version(debug) {
  897. assert(tostore != 0)
  898. }
  899. if (c <= MAXARG_C)
  900. luaK_codeABC(OpCode OP_SETLIST, base, b, c)
  901. else if (c <= MAXARG_Ax) {
  902. luaK_codeABC(OpCode OP_SETLIST, base, b, 0)
  903. version(debug) {
  904. assert(c <= MAXARG_Ax)
  905. }
  906. luaK_code(Instruction createAx(OpCode OP_EXTRAARG, c))
  907. }
  908. else
  909. ls syntaxError("constructor too long")
  910. freereg = base + 1 /* free registers with list values */
  911. }
  912. checklimit: func(v, l: Int, what: String) {
  913. if (v > l) {
  914. line := f linedefined
  915. where := (line == 0) ? "main function" : "function at line %d" format(line)
  916. msg := "too many %s (limit is %d) in %s" format(what, l, where)
  917. ls syntaxError(msg)
  918. }
  919. }
  920. }
  921. /*
  922. ** nodes for block list (list of active blocks)
  923. */
  924. BlockCnt: cover {
  925. previous: BlockCnt* /* chain */
  926. breaklist: Int /* list of jumps out of this loop */
  927. nactvar: UInt8 /* # active locals outside the breakable structure */
  928. upval: Bool /* true if some variable in the block is an upvalue */
  929. isbreakable: Bool /* true if `block' is a loop */
  930. }
  931. /*
  932. ** structure to chain all variables in the left-hand side of an
  933. ** assignment
  934. */
  935. LHS_assign: cover {
  936. prev: LHS_assign*
  937. v: ExpDesc /* variable (global, local, upvalue, or indexed) */
  938. }
  939. ConsControl: cover {
  940. v: ExpDesc /* last list item read */
  941. t: ExpDesc* /* table descriptor */
  942. nh: Int /* total number of `record' elements */
  943. na: Int /* total number of array elements */
  944. tostore: Int /* number of array elements pending to be stored */
  945. }
  946. Parser: final class extends Lexer {
  947. fs: FuncState /* `FuncState' is private to the parser */
  948. actvar: ArrayList<UInt16> /* list of all active local variables */
  949. init: func {}
  950. parse: func(=actvar) -> LuaProto {
  951. _mainfunc()
  952. next() /* read first token */
  953. chunk() /* read main chunk */
  954. _check(TK_EOS)
  955. fs finalize()
  956. version(debug) {
  957. assert(! fs prev)
  958. assert(fs f upvalues getSize() == 1)
  959. }
  960. return fs f
  961. }
  962. /*============================================================*/
  963. /* GRAMMAR RULES */
  964. /*============================================================*/
  965. fieldsel: func(v: ExpDesc@) {
  966. /* fieldsel -> ['.' | ':'] NAME */
  967. key: ExpDesc
  968. fs luaK_exp2anyregup(v&)
  969. next() /* skip the dot or colon */
  970. _checkname(key&)
  971. fs luaK_indexed(v&, key&)
  972. }
  973. yindex: func(v: ExpDesc@) {
  974. /* index -> '[' expr ']' */
  975. next() /* skip the '[' */
  976. expr(v&)
  977. fs luaK_exp2val(v&)
  978. _checknext(']' as Int)
  979. }
  980. /*
  981. ** {======================================================================
  982. ** Rules for Constructors
  983. ** =======================================================================
  984. */
  985. recfield: func(cc: ConsControl@) {
  986. /* recfield -> (NAME | `['exp1`]') = exp1 */
  987. reg := fs freereg
  988. key: ExpDesc
  989. if (t token == TK_NAME) {
  990. fs checklimit(cc nh, MAX_INT, "items in a constructor")
  991. _checkname(key&)
  992. }
  993. else /* ls->t.token == '[' */
  994. yindex(key&)
  995. cc nh += 1
  996. _checknext('=' as Int)
  997. rkkey := fs luaK_exp2RK(key&)
  998. val: ExpDesc
  999. expr(val&)
  1000. fs luaK_codeABC(OpCode OP_SETTABLE, cc t@ info, rkkey, fs luaK_exp2RK(val&))
  1001. fs freereg = reg /* free registers */
  1002. }
  1003. closelistfield: func(cc: ConsControl@) {
  1004. if (cc v k == ExpKind VVOID)
  1005. return; /* there is no list item */
  1006. fs luaK_exp2nextreg(cc v&)
  1007. cc v k = ExpKind VVOID
  1008. if (cc tostore == LFIELDS_PER_FLUSH) {
  1009. fs luaK_setlist(cc t@ info, cc na, cc tostore) /* flush */
  1010. cc tostore = 0 /* no more items pending */
  1011. }
  1012. }
  1013. lastlistfield: func(cc: ConsControl@) {
  1014. if (cc tostore == 0)
  1015. return
  1016. if (cc v k hasmultret()) {
  1017. fs luaK_setreturns(cc v&, LUA_MULTRET)
  1018. fs luaK_setlist(cc t@ info, cc na, LUA_MULTRET)
  1019. cc na -= 1 /* do not count last expression (unknown number of elements) */
  1020. }
  1021. else {
  1022. if (cc v k != ExpKind VVOID)
  1023. fs luaK_exp2nextreg(cc v&)
  1024. fs luaK_setlist(cc t@ info, cc na, cc tostore)
  1025. }
  1026. }
  1027. listfield: func(cc: ConsControl@) {
  1028. /* listfield -> exp */
  1029. expr(cc v&)
  1030. fs checklimit(cc na, MAX_INT, "items in a constructor")
  1031. cc na += 1
  1032. cc tostore += 1
  1033. }
  1034. field: func(cc: ConsControl@) {
  1035. /* field -> listfield | recfield */
  1036. match (t token) {
  1037. case TK_NAME => /* may be 'listfield' or 'recfield' */
  1038. if (lookahead() != '=') /* expression? */
  1039. listfield(cc&)
  1040. else
  1041. recfield(cc&)
  1042. case '[' =>
  1043. recfield(cc&)
  1044. case =>
  1045. listfield(cc&)
  1046. }
  1047. }
  1048. constructor: func(_t: ExpDesc@) {
  1049. /* constructor -> '{' [ field { sep field } [sep] ] '}'
  1050. sep -> ',' | ';' */
  1051. line := linenumber
  1052. pc := fs luaK_codeABC(OpCode OP_NEWTABLE, 0, 0, 0)
  1053. cc: ConsControl
  1054. cc na = 0
  1055. cc nh = 0
  1056. cc tostore = 0
  1057. cc t = _t&
  1058. init_exp(_t&, ExpKind VRELOCABLE, pc)
  1059. init_exp(cc v&, ExpKind VVOID, 0) /* no value (yet) */
  1060. fs luaK_exp2nextreg(_t&) /* fix it at stack top (for gc) */
  1061. _checknext('{' as Int)
  1062. while (true) {
  1063. version(debug) {
  1064. assert(cc v k == ExpKind VVOID || cc tostore > 0)
  1065. }
  1066. if (t token == '}')
  1067. break
  1068. closelistfield(cc&)
  1069. field(cc&)
  1070. if (! _testnext(',' as Int) && ! _testnext(';' as Int))
  1071. break
  1072. }
  1073. _check_match('}' as Int, '{' as Int, line)
  1074. lastlistfield(cc&)
  1075. pi := fs f code data as Instruction* + pc
  1076. pi@ = pi@ setarg_B(int2fb(cc na)) /* set initial array size */
  1077. pi@ = pi@ setarg_C(int2fb(cc nh)) /* set initial table size */
  1078. }
  1079. /* }====================================================================== */
  1080. parlist: func {
  1081. /* parlist -> [ param { `,' param } ] */
  1082. f := fs f
  1083. nparams := 0
  1084. f is_vararg = false
  1085. if (t token != ')') { /* is `parlist' not empty? */
  1086. while (! f is_vararg) {
  1087. match (t token) {
  1088. case TK_NAME => /* param -> NAME */
  1089. _new_localvar(_str_checkname())
  1090. nparams += 1
  1091. case TK_DOTS => /* param -> `...' */
  1092. next()
  1093. f is_vararg = true
  1094. case =>
  1095. syntaxError("<name> or '...' expected")
  1096. }
  1097. if (! _testnext(',' as Int))
  1098. break
  1099. }
  1100. }
  1101. _adjustlocalvars(nparams)
  1102. f numparams = fs nactvar
  1103. fs luaK_reserveregs(fs nactvar) /* reserve register for parameters */
  1104. }
  1105. body: func(e: ExpDesc@, needself: Bool, line: Int) {
  1106. /* body -> `(' parlist `)' chunk END */
  1107. fs = FuncState new(this, fs)
  1108. f := fs f
  1109. f linedefined = line
  1110. _checknext('(' as Int)
  1111. if (needself) {
  1112. _new_localvarliteral("self")
  1113. _adjustlocalvars(1)
  1114. }
  1115. parlist()
  1116. _checknext(')' as Int)
  1117. chunk()
  1118. f lastlinedefined = linenumber
  1119. _check_match(TK_END, TK_FUNCTION, line)
  1120. _codeclosure(f, e&)
  1121. fs = fs finalize()
  1122. }
  1123. explist1: func(v: ExpDesc@) -> Int {
  1124. /* explist1 -> expr { `,' expr } */
  1125. n := 1 /* at least one expression */
  1126. expr(v&)
  1127. while (_testnext(',' as Int)) {
  1128. fs luaK_exp2nextreg(v&)
  1129. expr(v&)
  1130. n += 1
  1131. }
  1132. return n
  1133. }
  1134. funcargs: func(f: ExpDesc@, line: Int) {
  1135. args: ExpDesc
  1136. match (t token) {
  1137. case '(' => /* funcargs -> `(' [ explist1 ] `)' */
  1138. next()
  1139. if (t token == ')') /* arg list is empty? */
  1140. args k = ExpKind VVOID
  1141. else {
  1142. explist1(args&)
  1143. fs luaK_setreturns(args&, LUA_MULTRET)
  1144. }
  1145. _check_match(')' as Int, '(' as Int, line)
  1146. case '{' => /* funcargs -> constructor */
  1147. constructor(args&)
  1148. case TK_STRING => /* funcargs -> STRING */
  1149. _codestring(args&, t str);
  1150. next() /* must use `seminfo' before `next' */
  1151. case =>
  1152. syntaxError("function arguments expected")
  1153. }
  1154. version(debug) {
  1155. assert(f k == ExpKind VNONRELOC)
  1156. }
  1157. nparams: Int
  1158. base := f info /* base register for call */
  1159. if (args k hasmultret())
  1160. nparams = LUA_MULTRET /* open call */
  1161. else {
  1162. if (args k != ExpKind VVOID)
  1163. fs luaK_exp2nextreg(args&) /* close last argument */
  1164. nparams = fs freereg - (base+1)
  1165. }
  1166. init_exp(f&, ExpKind VCALL, fs luaK_codeABC(OpCode OP_CALL, base, nparams+1, 2))
  1167. fs luaK_fixline(line)
  1168. fs freereg = base+1 /* call remove function and arguments and leaves
  1169. (unless changed) one result */
  1170. }
  1171. /*
  1172. ** {======================================================================
  1173. ** Expression parsing
  1174. ** =======================================================================
  1175. */
  1176. prefixexp: func(v: ExpDesc@) {
  1177. /* prefixexp -> NAME | '(' expr ')' */
  1178. match (t token) {
  1179. case '(' =>
  1180. line := linenumber
  1181. next()
  1182. expr(v&)
  1183. _check_match(')' as Int, '(' as Int, line)
  1184. fs luaK_dischargevars(v&)
  1185. case TK_NAME =>
  1186. _singlevar(v&)
  1187. case =>
  1188. syntaxError("unexpected symbol")
  1189. }
  1190. }
  1191. primaryexp: func(v: ExpDesc@) {
  1192. /* primaryexp ->
  1193. prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
  1194. line := linenumber
  1195. prefixexp(v&)
  1196. while (true) {
  1197. match {
  1198. case t token == '.' => /* fieldsel */
  1199. fieldsel(v&)
  1200. case t token == '[' => /* `[' exp1 `]' */
  1201. key: ExpDesc
  1202. fs luaK_exp2anyregup(v&)
  1203. yindex(key&)
  1204. fs luaK_indexed(v&, key&)
  1205. case t token == ':' => /* `:' NAME funcargs */
  1206. key: ExpDesc
  1207. next()
  1208. _checkname(key&)
  1209. fs luaK_self(v&, key&)
  1210. funcargs(v&, line)
  1211. case t token == '(' ||
  1212. t token == TK_STRING ||
  1213. t token == '{' => /* funcargs */
  1214. fs luaK_exp2nextreg(v&)
  1215. funcargs(v&, line)
  1216. case =>
  1217. return
  1218. }
  1219. }
  1220. }
  1221. simpleexp: func(v: ExpDesc@) {
  1222. /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
  1223. constructor | FUNCTION body | primaryexp */
  1224. match (t token) {
  1225. case TK_NUMBER =>
  1226. init_exp(v&, ExpKind VKNUM, 0)
  1227. v nval = t num
  1228. case TK_STRING =>
  1229. _codestring(v&, t str);
  1230. case TK_NIL =>
  1231. init_exp(v&, ExpKind VNIL, 0)
  1232. case TK_TRUE =>
  1233. init_exp(v&, ExpKind VTRUE, 0)
  1234. case TK_FALSE =>
  1235. init_exp(v&, ExpKind VFALSE, 0)
  1236. case TK_DOTS => /* vararg */
  1237. _check_condition(fs f is_vararg,
  1238. "cannot use '...' outside a vararg function")
  1239. init_exp(v&, ExpKind VVARARG, fs luaK_codeABC(OpCode OP_VARARG, 0, 1, 0))
  1240. case '{' => /* constructor */
  1241. constructor(v&)
  1242. return
  1243. case TK_FUNCTION =>
  1244. next()
  1245. body(v&, false, linenumber)
  1246. return
  1247. case =>
  1248. primaryexp(v&)
  1249. return
  1250. }
  1251. next()
  1252. }
  1253. getunopr: func(op: Int) -> UnOpr {
  1254. match (op) {
  1255. case TK_NOT =>
  1256. return UnOpr OPR_NOT
  1257. case '-' =>
  1258. return UnOpr OPR_MINUS
  1259. case '#' =>
  1260. return UnOpr OPR_LEN
  1261. case =>
  1262. return UnOpr OPR_NOUNOPR
  1263. }
  1264. return UnOpr OPR_NOUNOPR // avoir error
  1265. }
  1266. getbinopr: func(op: Int) -> BinOpr {
  1267. match (op) {
  1268. case '+' =>
  1269. return BinOpr OPR_ADD
  1270. case '-' =>
  1271. return BinOpr OPR_SUB
  1272. case '*' =>
  1273. return BinOpr OPR_MUL
  1274. case '/' =>
  1275. return BinOpr OPR_DIV
  1276. case '%' =>
  1277. return BinOpr OPR_MOD
  1278. case '^' =>
  1279. return BinOpr OPR_POW
  1280. case TK_CONCAT =>
  1281. return BinOpr OPR_CONCAT
  1282. case TK_NE =>
  1283. return BinOpr OPR_NE
  1284. case TK_EQ =>
  1285. return BinOpr OPR_EQ
  1286. case '<' =>
  1287. return BinOpr OPR_LT
  1288. case TK_LE =>
  1289. return BinOpr OPR_LE
  1290. case '>' =>
  1291. return BinOpr OPR_GT
  1292. case TK_GE =>
  1293. return BinOpr OPR_GE
  1294. case TK_AND =>
  1295. return BinOpr OPR_AND
  1296. case TK_OR =>
  1297. return BinOpr OPR_OR
  1298. case =>
  1299. return BinOpr OPR_NOBINOPR
  1300. }
  1301. return BinOpr OPR_NOBINOPR // avoid error
  1302. }
  1303. /*
  1304. ** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
  1305. ** where `binop' is any binary operator with a priority higher than `limit'
  1306. */
  1307. subexpr: func(v: ExpDesc@, limit: Int) -> BinOpr {
  1308. _enterlevel()
  1309. uop := getunopr(t token)
  1310. if (uop != UnOpr OPR_NOUNOPR) {
  1311. line := linenumber
  1312. next()
  1313. subexpr(v&, UNARY_PRIORITY)
  1314. fs luaK_prefix(uop, v&, line)
  1315. }
  1316. else
  1317. simpleexp(v&)
  1318. /* expand while operators have priorities higher than `limit' */
  1319. op := getbinopr(t token)
  1320. while (op != BinOpr OPR_NOBINOPR && PRIORITY_LEFT[op] > limit) {
  1321. v2: ExpDesc
  1322. line := linenumber
  1323. next()
  1324. fs luaK_infix(op, v&)
  1325. /* read sub-expression with higher priority */
  1326. nextop := subexpr(v2&, PRIORITY_RIGHT[op])
  1327. fs luaK_posfix(op, v&, v2&, line)
  1328. op = nextop
  1329. }
  1330. _leavelevel()
  1331. return op; /* return first untreated operator */
  1332. }
  1333. expr: func(v: ExpDesc@) {
  1334. subexpr(v&, 0)
  1335. }
  1336. /* }==================================================================== */
  1337. /*
  1338. ** {======================================================================
  1339. ** Rules for Statements
  1340. ** =======================================================================
  1341. */
  1342. block_follow: func(token: Int) -> Bool {
  1343. return (token == TK_ELSE ||
  1344. token == TK_ELSEIF ||
  1345. token == TK_END ||
  1346. token == TK_UNTIL ||
  1347. token == TK_EOS)
  1348. }
  1349. block: func {
  1350. /* block -> chunk */
  1351. bl: BlockCnt
  1352. fs enterblock(bl&, false)
  1353. chunk()
  1354. version(debug) {
  1355. assert(bl breaklist == NO_JUMP)
  1356. }
  1357. fs leaveblock()
  1358. }
  1359. /*
  1360. ** check whether, in an assignment to a local variable, the local variable
  1361. ** is needed in a previous assignment (to a table). If so, save original
  1362. ** local value in a safe place and use this safe copy in the previous
  1363. ** assignment.
  1364. */
  1365. _check_conflict: func(lh: LHS_assign*, v: ExpDesc@) {
  1366. extra := fs freereg /* eventual position to save local variable */
  1367. conflict := false
  1368. while (lh) {
  1369. /* conflict in table 't'? */
  1370. if (lh@ v ind_vt == v k && lh@ v ind_t == v info) {
  1371. conflict = true
  1372. lh@ v ind_vt = ExpKind VLOCAL
  1373. lh@ v ind_t = extra /* previous assignment will use safe copy */
  1374. }
  1375. /* conflict in index 'idx'? */
  1376. if (v k == ExpKind VLOCAL && lh@ v ind_idx == v info) {
  1377. conflict = true
  1378. lh@ v ind_idx = extra /* previous assignment will use safe copy */
  1379. }
  1380. lh = lh@ prev
  1381. }
  1382. if (conflict) {
  1383. op := (v k == ExpKind VLOCAL) ? OpCode OP_MOVE : OpCode OP_GETUPVAL
  1384. fs luaK_codeABC(op, fs freereg, v info, 0) /* make copy */
  1385. fs luaK_reserveregs(1)
  1386. }
  1387. }
  1388. assignment: func(lh: LHS_assign@, nvars: Int) {
  1389. e: ExpDesc
  1390. _check_condition(lh v k vkisvar(), "syntax error")
  1391. if (_testnext(',' as Int)) { /* assignment -> `,' primaryexp assignment */
  1392. nv: LHS_assign
  1393. nv prev = lh&
  1394. primaryexp(nv v&)
  1395. if (nv v k != ExpKind VINDEXED)
  1396. _check_conflict(lh&, nv v&)
  1397. assignment(nv&, nvars+1)
  1398. }
  1399. else { /* assignment -> `=' explist1 */
  1400. _checknext('=' as Int)
  1401. nexps := explist1(e&)
  1402. if (nexps != nvars) {
  1403. _adjust_assign(nvars, nexps, e&)
  1404. if (nexps > nvars)
  1405. fs freereg -= nexps - nvars /* remove extra values */
  1406. }
  1407. else {
  1408. fs luaK_setoneret(e&) /* close last expression */
  1409. fs luaK_storevar(lh v&, e&)
  1410. return /* avoid default */
  1411. }
  1412. }
  1413. init_exp(e&, ExpKind VNONRELOC, fs freereg - 1) /* default assignment */
  1414. fs luaK_storevar(lh v&, e&)
  1415. }
  1416. cond: func -> Int {
  1417. /* cond -> exp */
  1418. v: ExpDesc
  1419. expr(v&) /* read condition */
  1420. if (v k == ExpKind VNIL)
  1421. v k = ExpKind VFALSE /* `falses' are all equal here */
  1422. fs luaK_goiftrue(v&)
  1423. return v f
  1424. }
  1425. breakstat: func {
  1426. bl := fs bl
  1427. upval := false
  1428. while (bl) {
  1429. if (bl@ isbreakable)
  1430. break
  1431. upval |= bl@ upval
  1432. bl = bl@ previous
  1433. }
  1434. if (! bl)
  1435. syntaxError("no loop to break")
  1436. if (upval)
  1437. fs luaK_codeABC(OpCode OP_CLOSE, bl@ nactvar, 0, 0)
  1438. fs luaK_concat(bl@ breaklist&, fs luaK_jump())
  1439. }
  1440. whilestat: func(line: Int) {
  1441. /* whilestat -> WHILE cond DO block END */
  1442. bl: BlockCnt
  1443. next() /* skip WHILE */
  1444. whileinit := fs luaK_getlabel()
  1445. condexit := cond()
  1446. fs enterblock(bl&, true)
  1447. _checknext(TK_DO)
  1448. block()
  1449. fs luaK_patchlist(fs luaK_jump(), whileinit)
  1450. _check_match(TK_END, TK_WHILE, line)
  1451. fs leaveblock()
  1452. fs luaK_patchtohere(condexit) /* false conditions finish the loop */
  1453. }
  1454. repeatstat: func(line: Int) {
  1455. /* repeatstat -> REPEAT block UNTIL cond */
  1456. repeat_init := fs luaK_getlabel()
  1457. bl1, bl2: BlockCnt
  1458. fs enterblock(bl1&, true); /* loop block */
  1459. fs enterblock(bl2&, false); /* scope block */
  1460. next() /* skip REPEAT */
  1461. chunk()
  1462. _check_match(TK_UNTIL, TK_REPEAT, line)
  1463. condexit := cond() /* read condition (inside scope block) */
  1464. if (!bl2 upval) { /* no upvalues? */
  1465. fs leaveblock() /* finish scope */
  1466. fs luaK_patchlist(condexit, repeat_init) /* close the loop */
  1467. }
  1468. else { /* complete semantics when there are upvalues */
  1469. breakstat() /* if condition then break */
  1470. fs luaK_patchtohere(condexit) /* else... */
  1471. fs leaveblock() /* finish scope... */
  1472. fs luaK_patchlist(fs luaK_jump(), repeat_init) /* and repeat */
  1473. }
  1474. fs leaveblock() /* finish loop */
  1475. }
  1476. exp1: func {
  1477. e: ExpDesc
  1478. expr(e&)
  1479. fs luaK_exp2nextreg(e&)
  1480. version(debug) {
  1481. assert(e k == ExpKind VNONRELOC)
  1482. }
  1483. return e info
  1484. }
  1485. forbody: func(base, line, nvars: Int, isnum: Bool) {
  1486. /* forbody -> DO block */
  1487. bl: BlockCnt
  1488. _adjustlocalvars(3) /* control variables */
  1489. _checknext(TK_DO)
  1490. prep := isnum ? fs luaK_codeABx(OpCode OP_FORPREP, base, NO_JUMP + MAXARG_sBx) : fs luaK_jump()
  1491. fs enterblock(bl&, false) /* scope for declared variables */
  1492. _adjustlocalvars(nvars)
  1493. fs luaK_reserveregs(nvars)
  1494. block()
  1495. fs leaveblock() /* end of scope for declared variables */
  1496. fs luaK_patchtohere(prep)
  1497. endfor: Int
  1498. if (isnum) /* numeric for? */
  1499. endfor = fs luaK_codeABx(OpCode OP_FORLOOP, base, NO_JUMP + MAXARG_sBx);
  1500. else { /* generic for */
  1501. fs luaK_codeABC(OpCode OP_TFORCALL, base, 0, nvars)
  1502. fs luaK_fixline(line)
  1503. endfor = fs luaK_codeABx(OpCode OP_TFORLOOP, base + 2, NO_JUMP + MAXARG_sBx);
  1504. }
  1505. fs luaK_patchlist(endfor, prep + 1)
  1506. fs luaK_fixline(line)
  1507. }
  1508. fornum: func(varname: String, line: Int) {
  1509. /* fornum -> NAME = exp1,exp1[,exp1] forbody */
  1510. base := fs freereg
  1511. _new_localvarliteral("(for index)")
  1512. _new_localvarliteral("(for limit)")
  1513. _new_localvarliteral("(for step)")
  1514. _new_localvar(varname)
  1515. _checknext('=' as Int)
  1516. exp1() /* initial value */
  1517. _checknext(',' as Int)
  1518. exp1() /* limit */
  1519. if (_testnext(',' as Int))
  1520. exp1() /* optional step */
  1521. else { /* default step = 1 */
  1522. fs luaK_codeABxX(OpCode OP_LOADK, fs freereg, fs luaK_numberK(1))
  1523. fs luaK_reserveregs(1)
  1524. }
  1525. forbody(base, line, 1, true)
  1526. }
  1527. forlist: func(indexname: String) {
  1528. /* forlist -> NAME {,NAME} IN explist1 forbody */
  1529. nvars := 4 /* gen, state, control, plus at least one declared var */
  1530. base := fs freereg
  1531. /* create control variables */
  1532. _new_localvarliteral("(for generator)")
  1533. _new_localvarliteral("(for state)")
  1534. _new_localvarliteral("(for control)")
  1535. /* create declared variables */
  1536. _new_localvar(indexname)
  1537. while (_testnext(',' as Int)) {
  1538. _new_localvar(_str_checkname())
  1539. nvars += 1
  1540. }
  1541. _checknext(TK_IN)
  1542. line := linenumber
  1543. e: ExpDesc
  1544. _adjust_assign(3, explist1(e&), e&)
  1545. fs luaK_checkstack(3) /* extra space to call generator */
  1546. forbody(base, line, nvars - 3, false)
  1547. }
  1548. forstat: func(line: Int) {
  1549. /* forstat -> FOR (fornum | forlist) END */
  1550. bl: BlockCnt
  1551. fs enterblock(bl&, true) /* scope for loop and control variables */
  1552. next() /* skip `for' */
  1553. varname := _str_checkname() /* first variable name */
  1554. match (t token) {
  1555. case '=' =>
  1556. fornum(varname, line)
  1557. case ',' =>
  1558. forlist(varname)
  1559. case TK_IN =>
  1560. forlist(varname)
  1561. case =>
  1562. syntaxError("'=' or 'in' expected")
  1563. }
  1564. _check_match(TK_END, TK_FOR, line)
  1565. fs leaveblock() /* loop scope (`break' jumps to this point) */
  1566. }
  1567. test_then_block: func -> Int {
  1568. /* test_then_block -> [IF | ELSEIF] cond THEN block */
  1569. next() /* skip IF or ELSEIF */
  1570. condexit := cond()
  1571. _checknext(TK_THEN)
  1572. block() /* `then' part */
  1573. return condexit
  1574. }
  1575. ifstat: func(line: Int) {
  1576. /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
  1577. escapelist := NO_JUMP
  1578. flist := test_then_block() /* IF cond THEN block */
  1579. while (t token == TK_ELSEIF) {
  1580. fs luaK_concat(escapelist&, fs luaK_jump())
  1581. fs luaK_patchtohere(flist)
  1582. flist = test_then_block() /* ELSEIF cond THEN block */
  1583. }
  1584. if (t token == TK_ELSE) {
  1585. fs luaK_concat(escapelist&, fs luaK_jump())
  1586. fs luaK_patchtohere(flist)
  1587. next() /* skip ELSE (after patch, for correct line info) */
  1588. block() /* `else' part */
  1589. }
  1590. else
  1591. fs luaK_concat(escapelist&, flist)
  1592. fs luaK_patchtohere(escapelist)
  1593. _check_match(TK_END, TK_IF, line)
  1594. }
  1595. localfunc: func {
  1596. v, b: ExpDesc
  1597. _new_localvar(_str_checkname())
  1598. init_exp(v&, ExpKind VLOCAL, fs freereg)
  1599. fs luaK_reserveregs(1)
  1600. _adjustlocalvars(1)
  1601. body(b&, false, linenumber)
  1602. fs luaK_storevar(v&, b&)
  1603. }
  1604. localstat: func {
  1605. /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
  1606. nvars := 0
  1607. nexps: Int
  1608. e: ExpDesc
  1609. while (true) {
  1610. _new_localvar(_str_checkname())
  1611. nvars += 1
  1612. if (! _testnext(',' as Int))
  1613. break
  1614. }
  1615. if (_testnext('=' as Int))
  1616. nexps = explist1(e&)
  1617. else {
  1618. e k = ExpKind VVOID
  1619. nexps = 0
  1620. }
  1621. _adjust_assign(nvars, nexps, e&)
  1622. _adjustlocalvars(nvars)
  1623. }
  1624. funcname: func(v: ExpDesc@) -> Bool {
  1625. /* funcname -> NAME {fieldsel} [`:' NAME] */
  1626. needself := false
  1627. _singlevar(v&)
  1628. while (t token == '.')
  1629. fieldsel(v&)
  1630. if (t token == ':') {
  1631. needself = true
  1632. fieldsel(v&)
  1633. }
  1634. return needself
  1635. }
  1636. funcstat: func(line: Int) {
  1637. /* funcstat -> FUNCTION funcname body */
  1638. v, b: ExpDesc
  1639. next() /* skip FUNCTION */
  1640. needself := funcname(v&)
  1641. body(b&, needself, line)
  1642. fs luaK_storevar(v&, b&)
  1643. fs luaK_fixline(line) /* definition `happens' in the first line */
  1644. }
  1645. exprstat: func {
  1646. /* stat -> func | assignment */
  1647. v: LHS_assign
  1648. primaryexp(v v&)
  1649. if (v v k == ExpKind VCALL) { /* stat -> func */
  1650. pi := fs f code data as Instruction* + v v info
  1651. pi@ = pi@ setarg_C(1) /* call statement uses no results */
  1652. }
  1653. else { /* stat -> assignment */
  1654. v prev = null
  1655. assignment(v&, 1)
  1656. }
  1657. }
  1658. retstat: func {
  1659. /* stat -> RETURN explist */
  1660. e: ExpDesc
  1661. first, nret: Int /* registers with returned values */
  1662. if (block_follow(t token) || t token == ';') {
  1663. first = 0
  1664. nret = 0 /* return no values */
  1665. }
  1666. else {
  1667. nret = explist1(e&) /* optional return values */
  1668. if (e k hasmultret()) {
  1669. fs luaK_setreturns(e&, LUA_MULTRET)
  1670. if (e k == ExpKind VCALL && nret == 1) { /* tail call? */
  1671. pi := fs f code data as Instruction* + e info
  1672. pi@ = pi@ setOpcode(OpCode OP_TAILCALL)
  1673. version(debug) {
  1674. assert(pi@ getarg_A() == fs nactvar)
  1675. }
  1676. }
  1677. first = fs nactvar
  1678. nret = LUA_MULTRET /* return all values */
  1679. }
  1680. else {
  1681. if (nret == 1) /* only one single value? */
  1682. first = fs luaK_exp2anyreg(e&)
  1683. else {
  1684. fs luaK_exp2nextreg(e&) /* values must go to the `stack' */
  1685. first = fs nactvar /* return all `active' values */
  1686. version(debug) {
  1687. assert(nret == fs freereg - first)
  1688. }
  1689. }
  1690. }
  1691. }
  1692. fs luaK_ret(first, nret)
  1693. }
  1694. statement: func -> Bool {
  1695. line := linenumber /* may be needed for error messages */
  1696. match (t token) {
  1697. case ';' => /* stat -> ';' (empty statement) */
  1698. next() /* skip ';' */
  1699. return false
  1700. case TK_IF => /* stat -> ifstat */
  1701. ifstat(line)
  1702. return false
  1703. case TK_WHILE => /* stat -> whilestat */
  1704. whilestat(line)
  1705. return false
  1706. case TK_DO => /* stat -> DO block END */
  1707. next() /* skip DO */
  1708. block()
  1709. _check_match(TK_END, TK_DO, line)
  1710. return false
  1711. case TK_FOR => /* stat -> forstat */
  1712. forstat(line)
  1713. return false
  1714. case TK_REPEAT => /* stat -> repeatstat */
  1715. repeatstat(line)
  1716. return false
  1717. case TK_FUNCTION => /* stat -> funcstat */
  1718. funcstat(line)
  1719. return false
  1720. case TK_LOCAL => /* stat -> localstat */
  1721. next() /* skip LOCAL */
  1722. if (_testnext(TK_FUNCTION)) /* local function? */
  1723. localfunc()
  1724. else
  1725. localstat()
  1726. return false
  1727. case TK_RETURN => /* stat -> retstat */
  1728. next() /* skip RETURN */
  1729. retstat()
  1730. return true /* must be last statement */
  1731. case TK_BREAK => /* stat -> breakstat */
  1732. next() /* skip BREAK */
  1733. breakstat()
  1734. return true /* must be last statement */
  1735. case => /* stat -> func | assignment */
  1736. exprstat()
  1737. return false
  1738. }
  1739. return false
  1740. }
  1741. chunk: func {
  1742. /* chunk -> { stat [`;'] } */
  1743. last := false
  1744. _enterlevel()
  1745. while (!last && !block_follow(t token)) {
  1746. last = statement()
  1747. if (last)
  1748. _testnext(';' as Int)
  1749. version(debug) {
  1750. assert(fs f maxstacksize >= fs freereg)
  1751. assert(fs freereg >= fs nactvar)
  1752. }
  1753. fs freereg = fs nactvar
  1754. }
  1755. _leavelevel()
  1756. }
  1757. _testnext: func(c: Int) -> Bool {
  1758. if (t token == c) {
  1759. next()
  1760. return true
  1761. }
  1762. else
  1763. return false
  1764. }
  1765. _check: func(c: Int) {
  1766. if (t token != c)
  1767. _error_expected(c)
  1768. }
  1769. _checknext: func(c: Int) {
  1770. _check(c)
  1771. next()
  1772. }
  1773. _check_condition: func(c: Bool, msg: String) {
  1774. if (! c)
  1775. syntaxError(msg)
  1776. }
  1777. _check_match: func(what, who, where: Int) {
  1778. if (! _testnext(what)) {
  1779. if (where == linenumber)
  1780. _error_expected(what)
  1781. else
  1782. syntaxError("%s expected (to close %s at line %d)" format(
  1783. token2str(what),
  1784. token2str(who),
  1785. where
  1786. ))
  1787. }
  1788. }
  1789. _str_checkname: func -> String {
  1790. _check(TK_NAME)
  1791. ts := t str
  1792. next()
  1793. return ts
  1794. }
  1795. _codestring: func(e: ExpDesc@, s: String) {
  1796. init_exp(e&, ExpKind VK, fs luaK_stringK(s))
  1797. }
  1798. _checkname: func(e: ExpDesc@) {
  1799. _codestring(e&, _str_checkname())
  1800. }
  1801. _registerlocalvar: func(varname: String) -> Int {
  1802. locvars := fs f locvars
  1803. idx := locvars getSize()
  1804. locvars add(LocVar new(varname))
  1805. return idx
  1806. }
  1807. _new_localvar: func(name: String) {
  1808. reg := _registerlocalvar(name)
  1809. fs checklimit(actvar getSize() + 1 - fs firstlocal, MAXVARS, "local variables")
  1810. actvar add(reg)
  1811. }
  1812. _new_localvarliteral: func(name: String) {
  1813. _new_localvar(name)
  1814. }
  1815. _adjustlocalvars: func(nvars: Int) {
  1816. fs nactvar += nvars
  1817. while (nvars) {
  1818. pvar := fs getlocvar(fs nactvar - nvars)
  1819. pvar@ startpc = fs f code getSize()
  1820. nvars -= 1
  1821. }
  1822. }
  1823. _singlevar: func(var: ExpDesc@) {
  1824. varname := _str_checkname()
  1825. if (fs singlevaraux(varname, var&, 1) == ExpKind VVOID) { /* global name? */
  1826. key: ExpDesc
  1827. fs singlevaraux(envn, var&, 1) /* get environment variable */
  1828. version(debug) {
  1829. assert(var k == ExpKind VLOCAL || var k == ExpKind VUPVAL)
  1830. }
  1831. _codestring(key&, varname) /* key is variable name */
  1832. fs luaK_indexed(var&, key&) /* env[varname] */
  1833. }
  1834. }
  1835. _adjust_assign: func(nvars, nexps: Int, e: ExpDesc@) {
  1836. extra := nvars - nexps
  1837. if (e k hasmultret()) {
  1838. extra += 1 /* includes call itself */
  1839. if (extra < 0)
  1840. extra = 0
  1841. fs luaK_setreturns(e&, extra) /* last exp. provides the difference */
  1842. if (extra > 1)
  1843. fs luaK_reserveregs(extra-1)
  1844. }
  1845. else {
  1846. if (e k != ExpKind VVOID)
  1847. fs luaK_exp2nextreg(e&) /* close last expression */
  1848. if (extra > 0) {
  1849. reg := fs freereg
  1850. fs luaK_reserveregs(extra)
  1851. fs luaK_nil(reg, extra)
  1852. }
  1853. }
  1854. }
  1855. _enterlevel: func {
  1856. }
  1857. _leavelevel: func {
  1858. }
  1859. /*
  1860. ** adds prototype being created into its parent list of prototypes
  1861. ** and codes instruction to create new closure
  1862. */
  1863. _codeclosure: func(clp: LuaProto, v: ExpDesc@) {
  1864. f := fs prev f /* prototype of function creating new closure */
  1865. np := f p getSize()
  1866. f p add(clp)
  1867. init_exp(v&, ExpKind VRELOCABLE, fs prev luaK_codeABx(OpCode OP_CLOSURE, 0, np))
  1868. }
  1869. /*
  1870. ** opens the main function, which is a regular vararg function with an
  1871. ** upvalue named LUA_ENV
  1872. */
  1873. _mainfunc: func {
  1874. fs = FuncState new(this, null as FuncState)
  1875. fs f is_vararg = true /* main function is always vararg */
  1876. v: ExpDesc
  1877. init_exp(v&, ExpKind VLOCAL, 0)
  1878. fs newupvalue(envn, v&) /* create environment upvalue */
  1879. }
  1880. _error_expected: func(c: Int) {
  1881. syntaxError("%s expected" format(token2str(c)))
  1882. }
  1883. }
  1884. PRIORITY_LEFT := const [
  1885. 6, 6, 7, 7, 7, /* `+' `-' `*' `/' `%' */
  1886. 10, 5, /* ^, .. (right associative) */
  1887. 3, 3, 3, /* ==, <, <= */
  1888. 3, 3, 3, /* ~=, >, >= */
  1889. 2, 1 /* and, or */
  1890. ]
  1891. PRIORITY_RIGHT := const [
  1892. 6, 6, 7, 7, 7, /* `+' `-' `*' `/' `%' */
  1893. 9, 4, /* ^, .. (right associative) */
  1894. 3, 3, 3, /* ==, <, <= */
  1895. 3, 3, 3, /* ~=, >, >= */
  1896. 2, 1 /* and, or */
  1897. ]
  1898. UNARY_PRIORITY := const 8 /* priority for unary operators */
  1899. /*
  1900. ** Marks the end of a patch list. It is an invalid value both as an absolute
  1901. ** address, and as a list link (would link an element to itself).
  1902. */
  1903. NO_JUMP := const -1
  1904. /*
  1905. ** grep "ORDER OPR" if you change these enums (ORDER OP)
  1906. */
  1907. BinOpr: enum {
  1908. OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
  1909. OPR_CONCAT,
  1910. OPR_EQ, OPR_LT, OPR_LE,
  1911. OPR_NE, OPR_GT, OPR_GE,
  1912. OPR_AND, OPR_OR,
  1913. OPR_NOBINOPR
  1914. }
  1915. UnOpr: enum {
  1916. OPR_MINUS,
  1917. OPR_NOT,
  1918. OPR_LEN,
  1919. OPR_NOUNOPR
  1920. }
  1921. /* maximum number of local variables per function (must be smaller
  1922. than 250, due to the bytecode format) */
  1923. MAXVARS := const 200
  1924. /* maximum stack for a Lua function */
  1925. MAXSTACK := const 250
  1926. MAX_INT := const INT_MAX-2 /* maximum value of an int (-2 for safety) */
  1927. /*
  1928. ** maximum depth for nested C calls and syntactical nested non-terminals
  1929. ** in a program. (Value must fit in an unsigned short int.)
  1930. */
  1931. LUAI_MAXCCALLS := const 200
  1932. /*
  1933. ** maximum number of upvalues in a closure (both C and Lua). (Value
  1934. ** must fit in an unsigned char.)
  1935. */
  1936. MAXUPVAL := const 255 // UCHAR_MAX