summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c66
-rw-r--r--ldo.c5
-rw-r--r--lobject.h29
-rw-r--r--lopcodes.h5
-rw-r--r--lparser.c1035
-rw-r--r--lvm.c38
6 files changed, 658 insertions, 520 deletions
diff --git a/ldebug.c b/ldebug.c
index 4b31f458..2557d221 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.1 1999/12/14 18:31:20 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.2 1999/12/23 18:19:57 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -8,6 +8,8 @@
8#define LUA_REENTRANT 8#define LUA_REENTRANT
9 9
10#include "lapi.h" 10#include "lapi.h"
11#include "lauxlib.h"
12#include "ldebug.h"
11#include "lfunc.h" 13#include "lfunc.h"
12#include "lobject.h" 14#include "lobject.h"
13#include "lstate.h" 15#include "lstate.h"
@@ -17,6 +19,10 @@
17#include "luadebug.h" 19#include "luadebug.h"
18 20
19 21
22static int hasdebuginfo (lua_State *L, lua_Function f) {
23 return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE);
24}
25
20 26
21lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func) { 27lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func) {
22 lua_LHFunction old = L->linehook; 28 lua_LHFunction old = L->linehook;
@@ -52,6 +58,29 @@ lua_Function lua_stackedfunction (lua_State *L, int level) {
52} 58}
53 59
54 60
61const char *luaG_getname (lua_State *L, const char **name) {
62 lua_Function f = lua_stackedfunction(L, 0);
63 if (f == LUA_NOOBJECT || !hasdebuginfo(L, f) || ttype(f+2) == LUA_T_NIL)
64 return NULL; /* no name available */
65 else {
66 int i = (f+2)->value.i;
67 if (ttype(f) == LUA_T_LCLMARK)
68 f = protovalue(f);
69 LUA_ASSERT(L, ttype(f) == LUA_T_LMARK, "must be a Lua function");
70 LUA_ASSERT(L, ttype(&tfvalue(f)->consts[i]) == LUA_T_STRING, "");
71 *name = tsvalue(&tfvalue(f)->consts[i])->str;
72 switch (ttype(f+2)) {
73 case LUA_T_NGLOBAL: return "global";
74 case LUA_T_NLOCAL: return "local";
75 case LUA_T_NDOT: return "field";
76 default:
77 LUA_INTERNALERROR(L, "invalid tag for NAME");
78 return NULL; /* unreacheable; to avoid warnings */
79 }
80 }
81}
82
83
55int lua_nups (lua_State *L, lua_Function f) { 84int lua_nups (lua_State *L, lua_Function f) {
56 UNUSED(L); 85 UNUSED(L);
57 switch (luaA_normalizedtype(f)) { 86 switch (luaA_normalizedtype(f)) {
@@ -64,7 +93,7 @@ int lua_nups (lua_State *L, lua_Function f) {
64 93
65 94
66int lua_currentline (lua_State *L, lua_Function f) { 95int lua_currentline (lua_State *L, lua_Function f) {
67 return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; 96 return hasdebuginfo(L, f) ? (f+1)->value.i : -1;
68} 97}
69 98
70 99
@@ -77,9 +106,10 @@ lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
77 TProtoFunc *fp = luaA_protovalue(f)->value.tf; 106 TProtoFunc *fp = luaA_protovalue(f)->value.tf;
78 *name = luaF_getlocalname(fp, local_number, lua_currentline(L, f)); 107 *name = luaF_getlocalname(fp, local_number, lua_currentline(L, f));
79 if (*name) { 108 if (*name) {
80 /* if "*name", there must be a LUA_T_LINE */ 109 /* if "*name", there must be a LUA_T_LINE and a NAME */
81 /* therefore, f+2 points to function base */ 110 /* therefore, f+3 points to function base */
82 return luaA_putluaObject(L, (f+2)+(local_number-1)); 111 LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
112 return luaA_putluaObject(L, (f+3)+(local_number-1));
83 } 113 }
84 else 114 else
85 return LUA_NOOBJECT; 115 return LUA_NOOBJECT;
@@ -98,9 +128,8 @@ int lua_setlocal (lua_State *L, lua_Function f, int local_number) {
98 luaA_checkCparams(L, 1); 128 luaA_checkCparams(L, 1);
99 --L->top; 129 --L->top;
100 if (name) { 130 if (name) {
101 /* if "name", there must be a LUA_T_LINE */ 131 LUA_ASSERT(L, ttype(f+1) == LUA_T_LINE, "");
102 /* therefore, f+2 points to function base */ 132 *((f+3)+(local_number-1)) = *L->top;
103 *((f+2)+(local_number-1)) = *L->top;
104 return 1; 133 return 1;
105 } 134 }
106 else 135 else
@@ -148,3 +177,24 @@ const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
148 else return ""; /* not found at all */ 177 else return ""; /* not found at all */
149} 178}
150 179
180static void call_index_error (lua_State *L, TObject *o, const char *tp,
181 const char *v) {
182 const char *name;
183 const char *kind = luaG_getname(L, &name);
184 if (kind) { /* is there a name? */
185 luaL_verror(L, "%.10s `%.30s' is not a %.10s", kind, name, tp);
186 }
187 else {
188 luaL_verror(L, "attempt to %.10s a %.10s value", v, lua_type(L, o));
189 }
190}
191
192
193void luaG_callerror (lua_State *L, TObject *func) {
194 call_index_error(L, func, "function", "call");
195}
196
197
198void luaG_indexerror (lua_State *L, TObject *t) {
199 call_index_error(L, t, "table", "index");
200}
diff --git a/ldo.c b/ldo.c
index e4751e48..d2bdd440 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.60 1999/12/23 18:19:57 roberto Exp roberto $ 2** $Id: ldo.c,v 1.61 1999/12/27 17:33:22 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,6 +13,7 @@
13#define LUA_REENTRANT 13#define LUA_REENTRANT
14 14
15#include "lauxlib.h" 15#include "lauxlib.h"
16#include "ldebug.h"
16#include "ldo.h" 17#include "ldo.h"
17#include "lgc.h" 18#include "lgc.h"
18#include "lmem.h" 19#include "lmem.h"
@@ -220,7 +221,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
220 default: { /* `func' is not a function; check the `function' tag method */ 221 default: { /* `func' is not a function; check the `function' tag method */
221 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); 222 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
222 if (ttype(im) == LUA_T_NIL) 223 if (ttype(im) == LUA_T_NIL)
223 lua_error(L, "call expression not a function"); 224 luaG_callerror(L, func);
224 luaD_openstack(L, func); 225 luaD_openstack(L, func);
225 *func = *im; /* tag method is the new function to be called */ 226 *func = *im; /* tag method is the new function to be called */
226 goto retry; /* retry the call (without calling callhook again) */ 227 goto retry; /* retry the call (without calling callhook again) */
diff --git a/lobject.h b/lobject.h
index e971c85b..da61835c 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.41 1999/12/23 18:19:57 roberto Exp roberto $ 2** $Id: lobject.h,v 1.42 1999/12/27 17:33:22 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -72,16 +72,25 @@ typedef enum {
72 LUA_T_LPROTO = -4, /* fixed tag for Lua functions */ 72 LUA_T_LPROTO = -4, /* fixed tag for Lua functions */
73 LUA_T_CPROTO = -5, /* fixed tag for C functions */ 73 LUA_T_CPROTO = -5, /* fixed tag for C functions */
74 LUA_T_NIL = -6, /* last "pre-defined" tag */ 74 LUA_T_NIL = -6, /* last "pre-defined" tag */
75
75 LUA_T_LCLOSURE = -7, /* Lua closure */ 76 LUA_T_LCLOSURE = -7, /* Lua closure */
76 LUA_T_CCLOSURE = -8, /* C closure */ 77 LUA_T_CCLOSURE = -8, /* C closure */
78
77 LUA_T_LCLMARK = -9 ,/* mark for Lua closures */ 79 LUA_T_LCLMARK = -9 ,/* mark for Lua closures */
78 LUA_T_CCLMARK = -10,/* mark for C closures */ 80 LUA_T_CCLMARK = -10,/* mark for C closures */
79 LUA_T_LMARK = -11, /* mark for Lua prototypes */ 81 LUA_T_LMARK = -11, /* mark for Lua prototypes */
80 LUA_T_CMARK = -12, /* mark for C prototypes */ 82 LUA_T_CMARK = -12, /* mark for C prototypes */
81 LUA_T_LINE = -13 83
84 LUA_T_LINE = -13,
85 LUA_T_NGLOBAL = -14,
86 LUA_T_NLOCAL = -15,
87 LUA_T_NDOT = -16
82} lua_Type; 88} lua_Type;
83 89
84#define NUM_TAGS 7 90#define NUM_TAGS 7 /* tags for values visible from Lua */
91
92
93#define LAST_REGULAR_TAG LUA_T_CCLOSURE /* after that, are all marks */
85 94
86/* 95/*
87** chech whether `t' is a mark; ttypes are negative numbers, so the 96** chech whether `t' is a mark; ttypes are negative numbers, so the
@@ -91,13 +100,13 @@ typedef enum {
91 100
92 101
93typedef union { 102typedef union {
94 lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */ 103 lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */
95 real n; /* LUA_T_NUMBER */ 104 real n; /* LUA_T_NUMBER */
96 struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ 105 struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
97 struct TProtoFunc *tf; /* LUA_T_LPROTO, LUA_T_LMARK */ 106 struct TProtoFunc *tf; /* LUA_T_LPROTO, LUA_T_LMARK */
98 struct Closure *cl; /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */ 107 struct Closure *cl; /* LUA_T_[CL]CLOSURE, LUA_T_[CL]CLMARK */
99 struct Hash *a; /* LUA_T_ARRAY */ 108 struct Hash *a; /* LUA_T_ARRAY */
100 int i; /* LUA_T_LINE */ 109 int i; /* LUA_T_LINE */
101} Value; 110} Value;
102 111
103 112
diff --git a/lopcodes.h b/lopcodes.h
index f44b5f76..cb5fabeb 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.34 1999/11/25 18:59:43 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.35 1999/12/27 17:33:22 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -102,6 +102,9 @@ CLOSURE,/* b c v_c-v_1 closure(CNST[b], v_c-v_1) */
102SETLINEW,/* w - - LINE=w */ 102SETLINEW,/* w - - LINE=w */
103SETLINE,/* b - - LINE=b */ 103SETLINE,/* b - - LINE=b */
104 104
105SETNAMEW,/* w c - - NAME=CNST[w],c */
106SETNAME,/* b c - - NAME=CNST[b],c */
107
105LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */ 108LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
106LONGARG /* b (add b*(1<<16) to arg of next instruction) */ 109LONGARG /* b (add b*(1<<16) to arg of next instruction) */
107 110
diff --git a/lparser.c b/lparser.c
index 4229ddd6..e21ad7a1 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.49 1999/12/22 16:58:36 roberto Exp roberto $ 2** $Id: lparser.c,v 1.50 1999/12/23 18:19:57 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -63,6 +63,8 @@ typedef enum {
63typedef struct vardesc { 63typedef struct vardesc {
64 varkind k; 64 varkind k;
65 int info; 65 int info;
66 varkind prev_k; /* for debug information (NAMEs) */
67 int prev_info;
66} vardesc; 68} vardesc;
67 69
68 70
@@ -70,7 +72,7 @@ typedef struct vardesc {
70** Expression List descriptor: 72** Expression List descriptor:
71** tells number of expressions in the list, 73** tells number of expressions in the list,
72** and, if last expression is open (a function call), 74** and, if last expression is open (a function call),
73** where is its pc index of "nparam" 75** where is its pc index of `nparam'
74*/ 76*/
75typedef struct listdesc { 77typedef struct listdesc {
76 int n; 78 int n;
@@ -93,7 +95,7 @@ typedef struct constdesc {
93/* state needed to generate code for a given function */ 95/* state needed to generate code for a given function */
94typedef struct FuncState { 96typedef struct FuncState {
95 TProtoFunc *f; /* current function header */ 97 TProtoFunc *f; /* current function header */
96 struct FuncState *prev; /* enclosuring function */ 98 struct FuncState *prev; /* enclosing function */
97 int pc; /* next position to code */ 99 int pc; /* next position to code */
98 int stacksize; /* number of values on activation register */ 100 int stacksize; /* number of values on activation register */
99 int maxstacksize; /* maximum number of values on activation register */ 101 int maxstacksize; /* maximum number of values on activation register */
@@ -107,34 +109,13 @@ typedef struct FuncState {
107 109
108 110
109/* 111/*
110** prototypes for non-terminal functions 112** prototypes for recursive non-terminal functions
111*/ 113*/
112static int assignment (LexState *ls, vardesc *v, int nvars);
113static int cond (LexState *ls);
114static int funcname (LexState *ls, vardesc *v);
115static int funcparams (LexState *ls, int slf);
116static int listfields (LexState *ls);
117static int localnamelist (LexState *ls);
118static int optional (LexState *ls, int c);
119static int recfields (LexState *ls);
120static int stat (LexState *ls);
121static void block (LexState *ls);
122static void body (LexState *ls, int needself, int line); 114static void body (LexState *ls, int needself, int line);
123static void chunk (LexState *ls); 115static void chunk (LexState *ls);
124static void constructor (LexState *ls); 116static void constructor (LexState *ls);
125static void decinit (LexState *ls, listdesc *d); 117static void exp (LexState *ls, vardesc *v);
126static void exp0 (LexState *ls, vardesc *v);
127static void exp1 (LexState *ls); 118static void exp1 (LexState *ls);
128static void exp2 (LexState *ls, vardesc *v);
129static void explist (LexState *ls, listdesc *e);
130static void explist1 (LexState *ls, listdesc *e);
131static void ifpart (LexState *ls, int line);
132static void parlist (LexState *ls);
133static void part (LexState *ls, constdesc *cd);
134static void recfield (LexState *ls);
135static void ret (LexState *ls);
136static void var_or_func (LexState *ls, vardesc *v);
137static void var_or_func_tail (LexState *ls, vardesc *v);
138 119
139 120
140 121
@@ -268,7 +249,7 @@ static void code_string (LexState *ls, TaggedString *s) {
268 249
269#define LIM 20 250#define LIM 20
270static int real_constant (LexState *ls, real r) { 251static int real_constant (LexState *ls, real r) {
271 /* check whether 'r' has appeared within the last LIM entries */ 252 /* check whether `r' has appeared within the last LIM entries */
272 TProtoFunc *f = ls->fs->f; 253 TProtoFunc *f = ls->fs->f;
273 TObject *cnt = f->consts; 254 TObject *cnt = f->consts;
274 int c = f->nconsts; 255 int c = f->nconsts;
@@ -279,7 +260,7 @@ static int real_constant (LexState *ls, real r) {
279 } 260 }
280 /* not found; create a new entry */ 261 /* not found; create a new entry */
281 c = next_constant(ls, f); 262 c = next_constant(ls, f);
282 cnt = f->consts; /* 'next_constant' may reallocate this vector */ 263 cnt = f->consts; /* `next_constant' may reallocate this vector */
283 ttype(&cnt[c]) = LUA_T_NUMBER; 264 ttype(&cnt[c]) = LUA_T_NUMBER;
284 nvalue(&cnt[c]) = r; 265 nvalue(&cnt[c]) = r;
285 return c; 266 return c;
@@ -412,6 +393,31 @@ static void check_debugline (LexState *ls) {
412} 393}
413 394
414 395
396static void code_setname (LexState *ls, const vardesc *v) {
397 if (ls->L->debug) {
398 switch (v->prev_k) {
399 case VGLOBAL:
400 code_oparg(ls, SETNAME, v->prev_info, 0);
401 code_byte(ls, -LUA_T_NGLOBAL);
402 break;
403 case VLOCAL: {
404 TaggedString *varname = ls->fs->localvar[v->prev_info];
405 code_oparg(ls, SETNAME, string_constant(ls, ls->fs, varname), 0);
406 code_byte(ls, -LUA_T_NLOCAL);
407 break;
408 }
409 case VDOT:
410 code_oparg(ls, SETNAME, v->prev_info, 0);
411 code_byte(ls, -LUA_T_NDOT);
412 break;
413 default: /* VINDEXED or VEXP: no debug information */
414 code_oparg(ls, SETNAME, 0, 0);
415 code_byte(ls, -LUA_T_NIL);
416 }
417 }
418}
419
420
415static void adjuststack (LexState *ls, int n) { 421static void adjuststack (LexState *ls, int n) {
416 if (n > 0) 422 if (n > 0)
417 code_oparg(ls, POP, n, -n); 423 code_oparg(ls, POP, n, -n);
@@ -468,7 +474,7 @@ static void code_args (LexState *ls, int nparams, int dots) {
468 474
469 475
470static void unloaddot (LexState *ls, vardesc *v) { 476static void unloaddot (LexState *ls, vardesc *v) {
471 /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */ 477 /* dotted variables <a.x> must be stored as regular indexed vars <a["x"]> */
472 if (v->k == VDOT) { 478 if (v->k == VDOT) {
473 code_constant(ls, v->info); 479 code_constant(ls, v->info);
474 v->k = VINDEXED; 480 v->k = VINDEXED;
@@ -486,15 +492,19 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
486 assertglobal(ls, var->info); /* make sure that there is a global */ 492 assertglobal(ls, var->info); /* make sure that there is a global */
487 break; 493 break;
488 case VDOT: 494 case VDOT:
495 code_setname(ls, var);
489 code_oparg(ls, GETDOTTED, var->info, 0); 496 code_oparg(ls, GETDOTTED, var->info, 0);
490 break; 497 break;
491 case VINDEXED: 498 case VINDEXED:
499 code_setname(ls, var);
492 code_opcode(ls, GETTABLE, -1); 500 code_opcode(ls, GETTABLE, -1);
493 break; 501 break;
494 case VEXP: 502 case VEXP:
495 close_exp(ls, var->info, 1); /* function must return 1 value */ 503 close_exp(ls, var->info, 1); /* function must return 1 value */
496 break; 504 break;
497 } 505 }
506 var->prev_k = var->k; /* save previous var kind and info */
507 var->prev_info = var->info;
498 var->k = VEXP; 508 var->k = VEXP;
499 var->info = 0; /* now this is a closed expression */ 509 var->info = 0; /* now this is a closed expression */
500} 510}
@@ -510,6 +520,7 @@ static void storevar (LexState *ls, const vardesc *var) {
510 assertglobal(ls, var->info); /* make sure that there is a global */ 520 assertglobal(ls, var->info); /* make sure that there is a global */
511 break; 521 break;
512 case VINDEXED: 522 case VINDEXED:
523 code_setname(ls, var);
513 code_opcode(ls, SETTABLEPOP, -3); 524 code_opcode(ls, SETTABLEPOP, -3);
514 break; 525 break;
515 default: 526 default:
@@ -656,7 +667,7 @@ static void check (LexState *ls, int c) {
656static void check_match (LexState *ls, int what, int who, int where) { 667static void check_match (LexState *ls, int what, int who, int where) {
657 if (ls->token != what) 668 if (ls->token != what)
658 error_unmatched(ls, what, who, where); 669 error_unmatched(ls, what, who, where);
659 check_debugline(ls); /* to 'mark' the 'what' */ 670 check_debugline(ls); /* to `mark' the `what' */
660 next(ls); 671 next(ls);
661} 672}
662 673
@@ -705,241 +716,298 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
705/*============================================================*/ 716/*============================================================*/
706 717
707 718
708static void chunk (LexState *ls) {
709 /* chunk -> { stat [;] } ret */
710 while (stat(ls)) {
711 LUA_ASSERT(ls->L, ls->fs->stacksize == ls->fs->nlocalvar,
712 "stack size != # local vars");
713 optional(ls, ';');
714 }
715 ret(ls); /* optional return */
716}
717
718 719
719static void whilestat (LexState *ls, int line) { 720static int SaveWord (LexState *ls) {
720 /* whilestat -> WHILE cond DO block END */ 721 int res = ls->fs->pc;
721 FuncState *fs = ls->fs; 722 check_pc(ls, JMPSIZE);
722 TProtoFunc *f = fs->f; 723 ls->fs->pc += JMPSIZE; /* open space */
723 int while_init = fs->pc; 724 return res;
724 int cond_end, cond_size;
725 next(ls);
726 cond_end = cond(ls);
727 check(ls, DO);
728 block(ls);
729 check_match(ls, END, WHILE, line);
730 cond_size = cond_end-while_init;
731 check_pc(ls, cond_size);
732 memcpy(f->code+fs->pc, f->code+while_init, cond_size);
733 luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init);
734 while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size);
735 fix_upjmp(ls, IFTUPJMP, while_init);
736} 725}
737 726
738 727
739static void repeatstat (LexState *ls, int line) { 728static int SaveWordPop (LexState *ls) {
740 /* repeatstat -> REPEAT block UNTIL exp1 */ 729 deltastack(ls, -1); /* pop condition */
741 FuncState *fs = ls->fs; 730 return SaveWord(ls);
742 int repeat_init = fs->pc;
743 next(ls);
744 block(ls);
745 check_match(ls, UNTIL, REPEAT, line);
746 exp1(ls);
747 fix_upjmp(ls, IFFUPJMP, repeat_init);
748 deltastack(ls, -1); /* pops condition */
749} 731}
750 732
751 733
752static void localstat (LexState *ls) { 734static int cond (LexState *ls) {
753 /* stat -> LOCAL localnamelist decinit */ 735 /* cond -> exp1 */
754 FuncState *fs = ls->fs; 736 exp1(ls);
755 listdesc d; 737 return SaveWordPop(ls);
756 int nvars;
757 check_debugline(ls);
758 next(ls);
759 nvars = localnamelist(ls);
760 decinit(ls, &d);
761 adjustlocalvars(ls, nvars, fs->lastsetline);
762 adjust_mult_assign(ls, nvars, &d);
763} 738}
764 739
765 740
766static int funcstat (LexState *ls, int line) { 741static void explist1 (LexState *ls, listdesc *d) {
767 /* funcstat -> FUNCTION funcname body */
768 int needself;
769 vardesc v; 742 vardesc v;
770 if (ls->fs->prev) /* inside other function? */ 743 exp(ls, &v);
771 return 0; 744 d->n = 1;
772 check_debugline(ls); 745 while (ls->token == ',') {
773 next(ls); 746 d->n++;
774 needself = funcname(ls, &v); 747 lua_pushvar(ls, &v);
775 body(ls, needself, line); 748 next(ls);
776 storevar(ls, &v); 749 exp(ls, &v);
777 return 1; 750 }
751 if (v.k == VEXP)
752 d->pc = v.info;
753 else {
754 lua_pushvar(ls, &v);
755 d->pc = 0;
756 }
778} 757}
779 758
780 759
781static void namestat (LexState *ls) { 760static void explist (LexState *ls, listdesc *d) {
782 /* stat -> func | ['%'] NAME assignment */ 761 switch (ls->token) {
783 vardesc v; 762 case ELSE: case ELSEIF: case END: case UNTIL:
784 check_debugline(ls); 763 case EOS: case ';': case ')':
785 var_or_func(ls, &v); 764 d->pc = 0;
786 if (v.k == VEXP) { /* stat -> func */ 765 d->n = 0;
787 if (v.info == 0) /* is just an upper value? */ 766 break;
788 luaX_error(ls, "syntax error"); 767
789 close_exp(ls, v.info, 0); 768 default:
790 } 769 explist1(ls, d);
791 else { /* stat -> ['%'] NAME assignment */
792 int left = assignment(ls, &v, 1);
793 adjuststack(ls, left); /* remove eventual garbage left on stack */
794 } 770 }
795} 771}
796 772
797 773
798static int stat (LexState *ls) { 774static int funcparams (LexState *ls, int slf, vardesc *v) {
799 int line = ls->linenumber; /* may be needed for error messages */ 775 FuncState *fs = ls->fs;
776 int slevel = fs->stacksize - slf - 1; /* where is func in the stack */
800 switch (ls->token) { 777 switch (ls->token) {
801 case IF: /* stat -> IF ifpart END */ 778 case '(': { /* funcparams -> '(' explist ')' */
802 ifpart(ls, line); 779 int line = ls->linenumber;
803 return 1; 780 listdesc e;
781 next(ls);
782 explist(ls, &e);
783 check_match(ls, ')', '(', line);
784 close_exp(ls, e.pc, MULT_RET); /* close 1 for old semantics */
785 break;
786 }
804 787
805 case WHILE: /* stat -> whilestat */ 788 case '{': /* funcparams -> constructor */
806 whilestat(ls, line); 789 constructor(ls);
807 return 1; 790 break;
808 791
809 case DO: { /* stat -> DO block END */ 792 case STRING: /* funcparams -> STRING */
793 code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before `next' */
810 next(ls); 794 next(ls);
811 block(ls); 795 break;
812 check_match(ls, END, DO, line);
813 return 1;
814 }
815 796
816 case REPEAT: /* stat -> repeatstat */ 797 default:
817 repeatstat(ls, line); 798 luaX_error(ls, "function arguments expected");
818 return 1; 799 break;
800 }
801 code_setname(ls, v);
802 code_byte(ls, CALL);
803 code_byte(ls, 0); /* save space for nresult */
804 code_byte(ls, (Byte)slevel);
805 fs->stacksize = slevel; /* call will remove func and params */
806 return fs->pc-1;
807}
819 808
820 case FUNCTION: /* stat -> funcstat */
821 return funcstat(ls, line);
822 809
823 case LOCAL: /* stat -> localstat */ 810static void var_or_func_tail (LexState *ls, vardesc *v) {
824 localstat(ls); 811 for (;;) {
825 return 1; 812 switch (ls->token) {
813 case '.': /* var_or_func_tail -> '.' NAME */
814 next(ls);
815 lua_pushvar(ls, v); /* `v' must be on stack */
816 v->k = VDOT;
817 v->info = checkname(ls);
818 break;
826 819
827 case NAME: case '%': /* stat -> namestat */ 820 case '[': /* var_or_func_tail -> '[' exp1 ']' */
828 namestat(ls); 821 next(ls);
829 return 1; 822 lua_pushvar(ls, v); /* `v' must be on stack */
823 exp1(ls);
824 check(ls, ']');
825 v->k = VINDEXED;
826 break;
830 827
831 case RETURN: case ';': case ELSE: case ELSEIF: 828 case ':': { /* var_or_func_tail -> ':' NAME funcparams */
832 case END: case UNTIL: case EOS: /* 'stat' follow */ 829 int name;
833 return 0; 830 next(ls);
831 name = checkname(ls);
832 lua_pushvar(ls, v); /* `v' must be on stack */
833 code_setname(ls, v);
834 code_oparg(ls, PUSHSELF, name, 1);
835 v->prev_k = VDOT; /* ':' is syntactic sugar for '.' */
836 v->prev_info = name;
837 v->k = VEXP;
838 v->info = funcparams(ls, 1, v);
839 break;
840 }
834 841
835 default: 842 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
836 error_unexpected(ls); 843 lua_pushvar(ls, v); /* `v' must be on stack */
837 return 0; /* to avoid warnings */ 844 v->k = VEXP;
845 v->info = funcparams(ls, 0, v);
846 break;
847
848 default: return; /* should be follow... */
849 }
838 } 850 }
839} 851}
840 852
841static int SaveWord (LexState *ls) {
842 int res = ls->fs->pc;
843 check_pc(ls, JMPSIZE);
844 ls->fs->pc += JMPSIZE; /* open space */
845 return res;
846}
847 853
848static int SaveWordPop (LexState *ls) { 854static void var_or_func (LexState *ls, vardesc *v) {
849 deltastack(ls, -1); /* pop condition */ 855 /* var_or_func -> ['%'] NAME var_or_func_tail */
850 return SaveWord(ls); 856 if (optional(ls, '%')) { /* upvalue? */
857 pushupvalue(ls, str_checkname(ls));
858 v->k = VEXP;
859 v->info = 0; /* closed expression */
860 }
861 else /* variable name */
862 singlevar(ls, str_checkname(ls), v, 0);
863 var_or_func_tail(ls, v);
851} 864}
852 865
853static int cond (LexState *ls) { 866
854 /* cond -> exp1 */ 867
868/*
869** {======================================================================
870** Rules for Constructors
871** =======================================================================
872*/
873
874static void recfield (LexState *ls) {
875 /* recfield -> (NAME | '['exp1']') = exp1 */
876 switch (ls->token) {
877 case NAME:
878 code_constant(ls, checkname(ls));
879 break;
880
881 case '[':
882 next(ls);
883 exp1(ls);
884 check(ls, ']');
885 break;
886
887 default: luaX_error(ls, "NAME or `[' expected");
888 }
889 check(ls, '=');
855 exp1(ls); 890 exp1(ls);
856 return SaveWordPop(ls);
857} 891}
858 892
859static void block (LexState *ls) {
860 /* block -> chunk */
861 FuncState *fs = ls->fs;
862 int nlocalvar = fs->nlocalvar;
863 chunk(ls);
864 adjuststack(ls, fs->nlocalvar - nlocalvar);
865 for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--)
866 luaI_unregisterlocalvar(ls, fs->lastsetline);
867}
868 893
869static int funcname (LexState *ls, vardesc *v) { 894static int recfields (LexState *ls) {
870 /* funcname -> NAME [':' NAME | '.' NAME] */ 895 /* recfields -> { ',' recfield } [','] */
871 int needself = 0; 896 int n = 1; /* one has been read before */
872 singlevar(ls, str_checkname(ls), v, 0); 897 while (ls->token == ',') {
873 if (ls->token == ':' || ls->token == '.') {
874 needself = (ls->token == ':');
875 next(ls); 898 next(ls);
876 lua_pushvar(ls, v); 899 if (ls->token == ';' || ls->token == '}')
877 code_constant(ls, checkname(ls)); 900 break;
878 v->k = VINDEXED; 901 recfield(ls);
902 n++;
903 if (n%RFIELDS_PER_FLUSH == 0)
904 flush_record(ls, RFIELDS_PER_FLUSH);
879 } 905 }
880 return needself; 906 flush_record(ls, n%RFIELDS_PER_FLUSH);
907 return n;
881} 908}
882 909
883static void body (LexState *ls, int needself, int line) { 910
884 /* body -> '(' parlist ')' chunk END */ 911static int listfields (LexState *ls) {
885 FuncState newfs; 912 /* listfields -> { ',' exp1 } [','] */
886 init_state(ls, &newfs, ls->fs->f->source); 913 int n = 1; /* one has been read before */
887 newfs.f->lineDefined = line; 914 while (ls->token == ',') {
888 check(ls, '('); 915 next(ls);
889 if (needself) 916 if (ls->token == ';' || ls->token == '}')
890 add_localvar(ls, luaS_newfixed(ls->L, "self")); 917 break;
891 parlist(ls); 918 exp1(ls);
892 check(ls, ')'); 919 n++;
893 chunk(ls); 920 if (n%LFIELDS_PER_FLUSH == 0)
894 check_match(ls, END, FUNCTION, line); 921 flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
895 close_func(ls); 922 }
896 func_onstack(ls, &newfs); 923 flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
924 return n;
897} 925}
898 926
899 927
900static void ifpart (LexState *ls, int line) { 928
901 /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ 929static void constructor_part (LexState *ls, constdesc *cd) {
902 int c; 930 switch (ls->token) {
903 int e; 931 case ';': case '}': /* constructor_part -> empty */
904 next(ls); /* skip IF or ELSEIF */ 932 cd->n = 0;
905 c = cond(ls); 933 cd->k = ls->token;
906 check(ls, THEN); 934 return;
907 block(ls); 935
908 e = SaveWord(ls); 936 case NAME: {
909 if (ls->token == ELSEIF) 937 vardesc v;
910 ifpart(ls, line); 938 exp(ls, &v);
911 else { 939 if (ls->token == '=') {
912 if (optional(ls, ELSE)) 940 switch (v.k) {
913 block(ls); 941 case VGLOBAL:
914 check_match(ls, END, IF, line); 942 code_constant(ls, v.info);
943 break;
944 case VLOCAL:
945 code_string(ls, ls->fs->localvar[v.info]);
946 break;
947 default:
948 error_unexpected(ls);
949 }
950 next(ls);
951 exp1(ls);
952 cd->n = recfields(ls);
953 cd->k = 1; /* record */
954 }
955 else {
956 lua_pushvar(ls, &v);
957 cd->n = listfields(ls);
958 cd->k = 0; /* list */
959 }
960 break;
961 }
962
963 case '[': /* constructor_part -> recfield recfields */
964 recfield(ls);
965 cd->n = recfields(ls);
966 cd->k = 1; /* record */
967 break;
968
969 default: /* constructor_part -> exp1 listfields */
970 exp1(ls);
971 cd->n = listfields(ls);
972 cd->k = 0; /* list */
973 break;
915 } 974 }
916 codeIf(ls, c, e);
917} 975}
918 976
919 977
920static void ret (LexState *ls) { 978static void constructor (LexState *ls) {
921 /* ret -> [RETURN explist sc] */ 979 /* constructor -> '{' constructor_part [';' constructor_part] '}' */
922 if (optional(ls, RETURN)) { 980 int line = ls->linenumber;
923 listdesc e; 981 int pc = SaveWord(ls);
924 check_debugline(ls); 982 int nelems;
925 explist(ls, &e); 983 constdesc cd;
926 if (e.pc > 0) { /* expression is an open function call? */ 984 deltastack(ls, 1);
927 Byte *code = ls->fs->f->code; 985 check(ls, '{');
928 code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */ 986 constructor_part(ls, &cd);
929 code[e.pc-1] = (Byte)ls->fs->nlocalvar; 987 nelems = cd.n;
930 } 988 if (ls->token == ';') {
931 else 989 constdesc other_cd;
932 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); 990 next(ls);
933 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ 991 constructor_part(ls, &other_cd);
934 optional(ls, ';'); 992 if (cd.k == other_cd.k) /* repeated parts? */
993 luaX_error(ls, "invalid constructor syntax");
994 nelems += other_cd.n;
935 } 995 }
996 check_match(ls, '}', '{', line);
997 fix_opcode(ls, pc, CREATEARRAY, nelems);
936} 998}
937 999
1000/* }====================================================================== */
1001
1002
1003
938 1004
939/* 1005/*
1006** {======================================================================
940** For parsing expressions, we use a classic stack with priorities. 1007** For parsing expressions, we use a classic stack with priorities.
941** Each binary operator is represented by its index in "binop" + FIRSTBIN 1008** Each binary operator is represented by its index in `binop' + FIRSTBIN
942** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. 1009** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1.
1010** =======================================================================
943*/ 1011*/
944 1012
945#define INDNOT 0 1013#define INDNOT 0
@@ -969,30 +1037,6 @@ typedef struct stack_op {
969} stack_op; 1037} stack_op;
970 1038
971 1039
972static void exp1 (LexState *ls) {
973 vardesc v;
974 exp0(ls, &v);
975 lua_pushvar(ls, &v);
976 if (is_in(ls->token, expfollow) < 0)
977 luaX_error(ls, "malformed expression");
978}
979
980
981static void exp0 (LexState *ls, vardesc *v) {
982 /* exp0 -> exp2 {(AND | OR) exp2} */
983 exp2(ls, v);
984 while (ls->token == AND || ls->token == OR) {
985 int op = (ls->token == AND) ? ONFJMP : ONTJMP;
986 int pc;
987 lua_pushvar(ls, v);
988 next(ls);
989 pc = SaveWordPop(ls);
990 exp2(ls, v);
991 lua_pushvar(ls, v);
992 fix_jump(ls, pc, op, ls->fs->pc);
993 }
994}
995
996 1040
997static void push (LexState *ls, stack_op *s, int op) { 1041static void push (LexState *ls, stack_op *s, int op) {
998 if (s->top >= MAXOPS) 1042 if (s->top >= MAXOPS)
@@ -1015,8 +1059,8 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1015 case NUMBER: { /* simpleexp -> NUMBER */ 1059 case NUMBER: { /* simpleexp -> NUMBER */
1016 real r = ls->seminfo.r; 1060 real r = ls->seminfo.r;
1017 next(ls); 1061 next(ls);
1018 /* dirty trick: check whether it is a -NUMBER not followed by '^' */ 1062 /* dirty trick: check whether it is a -NUMBER not followed by '^' */
1019 /* (because the priority of '^' is higher than '-'...) */ 1063 /* (because the priority of '^' is higher than the priority of '-') */
1020 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') { 1064 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
1021 s->top--; /* remove '-' from stack */ 1065 s->top--; /* remove '-' from stack */
1022 r = -r; 1066 r = -r;
@@ -1044,9 +1088,9 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1044 body(ls, 0, ls->linenumber); 1088 body(ls, 0, ls->linenumber);
1045 break; 1089 break;
1046 1090
1047 case '(': /* simpleexp -> '(' exp0 ')' */ 1091 case '(': /* simpleexp -> '(' exp ')' */
1048 next(ls); 1092 next(ls);
1049 exp0(ls, v); 1093 exp(ls, v);
1050 check(ls, ')'); 1094 check(ls, ')');
1051 return; 1095 return;
1052 1096
@@ -1072,7 +1116,7 @@ static void prefixexp (LexState *ls, vardesc *v, stack_op *s) {
1072} 1116}
1073 1117
1074 1118
1075static void exp2 (LexState *ls, vardesc *v) { 1119static void arith_exp (LexState *ls, vardesc *v) {
1076 stack_op s; 1120 stack_op s;
1077 int op; 1121 int op;
1078 s.top = 0; 1122 s.top = 0;
@@ -1094,156 +1138,118 @@ static void exp2 (LexState *ls, vardesc *v) {
1094} 1138}
1095 1139
1096 1140
1097static void var_or_func (LexState *ls, vardesc *v) { 1141static void exp1 (LexState *ls) {
1098 /* var_or_func -> ['%'] NAME var_or_func_tail */ 1142 vardesc v;
1099 if (optional(ls, '%')) { /* upvalue? */ 1143 exp(ls, &v);
1100 pushupvalue(ls, str_checkname(ls)); 1144 lua_pushvar(ls, &v);
1101 v->k = VEXP; 1145 if (is_in(ls->token, expfollow) < 0)
1102 v->info = 0; /* closed expression */ 1146 luaX_error(ls, "malformed expression");
1103 }
1104 else /* variable name */
1105 singlevar(ls, str_checkname(ls), v, 0);
1106 var_or_func_tail(ls, v);
1107} 1147}
1108 1148
1109 1149
1110static void var_or_func_tail (LexState *ls, vardesc *v) { 1150static void exp (LexState *ls, vardesc *v) {
1111 for (;;) { 1151 /* exp -> arith_exp {(AND | OR) arith_exp} */
1112 switch (ls->token) { 1152 arith_exp(ls, v);
1113 case '.': /* var_or_func_tail -> '.' NAME */ 1153 while (ls->token == AND || ls->token == OR) {
1114 next(ls); 1154 OpCode op = (ls->token == AND) ? ONFJMP : ONTJMP;
1115 lua_pushvar(ls, v); /* `v' must be on stack */ 1155 int pc;
1116 v->k = VDOT; 1156 lua_pushvar(ls, v);
1117 v->info = checkname(ls); 1157 next(ls);
1118 break; 1158 pc = SaveWordPop(ls);
1119 1159 arith_exp(ls, v);
1120 case '[': /* var_or_func_tail -> '[' exp1 ']' */ 1160 lua_pushvar(ls, v);
1121 next(ls); 1161 fix_jump(ls, pc, op, ls->fs->pc);
1122 lua_pushvar(ls, v); /* `v' must be on stack */
1123 exp1(ls);
1124 check(ls, ']');
1125 v->k = VINDEXED;
1126 break;
1127
1128 case ':': /* var_or_func_tail -> ':' NAME funcparams */
1129 next(ls);
1130 lua_pushvar(ls, v); /* `v' must be on stack */
1131 code_oparg(ls, PUSHSELF, checkname(ls), 1);
1132 v->k = VEXP;
1133 v->info = funcparams(ls, 1);
1134 break;
1135
1136 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
1137 lua_pushvar(ls, v); /* `v' must be on stack */
1138 v->k = VEXP;
1139 v->info = funcparams(ls, 0);
1140 break;
1141
1142 default: return; /* should be follow... */
1143 }
1144 } 1162 }
1145} 1163}
1146 1164
1147static int funcparams (LexState *ls, int slf) {
1148 FuncState *fs = ls->fs;
1149 int slevel = fs->stacksize - slf - 1; /* where is func in the stack */
1150 switch (ls->token) {
1151 case '(': { /* funcparams -> '(' explist ')' */
1152 int line = ls->linenumber;
1153 listdesc e;
1154 next(ls);
1155 explist(ls, &e);
1156 check_match(ls, ')', '(', line);
1157 close_exp(ls, e.pc, MULT_RET); /* close 1 for old semantics */
1158 break;
1159 }
1160 1165
1161 case '{': /* funcparams -> constructor */ 1166/* }==================================================================== */
1162 constructor(ls);
1163 break;
1164 1167
1165 case STRING: /* funcparams -> STRING */
1166 code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before `next' */
1167 next(ls);
1168 break;
1169 1168
1170 default: 1169/*
1171 luaX_error(ls, "function arguments expected"); 1170** {======================================================================
1172 break; 1171** Rules for Statements
1173 } 1172** =======================================================================
1174 code_byte(ls, CALL); 1173*/
1175 code_byte(ls, 0); /* save space for nresult */
1176 code_byte(ls, (Byte)slevel);
1177 fs->stacksize = slevel; /* call will remove func and params */
1178 return fs->pc-1;
1179}
1180 1174
1181static void explist (LexState *ls, listdesc *d) {
1182 switch (ls->token) {
1183 case ELSE: case ELSEIF: case END: case UNTIL:
1184 case EOS: case ';': case ')':
1185 d->pc = 0;
1186 d->n = 0;
1187 break;
1188 1175
1189 default: 1176static void block (LexState *ls) {
1190 explist1(ls, d); 1177 /* block -> chunk */
1191 } 1178 FuncState *fs = ls->fs;
1179 int nlocalvar = fs->nlocalvar;
1180 chunk(ls);
1181 adjuststack(ls, fs->nlocalvar - nlocalvar);
1182 for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--)
1183 luaI_unregisterlocalvar(ls, fs->lastsetline);
1192} 1184}
1193 1185
1194static void explist1 (LexState *ls, listdesc *d) { 1186
1195 vardesc v; 1187static int assignment (LexState *ls, vardesc *v, int nvars) {
1196 exp0(ls, &v); 1188 int left = 0;
1197 d->n = 1; 1189 checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");
1198 while (ls->token == ',') { 1190 unloaddot(ls, v);
1199 d->n++; 1191 if (ls->token == ',') { /* assignment -> ',' NAME assignment */
1200 lua_pushvar(ls, &v); 1192 vardesc nv;
1201 next(ls); 1193 next(ls);
1202 exp0(ls, &v); 1194 var_or_func(ls, &nv);
1195 if (nv.k == VEXP)
1196 luaX_error(ls, "syntax error");
1197 left = assignment(ls, &nv, nvars+1);
1203 } 1198 }
1204 if (v.k == VEXP) 1199 else { /* assignment -> '=' explist1 */
1205 d->pc = v.info; 1200 listdesc d;
1206 else { 1201 if (ls->token != '=')
1207 lua_pushvar(ls, &v); 1202 error_unexpected(ls);
1208 d->pc = 0; 1203 next(ls);
1204 explist1(ls, &d);
1205 adjust_mult_assign(ls, nvars, &d);
1206 }
1207 if (v->k != VINDEXED || left+(nvars-1) == 0) {
1208 /* global/local var or indexed var without values in between */
1209 storevar(ls, v);
1210 }
1211 else { /* indexed var with values in between*/
1212 code_setname(ls, v);
1213 code_oparg(ls, SETTABLE, left+(nvars-1), -1);
1214 left += 2; /* table&index are not popped, because they aren't on top */
1209 } 1215 }
1216 return left;
1210} 1217}
1211 1218
1212static void parlist (LexState *ls) {
1213 int nparams = 0;
1214 int dots = 0;
1215 switch (ls->token) {
1216 case DOTS: /* parlist -> DOTS */
1217 next(ls);
1218 dots = 1;
1219 break;
1220 1219
1221 case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */ 1220static void whilestat (LexState *ls, int line) {
1222 init: 1221 /* whilestat -> WHILE cond DO block END */
1223 store_localvar(ls, str_checkname(ls), nparams++); 1222 FuncState *fs = ls->fs;
1224 if (ls->token == ',') { 1223 TProtoFunc *f = fs->f;
1225 next(ls); 1224 int while_init = fs->pc;
1226 switch (ls->token) { 1225 int cond_end, cond_size;
1227 case DOTS: /* tailparlist -> DOTS */ 1226 next(ls);
1228 next(ls); 1227 cond_end = cond(ls);
1229 dots = 1; 1228 check(ls, DO);
1230 break; 1229 block(ls);
1231 1230 check_match(ls, END, WHILE, line);
1232 case NAME: /* tailparlist -> NAME [',' tailparlist] */ 1231 cond_size = cond_end-while_init;
1233 goto init; 1232 check_pc(ls, cond_size);
1234 1233 memcpy(f->code+fs->pc, f->code+while_init, cond_size);
1235 default: luaX_error(ls, "NAME or `...' expected"); 1234 luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init);
1236 } 1235 while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size);
1237 } 1236 fix_upjmp(ls, IFTUPJMP, while_init);
1238 break; 1237}
1239 1238
1240 case ')': break; /* parlist -> empty */
1241 1239
1242 default: luaX_error(ls, "NAME or `...' expected"); 1240static void repeatstat (LexState *ls, int line) {
1243 } 1241 /* repeatstat -> REPEAT block UNTIL exp1 */
1244 code_args(ls, nparams, dots); 1242 FuncState *fs = ls->fs;
1243 int repeat_init = fs->pc;
1244 next(ls);
1245 block(ls);
1246 check_match(ls, UNTIL, REPEAT, line);
1247 exp1(ls);
1248 fix_upjmp(ls, IFFUPJMP, repeat_init);
1249 deltastack(ls, -1); /* pops condition */
1245} 1250}
1246 1251
1252
1247static int localnamelist (LexState *ls) { 1253static int localnamelist (LexState *ls) {
1248 /* localnamelist -> NAME {',' NAME} */ 1254 /* localnamelist -> NAME {',' NAME} */
1249 int i = 1; 1255 int i = 1;
@@ -1255,6 +1261,7 @@ static int localnamelist (LexState *ls) {
1255 return i; 1261 return i;
1256} 1262}
1257 1263
1264
1258static void decinit (LexState *ls, listdesc *d) { 1265static void decinit (LexState *ls, listdesc *d) {
1259 /* decinit -> ['=' explist1] */ 1266 /* decinit -> ['=' explist1] */
1260 if (ls->token == '=') { 1267 if (ls->token == '=') {
@@ -1268,156 +1275,212 @@ static void decinit (LexState *ls, listdesc *d) {
1268} 1275}
1269 1276
1270 1277
1271static int assignment (LexState *ls, vardesc *v, int nvars) { 1278static void localstat (LexState *ls) {
1272 int left = 0; 1279 /* stat -> LOCAL localnamelist decinit */
1273 checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); 1280 FuncState *fs = ls->fs;
1274 unloaddot(ls, v); 1281 listdesc d;
1275 if (ls->token == ',') { /* assignment -> ',' NAME assignment */ 1282 int nvars;
1276 vardesc nv; 1283 check_debugline(ls);
1284 next(ls);
1285 nvars = localnamelist(ls);
1286 decinit(ls, &d);
1287 adjustlocalvars(ls, nvars, fs->lastsetline);
1288 adjust_mult_assign(ls, nvars, &d);
1289}
1290
1291
1292static int funcname (LexState *ls, vardesc *v) {
1293 /* funcname -> NAME [':' NAME | '.' NAME] */
1294 int needself = 0;
1295 singlevar(ls, str_checkname(ls), v, 0);
1296 if (ls->token == ':' || ls->token == '.') {
1297 needself = (ls->token == ':');
1277 next(ls); 1298 next(ls);
1278 var_or_func(ls, &nv); 1299 lua_pushvar(ls, v);
1279 if (nv.k == VEXP) 1300 code_constant(ls, checkname(ls));
1280 luaX_error(ls, "syntax error"); 1301 v->k = VINDEXED;
1281 left = assignment(ls, &nv, nvars+1);
1282 } 1302 }
1283 else { /* assignment -> '=' explist1 */ 1303 return needself;
1284 listdesc d; 1304}
1285 if (ls->token != '=') 1305
1286 error_unexpected(ls); 1306
1287 next(ls); 1307static int funcstat (LexState *ls, int line) {
1288 explist1(ls, &d); 1308 /* funcstat -> FUNCTION funcname body */
1289 adjust_mult_assign(ls, nvars, &d); 1309 int needself;
1310 vardesc v;
1311 if (ls->fs->prev) /* inside other function? */
1312 return 0;
1313 check_debugline(ls);
1314 next(ls);
1315 needself = funcname(ls, &v);
1316 body(ls, needself, line);
1317 storevar(ls, &v);
1318 return 1;
1319}
1320
1321
1322static void namestat (LexState *ls) {
1323 /* stat -> func | ['%'] NAME assignment */
1324 vardesc v;
1325 check_debugline(ls);
1326 var_or_func(ls, &v);
1327 if (v.k == VEXP) { /* stat -> func */
1328 if (v.info == 0) /* is just an upper value? */
1329 luaX_error(ls, "syntax error");
1330 close_exp(ls, v.info, 0);
1290 } 1331 }
1291 if (v->k != VINDEXED || left+(nvars-1) == 0) { 1332 else { /* stat -> ['%'] NAME assignment */
1292 /* global/local var or indexed var without values in between */ 1333 int left = assignment(ls, &v, 1);
1293 storevar(ls, v); 1334 adjuststack(ls, left); /* remove eventual garbage left on stack */
1294 } 1335 }
1295 else { /* indexed var with values in between*/ 1336}
1296 code_oparg(ls, SETTABLE, left+(nvars-1), -1); 1337
1297 left += 2; /* table&index are not popped, because they aren't on top */ 1338
1339static void ifpart (LexState *ls, int line) {
1340 /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
1341 int c;
1342 int e;
1343 next(ls); /* skip IF or ELSEIF */
1344 c = cond(ls);
1345 check(ls, THEN);
1346 block(ls);
1347 e = SaveWord(ls);
1348 if (ls->token == ELSEIF)
1349 ifpart(ls, line);
1350 else {
1351 if (optional(ls, ELSE))
1352 block(ls);
1353 check_match(ls, END, IF, line);
1298 } 1354 }
1299 return left; 1355 codeIf(ls, c, e);
1300} 1356}
1301 1357
1302 1358
1303static void constructor (LexState *ls) { 1359static int stat (LexState *ls) {
1304 /* constructor -> '{' part [';' part] '}' */ 1360 int line = ls->linenumber; /* may be needed for error messages */
1305 int line = ls->linenumber; 1361 switch (ls->token) {
1306 int pc = SaveWord(ls); 1362 case IF: /* stat -> IF ifpart END */
1307 int nelems; 1363 ifpart(ls, line);
1308 constdesc cd; 1364 return 1;
1309 deltastack(ls, 1); 1365
1310 check(ls, '{'); 1366 case WHILE: /* stat -> whilestat */
1311 part(ls, &cd); 1367 whilestat(ls, line);
1312 nelems = cd.n; 1368 return 1;
1313 if (ls->token == ';') { 1369
1314 constdesc other_cd; 1370 case DO: { /* stat -> DO block END */
1315 next(ls); 1371 next(ls);
1316 part(ls, &other_cd); 1372 block(ls);
1317 if (cd.k == other_cd.k) /* repeated parts? */ 1373 check_match(ls, END, DO, line);
1318 luaX_error(ls, "invalid constructor syntax"); 1374 return 1;
1319 nelems += other_cd.n; 1375 }
1376
1377 case REPEAT: /* stat -> repeatstat */
1378 repeatstat(ls, line);
1379 return 1;
1380
1381 case FUNCTION: /* stat -> funcstat */
1382 return funcstat(ls, line);
1383
1384 case LOCAL: /* stat -> localstat */
1385 localstat(ls);
1386 return 1;
1387
1388 case NAME: case '%': /* stat -> namestat */
1389 namestat(ls);
1390 return 1;
1391
1392 case RETURN: case ';': case ELSE: case ELSEIF:
1393 case END: case UNTIL: case EOS: /* 'stat' follow */
1394 return 0;
1395
1396 default:
1397 error_unexpected(ls);
1398 return 0; /* to avoid warnings */
1320 } 1399 }
1321 check_match(ls, '}', '{', line);
1322 fix_opcode(ls, pc, CREATEARRAY, nelems);
1323} 1400}
1324 1401
1325static void part (LexState *ls, constdesc *cd) { 1402
1403static void parlist (LexState *ls) {
1404 int nparams = 0;
1405 int dots = 0;
1326 switch (ls->token) { 1406 switch (ls->token) {
1327 case ';': case '}': /* part -> empty */ 1407 case DOTS: /* parlist -> DOTS */
1328 cd->n = 0; 1408 next(ls);
1329 cd->k = ls->token; 1409 dots = 1;
1330 return; 1410 break;
1331 1411
1332 case NAME: { 1412 case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */
1333 vardesc v; 1413 init:
1334 exp0(ls, &v); 1414 store_localvar(ls, str_checkname(ls), nparams++);
1335 if (ls->token == '=') { 1415 if (ls->token == ',') {
1336 switch (v.k) { 1416 next(ls);
1337 case VGLOBAL: 1417 switch (ls->token) {
1338 code_constant(ls, v.info); 1418 case DOTS: /* tailparlist -> DOTS */
1339 break; 1419 next(ls);
1340 case VLOCAL: 1420 dots = 1;
1341 code_string(ls, ls->fs->localvar[v.info]);
1342 break; 1421 break;
1343 default: 1422
1344 error_unexpected(ls); 1423 case NAME: /* tailparlist -> NAME [',' tailparlist] */
1424 goto init;
1425
1426 default: luaX_error(ls, "NAME or `...' expected");
1345 } 1427 }
1346 next(ls);
1347 exp1(ls);
1348 cd->n = recfields(ls);
1349 cd->k = 1; /* record */
1350 }
1351 else {
1352 lua_pushvar(ls, &v);
1353 cd->n = listfields(ls);
1354 cd->k = 0; /* list */
1355 } 1428 }
1356 break; 1429 break;
1357 }
1358 1430
1359 case '[': /* part -> recfield recfields */ 1431 case ')': break; /* parlist -> empty */
1360 recfield(ls);
1361 cd->n = recfields(ls);
1362 cd->k = 1; /* record */
1363 break;
1364 1432
1365 default: /* part -> exp1 listfields */ 1433 default: luaX_error(ls, "NAME or `...' expected");
1366 exp1(ls);
1367 cd->n = listfields(ls);
1368 cd->k = 0; /* list */
1369 break;
1370 } 1434 }
1435 code_args(ls, nparams, dots);
1371} 1436}
1372 1437
1373static int recfields (LexState *ls) { 1438
1374 /* recfields -> { ',' recfield } [','] */ 1439static void body (LexState *ls, int needself, int line) {
1375 int n = 1; /* one has been read before */ 1440 /* body -> '(' parlist ')' chunk END */
1376 while (ls->token == ',') { 1441 FuncState newfs;
1377 next(ls); 1442 init_state(ls, &newfs, ls->fs->f->source);
1378 if (ls->token == ';' || ls->token == '}') 1443 newfs.f->lineDefined = line;
1379 break; 1444 check(ls, '(');
1380 recfield(ls); 1445 if (needself)
1381 n++; 1446 add_localvar(ls, luaS_newfixed(ls->L, "self"));
1382 if (n%RFIELDS_PER_FLUSH == 0) 1447 parlist(ls);
1383 flush_record(ls, RFIELDS_PER_FLUSH); 1448 check(ls, ')');
1384 } 1449 chunk(ls);
1385 flush_record(ls, n%RFIELDS_PER_FLUSH); 1450 check_match(ls, END, FUNCTION, line);
1386 return n; 1451 close_func(ls);
1452 func_onstack(ls, &newfs);
1387} 1453}
1388 1454
1389static int listfields (LexState *ls) { 1455
1390 /* listfields -> { ',' exp1 } [','] */ 1456static void ret (LexState *ls) {
1391 int n = 1; /* one has been read before */ 1457 /* ret -> [RETURN explist sc] */
1392 while (ls->token == ',') { 1458 if (optional(ls, RETURN)) {
1393 next(ls); 1459 listdesc e;
1394 if (ls->token == ';' || ls->token == '}') 1460 check_debugline(ls);
1395 break; 1461 explist(ls, &e);
1396 exp1(ls); 1462 if (e.pc > 0) { /* expression is an open function call? */
1397 n++; 1463 Byte *code = ls->fs->f->code;
1398 if (n%LFIELDS_PER_FLUSH == 0) 1464 code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */
1399 flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); 1465 code[e.pc-1] = (Byte)ls->fs->nlocalvar;
1466 }
1467 else
1468 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
1469 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
1470 optional(ls, ';');
1400 } 1471 }
1401 flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
1402 return n;
1403} 1472}
1404 1473
1405static void recfield (LexState *ls) { 1474/* }====================================================================== */
1406 /* recfield -> (NAME | '['exp1']') = exp1 */
1407 switch (ls->token) {
1408 case NAME:
1409 code_constant(ls, checkname(ls));
1410 break;
1411 1475
1412 case '[':
1413 next(ls);
1414 exp1(ls);
1415 check(ls, ']');
1416 break;
1417 1476
1418 default: luaX_error(ls, "NAME or `[' expected"); 1477static void chunk (LexState *ls) {
1478 /* chunk -> { stat [;] } ret */
1479 while (stat(ls)) {
1480 LUA_ASSERT(ls->L, ls->fs->stacksize == ls->fs->nlocalvar,
1481 "stack size != # local vars");
1482 optional(ls, ';');
1419 } 1483 }
1420 check(ls, '='); 1484 ret(ls); /* optional return */
1421 exp1(ls);
1422} 1485}
1423 1486
diff --git a/lvm.c b/lvm.c
index 45bc6616..e2da0801 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.75 1999/12/23 18:19:57 roberto Exp roberto $ 2** $Id: lvm.c,v 1.76 1999/12/27 17:33:22 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -12,6 +12,7 @@
12#define LUA_REENTRANT 12#define LUA_REENTRANT
13 13
14#include "lauxlib.h" 14#include "lauxlib.h"
15#include "ldebug.h"
15#include "ldo.h" 16#include "ldo.h"
16#include "lfunc.h" 17#include "lfunc.h"
17#include "lgc.h" 18#include "lgc.h"
@@ -33,7 +34,7 @@
33 34
34 35
35/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */ 36/* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
36#define EXTRA_STACK 5 37#define EXTRA_STACK 6
37 38
38 39
39 40
@@ -105,7 +106,7 @@ void luaV_gettable (lua_State *L) {
105 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ 106 if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
106 im = luaT_getimbyObj(L, table, IM_GETTABLE); 107 im = luaT_getimbyObj(L, table, IM_GETTABLE);
107 if (ttype(im) == LUA_T_NIL) 108 if (ttype(im) == LUA_T_NIL)
108 lua_error(L, "indexed expression not a table"); 109 luaG_indexerror(L, table);
109 } 110 }
110 else { /* object is a table... */ 111 else { /* object is a table... */
111 int tg = table->value.a->htag; 112 int tg = table->value.a->htag;
@@ -138,7 +139,7 @@ void luaV_settable (lua_State *L, StkId t) {
138 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get `settable' method */ 139 if (ttype(t) != LUA_T_ARRAY) { /* not a table, get `settable' method */
139 im = luaT_getimbyObj(L, t, IM_SETTABLE); 140 im = luaT_getimbyObj(L, t, IM_SETTABLE);
140 if (ttype(im) == LUA_T_NIL) 141 if (ttype(im) == LUA_T_NIL)
141 lua_error(L, "indexed expression not a table"); 142 luaG_indexerror(L, t);
142 } 143 }
143 else { /* object is a table... */ 144 else { /* object is a table... */
144 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE); 145 im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
@@ -587,17 +588,28 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
587 588
588 case SETLINEW: aux += highbyte(L, *pc++); 589 case SETLINEW: aux += highbyte(L, *pc++);
589 case SETLINE: aux += *pc++; 590 case SETLINE: aux += *pc++;
590 L->top = top; 591 if ((base-2)->ttype != LUA_T_LINE) {
591 if ((base-1)->ttype != LUA_T_LINE) { 592 /* open space for LINE and NAME values */
592 /* open space for LINE value */ 593 int i = top-base;
593 luaD_openstack(L, base); 594 while (i--) base[i+2] = base[i];
594 base->ttype = LUA_T_LINE; 595 base += 2;
595 base++; 596 top += 2;
596 top++; 597 (base-1)->ttype = LUA_T_NIL; /* initial value for NAME */
598 (base-2)->ttype = LUA_T_LINE;
597 } 599 }
598 (base-1)->value.i = aux; 600 (base-2)->value.i = aux;
599 if (L->linehook) 601 if (L->linehook) {
602 L->top = top;
600 luaD_lineHook(L, aux); 603 luaD_lineHook(L, aux);
604 }
605 break;
606
607 case SETNAMEW: aux += highbyte(L, *pc++);
608 case SETNAME: aux += *pc++;
609 if ((base-2)->ttype == LUA_T_LINE) { /* function has debug info? */
610 (base-1)->ttype = -(*pc++);
611 (base-1)->value.i = aux;
612 }
601 break; 613 break;
602 614
603 case LONGARGW: aux += highbyte(L, *pc++); 615 case LONGARGW: aux += highbyte(L, *pc++);