aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-03 15:53:17 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-03-03 15:53:17 -0300
commitd1ea38580ae35a3a34e7122c41682af7f9901030 (patch)
treece7fa1568be9eb757805966b77ea1eac2bc604f6
parent3c9d999424520c809e05bee11d81788b488434f6 (diff)
downloadlua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.gz
lua-d1ea38580ae35a3a34e7122c41682af7f9901030.tar.bz2
lua-d1ea38580ae35a3a34e7122c41682af7f9901030.zip
change of code generation design (independent functions for each opcode)
-rw-r--r--lcode.c223
-rw-r--r--lcode.h25
-rw-r--r--lopcodes.h7
-rw-r--r--lparser.c85
-rw-r--r--lparser.h28
5 files changed, 180 insertions, 188 deletions
diff --git a/lcode.c b/lcode.c
index cf9aee47..2d9c2285 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $ 2** $Id: lcode.c,v 1.3 2000/03/03 14:58:26 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,12 +20,10 @@ void luaK_error (LexState *ls, const char *msg) {
20} 20}
21 21
22 22
23static Instruction *last_i (FuncState *fs) { 23static Instruction *last_i (LexState *ls, expdesc *v) {
24 static Instruction dummy = SET_OPCODE(0, ENDCODE); 24 FuncState *fs = ls->fs;
25 if (fs->last_pc < 0) 25 int last_pc = (v->info != NOJUMPS) ? v->info : fs->pc-1;
26 return &dummy; 26 return &fs->f->code[last_pc];
27 else
28 return &fs->f->code[fs->last_pc];
29} 27}
30 28
31 29
@@ -37,58 +35,64 @@ int luaK_primitivecode (LexState *ls, Instruction i) {
37} 35}
38 36
39 37
38static void luaK_minus (LexState *ls, expdesc *v) {
39 Instruction *last = last_i(ls, v);
40 switch(GET_OPCODE(*last)) {
41 case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); return;
42 case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); return;
43 case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); return;
44 default: luaK_primitivecode(ls, CREATE_0(MINUSOP));
45 }
46}
40 47
41int luaK_code (LexState *ls, Instruction i) {
42 FuncState *fs = ls->fs;
43 Instruction *last = last_i(fs);
44 switch (GET_OPCODE(i)) {
45
46 case MINUSOP:
47 switch(GET_OPCODE(*last)) {
48 case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break;
49 case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break;
50 case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break;
51 default: fs->last_pc = luaK_primitivecode(ls, i);
52 }
53 break;
54 48
55 case GETTABLE: 49static void luaK_gettable (LexState *ls, expdesc *v) {
56 switch(GET_OPCODE(*last)) { 50 Instruction *last = last_i(ls, v);
57 case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break; 51 luaK_deltastack(ls, -1);
58 default: fs->last_pc = luaK_primitivecode(ls, i); 52 switch(GET_OPCODE(*last)) {
59 } 53 case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
60 break; 54 default: luaK_primitivecode(ls, CREATE_0(GETTABLE));
55 }
56}
61 57
62 case RETCODE:
63 switch(GET_OPCODE(*last)) {
64 case CALL:
65 *last = SET_OPCODE(*last, TAILCALL);
66 *last = SETARG_B(*last, GETARG_U(i));
67 break;
68 default: fs->last_pc = luaK_primitivecode(ls, i);
69 }
70 break;
71 58
72 case ADDOP: 59static void luaK_add (LexState *ls, expdesc *v) {
73 switch(GET_OPCODE(*last)) { 60 Instruction *last = last_i(ls, v);
74 case PUSHINT: *last = SET_OPCODE(*last, ADDI); break; 61 luaK_deltastack(ls, -1);
75 default: fs->last_pc = luaK_primitivecode(ls, i); 62 switch(GET_OPCODE(*last)) {
76 } 63 case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
77 break; 64 default: luaK_primitivecode(ls, CREATE_0(ADDOP));
65 }
66}
67
78 68
79 case SUBOP: 69static void luaK_sub (LexState *ls, expdesc *v) {
80 switch(GET_OPCODE(*last)) { 70 Instruction *last = last_i(ls, v);
81 case PUSHINT: 71 luaK_deltastack(ls, -1);
82 *last = SET_OPCODE(*last, ADDI); 72 switch(GET_OPCODE(*last)) {
83 *last = SETARG_S(*last, -GETARG_S(*last)); 73 case PUSHINT:
84 break; 74 *last = SET_OPCODE(*last, ADDI);
85 default: fs->last_pc = luaK_primitivecode(ls, i); 75 *last = SETARG_S(*last, -GETARG_S(*last));
86 }
87 break; 76 break;
77 default: luaK_primitivecode(ls, CREATE_0(SUBOP));
78 }
79}
88 80
89 default: fs->last_pc = luaK_primitivecode(ls, i); 81
82void luaK_retcode (LexState *ls, int nlocals, listdesc *e) {
83 if (e->n > 0 && luaK_iscall(ls, e->info)) {
84 Instruction *last = &ls->fs->f->code[ls->fs->pc-1];
85 *last = SET_OPCODE(*last, TAILCALL);
86 *last = SETARG_B(*last, nlocals);
90 } 87 }
91 return fs->last_pc; 88 else
89 luaK_U(ls, RETCODE, nlocals, 0);
90}
91
92
93int luaK_code (LexState *ls, Instruction i, int delta) {
94 luaK_deltastack(ls, delta);
95 return luaK_primitivecode(ls, i);
92} 96}
93 97
94 98
@@ -97,7 +101,6 @@ void luaK_fixjump (LexState *ls, int pc, int dest) {
97 Instruction *jmp = &fs->f->code[pc]; 101 Instruction *jmp = &fs->f->code[pc];
98 /* jump is relative to position following jump instruction */ 102 /* jump is relative to position following jump instruction */
99 *jmp = SETARG_S(*jmp, dest-(pc+1)); 103 *jmp = SETARG_S(*jmp, dest-(pc+1));
100 fs->last_pc = pc;
101} 104}
102 105
103 106
@@ -112,38 +115,8 @@ void luaK_deltastack (LexState *ls, int delta) {
112} 115}
113 116
114 117
115static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { 118void luaK_kstr (LexState *ls, int c) {
116 luaK_deltastack(ls, delta); 119 luaK_U(ls, PUSHSTRING, c, 1);
117 return luaK_code(ls, SET_OPCODE(i, op));
118}
119
120
121int luaK_0 (LexState *ls, OpCode op, int delta) {
122 return aux_code(ls, op, 0, delta);
123}
124
125
126int luaK_U (LexState *ls, OpCode op, int u, int delta) {
127 Instruction i = SETARG_U(0, u);
128 return aux_code(ls, op, i, delta);
129}
130
131
132int luaK_S (LexState *ls, OpCode op, int s, int delta) {
133 Instruction i = SETARG_S(0, s);
134 return aux_code(ls, op, i, delta);
135}
136
137
138int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) {
139 Instruction i = SETARG_A(0, a);
140 i = SETARG_B(i, b);
141 return aux_code(ls, op, i, delta);
142}
143
144
145int luaK_kstr (LexState *ls, int c) {
146 return luaK_U(ls, PUSHSTRING, c, 1);
147} 120}
148 121
149 122
@@ -166,37 +139,40 @@ static int real_constant (LexState *ls, real r) {
166} 139}
167 140
168 141
169int luaK_number (LexState *ls, real f) { 142void luaK_number (LexState *ls, real f) {
170 if (f <= (real)MAXARG_S && (int)f == f) 143 if (f <= (real)MAXARG_S && (int)f == f)
171 return luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ 144 luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */
172 else 145 else
173 return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); 146 luaK_U(ls, PUSHNUM, real_constant(ls, f), 1);
174} 147}
175 148
176 149
177int luaK_adjuststack (LexState *ls, int n) { 150void luaK_adjuststack (LexState *ls, int n) {
178 if (n > 0) 151 if (n > 0)
179 return luaK_U(ls, POP, n, -n); 152 luaK_U(ls, POP, n, -n);
180 else if (n < 0) 153 else if (n < 0)
181 return luaK_U(ls, PUSHNIL, (-n)-1, -n); 154 luaK_U(ls, PUSHNIL, (-n)-1, -n);
182 else return 0;
183} 155}
184 156
185 157
186int luaK_iscall (LexState *ls, int pc) { 158int luaK_iscall (LexState *ls, int hasjumps) {
187 return (GET_OPCODE(ls->fs->f->code[pc]) == CALL); 159 if (hasjumps) return 0; /* a call cannot have internal jumps */
160 else /* check whether last instruction is a function call */
161 return (GET_OPCODE(ls->fs->f->code[ls->fs->pc-1]) == CALL);
188} 162}
189 163
190 164
191void luaK_setcallreturns (LexState *ls, int pc, int nresults) { 165void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults) {
192 if (luaK_iscall(ls, pc)) { /* expression is a function call? */ 166 if (!hasjumps) { /* if `hasjumps' cannot be a function call */
193 Instruction *i = &ls->fs->f->code[pc]; 167 Instruction *i = &ls->fs->f->code[ls->fs->pc-1];
194 int old_nresults = GETARG_B(*i); 168 if (GET_OPCODE(*i) == CALL) { /* expression is a function call? */
195 if (old_nresults != MULT_RET) 169 int old_nresults = GETARG_B(*i);
196 luaK_deltastack(ls, -old_nresults); /* pop old nresults */ 170 if (old_nresults != MULT_RET)
197 *i = SETARG_B(*i, nresults); /* set nresults */ 171 luaK_deltastack(ls, -old_nresults); /* pop old nresults */
198 if (nresults != MULT_RET) 172 *i = SETARG_B(*i, nresults); /* set nresults */
199 luaK_deltastack(ls, nresults); /* push results */ 173 if (nresults != MULT_RET)
174 luaK_deltastack(ls, nresults); /* push results */
175 }
200 } 176 }
201} 177}
202 178
@@ -209,20 +185,21 @@ static void assertglobal (LexState *ls, int index) {
209void luaK_2stack (LexState *ls, expdesc *var) { 185void luaK_2stack (LexState *ls, expdesc *var) {
210 switch (var->k) { 186 switch (var->k) {
211 case VLOCAL: 187 case VLOCAL:
212 var->info = luaK_U(ls, PUSHLOCAL, var->info, 1); 188 luaK_U(ls, PUSHLOCAL, var->info, 1);
213 break; 189 break;
214 case VGLOBAL: 190 case VGLOBAL:
191 luaK_U(ls, GETGLOBAL, var->info, 1);
215 assertglobal(ls, var->info); /* make sure that there is a global */ 192 assertglobal(ls, var->info); /* make sure that there is a global */
216 var->info = luaK_U(ls, GETGLOBAL, var->info, 1);
217 break; 193 break;
218 case VINDEXED: 194 case VINDEXED:
219 var->info = luaK_0(ls, GETTABLE, -1); 195 luaK_gettable(ls, var);
220 break; 196 break;
221 case VEXP: 197 case VEXP:
222 luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ 198 luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */
223 break; 199 return; /* does not change var->info */
224 } 200 }
225 var->k = VEXP; 201 var->k = VEXP;
202 var->info = NOJUMPS;
226} 203}
227 204
228 205
@@ -246,10 +223,9 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
246 223
247void luaK_prefix (LexState *ls, int op, expdesc *v) { 224void luaK_prefix (LexState *ls, int op, expdesc *v) {
248 luaK_2stack(ls, v); 225 luaK_2stack(ls, v);
249 if (op == '-') 226 if (op == '-') luaK_minus(ls, v);
250 v->info = luaK_0(ls, MINUSOP, 0); 227 else luaK_0(ls, NOTOP, 0);
251 else 228 v->info = NOJUMPS;
252 v->info = luaK_0(ls, NOTOP, 0);
253} 229}
254 230
255 231
@@ -267,19 +243,20 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
267 switch (op) { 243 switch (op) {
268 case AND: case OR: 244 case AND: case OR:
269 luaK_fixjump(ls, v1->info, ls->fs->pc); 245 luaK_fixjump(ls, v1->info, ls->fs->pc);
270 break; 246 return; /* keep v1->info != NOJUMPS */
271 case '+': v1->info = luaK_0(ls, ADDOP, -1); break; 247 case '+': luaK_add(ls, v2); break;
272 case '-': v1->info = luaK_0(ls, SUBOP, -1); break; 248 case '-': luaK_sub(ls, v2); break;
273 case '*': v1->info = luaK_0(ls, MULTOP, -1); break; 249 case '*': luaK_0(ls, MULTOP, -1); break;
274 case '/': v1->info = luaK_0(ls, DIVOP, -1); break; 250 case '/': luaK_0(ls, DIVOP, -1); break;
275 case '^': v1->info = luaK_0(ls, POWOP, -1); break; 251 case '^': luaK_0(ls, POWOP, -1); break;
276 case CONC: v1->info = luaK_0(ls, CONCOP, -1); break; 252 case CONC: luaK_0(ls, CONCOP, -1); break;
277 case EQ: v1->info = luaK_0(ls, EQOP, -1); break; 253 case EQ: luaK_0(ls, EQOP, -1); break;
278 case NE: v1->info = luaK_0(ls, NEQOP, -1); break; 254 case NE: luaK_0(ls, NEQOP, -1); break;
279 case '>': v1->info = luaK_0(ls, GTOP, -1); break; 255 case '>': luaK_0(ls, GTOP, -1); break;
280 case '<': v1->info = luaK_0(ls, LTOP, -1); break; 256 case '<': luaK_0(ls, LTOP, -1); break;
281 case GE: v1->info = luaK_0(ls, GEOP, -1); break; 257 case GE: luaK_0(ls, GEOP, -1); break;
282 case LE: v1->info = luaK_0(ls, LEOP, -1); break; 258 case LE: luaK_0(ls, LEOP, -1); break;
283 } 259 }
260 v1->info = NOJUMPS;
284} 261}
285 262
diff --git a/lcode.h b/lcode.h
index 23a26dc7..0ba83766 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.1 2000/02/22 13:31:19 roberto Exp roberto $ 2** $Id: lcode.h,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,20 +13,23 @@
13#include "lparser.h" 13#include "lparser.h"
14 14
15 15
16#define luaK_0(ls,o,d) luaK_code(ls, CREATE_0(o), d)
17#define luaK_U(ls,o,u,d) luaK_code(ls, CREATE_U(o,u), d)
18#define luaK_S(ls,o,s,d) luaK_code(ls, CREATE_S(o,s), d)
19#define luaK_AB(ls,o,a,b,d) luaK_code(ls, CREATE_AB(o,a,b), d)
20
21
16void luaK_error (LexState *ls, const char *msg); 22void luaK_error (LexState *ls, const char *msg);
17int luaK_primitivecode (LexState *ls, Instruction i); 23int luaK_primitivecode (LexState *ls, Instruction i);
18int luaK_code (LexState *ls, Instruction i); 24int luaK_code (LexState *ls, Instruction i, int delta);
25void luaK_retcode (LexState *ls, int nlocals, listdesc *e);
19void luaK_fixjump (LexState *ls, int pc, int dest); 26void luaK_fixjump (LexState *ls, int pc, int dest);
20void luaK_deltastack (LexState *ls, int delta); 27void luaK_deltastack (LexState *ls, int delta);
21int luaK_0 (LexState *ls, OpCode op, int delta); 28void luaK_kstr (LexState *ls, int c);
22int luaK_U (LexState *ls, OpCode op, int u, int delta); 29void luaK_number (LexState *ls, real f);
23int luaK_S (LexState *ls, OpCode op, int s, int delta); 30void luaK_adjuststack (LexState *ls, int n);
24int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta); 31int luaK_iscall (LexState *ls, int hasjumps);
25int luaK_kstr (LexState *ls, int c); 32void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults);
26int luaK_number (LexState *ls, real f);
27int luaK_adjuststack (LexState *ls, int n);
28int luaK_iscall (LexState *ls, int pc);
29void luaK_setcallreturns (LexState *ls, int pc, int nresults);
30void luaK_2stack (LexState *ls, expdesc *var); 33void luaK_2stack (LexState *ls, expdesc *var);
31void luaK_storevar (LexState *ls, const expdesc *var); 34void luaK_storevar (LexState *ls, const expdesc *var);
32void luaK_prefix (LexState *ls, int op, expdesc *v); 35void luaK_prefix (LexState *ls, int op, expdesc *v);
diff --git a/lopcodes.h b/lopcodes.h
index c822049c..b2819c3b 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.42 2000/03/02 12:32:53 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.43 2000/03/03 14:58:26 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*/
@@ -47,6 +47,11 @@
47#define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) 47#define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16))
48#define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) 48#define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8))
49 49
50#define CREATE_0(o) ((Instruction)(o))
51#define CREATE_U(o,u) ((Instruction)(o) | (Instruction)(u)<<8)
52#define CREATE_S(o,s) ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<8)
53#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<16) \
54 | ((Instruction)(b)<<8))
50 55
51 56
52/* 57/*
diff --git a/lparser.c b/lparser.c
index 1cdc35b6..b13ee9d5 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.61 2000/03/03 12:33:59 roberto Exp roberto $ 2** $Id: lparser.c,v 1.62 2000/03/03 14:58:26 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*/
@@ -23,15 +23,13 @@
23 23
24 24
25/* 25/*
26** Expression List descriptor: 26** check whether arbitrary limits fit in respective opcode types
27** tells number of expressions in the list,
28** and, if last expression is open (a function call),
29** where is the call pc index.
30*/ 27*/
31typedef struct listdesc { 28#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \
32 int n; 29 MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B
33 int pc; /* 0 if last expression is closed */ 30#error invalid limits
34} listdesc; 31#endif
32
35 33
36 34
37/* 35/*
@@ -51,11 +49,11 @@ typedef struct constdesc {
51/* 49/*
52** prototypes for recursive non-terminal functions 50** prototypes for recursive non-terminal functions
53*/ 51*/
54static int body (LexState *ls, int needself, int line); 52static void body (LexState *ls, int needself, int line);
55static void chunk (LexState *ls); 53static void chunk (LexState *ls);
56static int constructor (LexState *ls); 54static void constructor (LexState *ls);
57static void expr (LexState *ls, expdesc *v); 55static void expr (LexState *ls, expdesc *v);
58static void exp1 (LexState *ls); 56static int exp1 (LexState *ls);
59 57
60 58
61static void next (LexState *ls) { 59static void next (LexState *ls) {
@@ -145,8 +143,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) {
145} 143}
146 144
147 145
148static int code_string (LexState *ls, TaggedString *s) { 146static void code_string (LexState *ls, TaggedString *s) {
149 return luaK_kstr(ls, string_constant(ls, ls->fs, s)); 147 luaK_kstr(ls, string_constant(ls, ls->fs, s));
150} 148}
151 149
152 150
@@ -249,18 +247,18 @@ static int indexupvalue (LexState *ls, TaggedString *n) {
249} 247}
250 248
251 249
252static int pushupvalue (LexState *ls, TaggedString *n) { 250static void pushupvalue (LexState *ls, TaggedString *n) {
253 if (ls->fs->prev == NULL) 251 if (ls->fs->prev == NULL)
254 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); 252 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
255 if (aux_localname(ls->fs, n) >= 0) 253 if (aux_localname(ls->fs, n) >= 0)
256 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); 254 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
257 return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); 255 luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
258} 256}
259 257
260 258
261static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { 259static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
262 int diff = d->n - nvars; 260 int diff = d->n - nvars;
263 if (d->n == 0 || !luaK_iscall(ls, d->pc)) { /* list is empty or closed */ 261 if (d->n == 0 || !luaK_iscall(ls, d->info)) { /* list is empty or closed */
264 /* push or pop eventual difference between list lengths */ 262 /* push or pop eventual difference between list lengths */
265 luaK_adjuststack(ls, diff); 263 luaK_adjuststack(ls, diff);
266 } 264 }
@@ -268,10 +266,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
268 diff--; /* do not count function call itself */ 266 diff--; /* do not count function call itself */
269 if (diff <= 0) { /* more variables than values? */ 267 if (diff <= 0) { /* more variables than values? */
270 /* function call must provide extra values */ 268 /* function call must provide extra values */
271 luaK_setcallreturns(ls, d->pc, -diff); 269 luaK_setcallreturns(ls, d->info, -diff);
272 } 270 }
273 else { /* more values than variables */ 271 else { /* more values than variables */
274 luaK_setcallreturns(ls, d->pc, 0); /* call should provide no value */ 272 luaK_setcallreturns(ls, d->info, 0); /* call should provide no value */
275 luaK_adjuststack(ls, diff); /* pop eventual extra values */ 273 luaK_adjuststack(ls, diff); /* pop eventual extra values */
276 } 274 }
277 } 275 }
@@ -308,7 +306,7 @@ static int getvarname (LexState *ls, expdesc *var) {
308} 306}
309 307
310 308
311static int func_onstack (LexState *ls, FuncState *func) { 309static void func_onstack (LexState *ls, FuncState *func) {
312 TProtoFunc *f = ls->fs->f; 310 TProtoFunc *f = ls->fs->f;
313 int i; 311 int i;
314 for (i=0; i<func->nupvalues; i++) 312 for (i=0; i<func->nupvalues; i++)
@@ -317,7 +315,7 @@ static int func_onstack (LexState *ls, FuncState *func) {
317 constantEM, MAXARG_A); 315 constantEM, MAXARG_A);
318 f->kproto[f->nkproto++] = func->f; 316 f->kproto[f->nkproto++] = func->f;
319 luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ 317 luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */
320 return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); 318 luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues);
321} 319}
322 320
323 321
@@ -333,7 +331,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
333 fs->f = f; 331 fs->f = f;
334 f->source = source; 332 f->source = source;
335 fs->pc = 0; 333 fs->pc = 0;
336 fs->last_pc = -1; /* invalid index to signal no last instruction */
337 f->code = NULL; 334 f->code = NULL;
338 f->maxstacksize = 0; 335 f->maxstacksize = 0;
339 f->numparams = 0; /* default for main chunk */ 336 f->numparams = 0; /* default for main chunk */
@@ -395,7 +392,7 @@ static void explist1 (LexState *ls, listdesc *d) {
395 } 392 }
396 luaK_2stack(ls, &v); 393 luaK_2stack(ls, &v);
397 luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ 394 luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */
398 d->pc = v.info; 395 d->info = v.info;
399} 396}
400 397
401 398
@@ -412,7 +409,7 @@ static void explist (LexState *ls, listdesc *d) {
412} 409}
413 410
414 411
415static int funcparams (LexState *ls, int slf) { 412static void funcparams (LexState *ls, int slf) {
416 FuncState *fs = ls->fs; 413 FuncState *fs = ls->fs;
417 int slevel = fs->stacksize - slf - 1; /* where is func in the stack */ 414 int slevel = fs->stacksize - slf - 1; /* where is func in the stack */
418 switch (ls->token) { 415 switch (ls->token) {
@@ -443,7 +440,7 @@ static int funcparams (LexState *ls, int slf) {
443 break; 440 break;
444 } 441 }
445 fs->stacksize = slevel; /* call will remove func and params */ 442 fs->stacksize = slevel; /* call will remove func and params */
446 return luaK_AB(ls, CALL, slevel, 0, 0); 443 luaK_AB(ls, CALL, slevel, 0, 0);
447} 444}
448 445
449 446
@@ -455,14 +452,15 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
455 luaK_2stack(ls, v); /* `v' must be on stack */ 452 luaK_2stack(ls, v); /* `v' must be on stack */
456 luaK_kstr(ls, checkname(ls)); 453 luaK_kstr(ls, checkname(ls));
457 v->k = VINDEXED; 454 v->k = VINDEXED;
455 v->info = NOJUMPS;
458 break; 456 break;
459 457
460 case '[': /* var_or_func_tail -> '[' exp1 ']' */ 458 case '[': /* var_or_func_tail -> '[' exp1 ']' */
461 next(ls); 459 next(ls);
462 luaK_2stack(ls, v); /* `v' must be on stack */ 460 luaK_2stack(ls, v); /* `v' must be on stack */
463 exp1(ls);
464 check(ls, ']');
465 v->k = VINDEXED; 461 v->k = VINDEXED;
462 v->info = exp1(ls);
463 check(ls, ']');
466 break; 464 break;
467 465
468 case ':': { /* var_or_func_tail -> ':' NAME funcparams */ 466 case ':': { /* var_or_func_tail -> ':' NAME funcparams */
@@ -471,15 +469,17 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
471 name = checkname(ls); 469 name = checkname(ls);
472 luaK_2stack(ls, v); /* `v' must be on stack */ 470 luaK_2stack(ls, v); /* `v' must be on stack */
473 luaK_U(ls, PUSHSELF, name, 1); 471 luaK_U(ls, PUSHSELF, name, 1);
472 funcparams(ls, 1);
474 v->k = VEXP; 473 v->k = VEXP;
475 v->info = funcparams(ls, 1); 474 v->info = NOJUMPS;
476 break; 475 break;
477 } 476 }
478 477
479 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ 478 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
480 luaK_2stack(ls, v); /* `v' must be on stack */ 479 luaK_2stack(ls, v); /* `v' must be on stack */
480 funcparams(ls, 0);
481 v->k = VEXP; 481 v->k = VEXP;
482 v->info = funcparams(ls, 0); 482 v->info = NOJUMPS;
483 break; 483 break;
484 484
485 default: return; /* should be follow... */ 485 default: return; /* should be follow... */
@@ -491,8 +491,9 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
491static void var_or_func (LexState *ls, expdesc *v) { 491static void var_or_func (LexState *ls, expdesc *v) {
492 /* var_or_func -> ['%'] NAME var_or_func_tail */ 492 /* var_or_func -> ['%'] NAME var_or_func_tail */
493 if (optional(ls, '%')) { /* upvalue? */ 493 if (optional(ls, '%')) { /* upvalue? */
494 pushupvalue(ls, str_checkname(ls));
494 v->k = VEXP; 495 v->k = VEXP;
495 v->info = pushupvalue(ls, str_checkname(ls)); 496 v->info = NOJUMPS;
496 } 497 }
497 else /* variable name */ 498 else /* variable name */
498 singlevar(ls, str_checkname(ls), v, 0); 499 singlevar(ls, str_checkname(ls), v, 0);
@@ -614,7 +615,7 @@ static void constructor_part (LexState *ls, constdesc *cd) {
614} 615}
615 616
616 617
617static int constructor (LexState *ls) { 618static void constructor (LexState *ls) {
618 /* constructor -> '{' constructor_part [';' constructor_part] '}' */ 619 /* constructor -> '{' constructor_part [';' constructor_part] '}' */
619 int line = ls->linenumber; 620 int line = ls->linenumber;
620 int pc = luaK_U(ls, CREATETABLE, 0, 1); 621 int pc = luaK_U(ls, CREATETABLE, 0, 1);
@@ -634,7 +635,6 @@ static int constructor (LexState *ls) {
634 check_match(ls, '}', '{', line); 635 check_match(ls, '}', '{', line);
635 /* set initial table size */ 636 /* set initial table size */
636 ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); 637 ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems);
637 return pc;
638} 638}
639 639
640/* }====================================================================== */ 640/* }====================================================================== */
@@ -655,28 +655,27 @@ static void simpleexp (LexState *ls, expdesc *v) {
655 case NUMBER: { /* simpleexp -> NUMBER */ 655 case NUMBER: { /* simpleexp -> NUMBER */
656 real r = ls->seminfo.r; 656 real r = ls->seminfo.r;
657 next(ls); 657 next(ls);
658 v->info = luaK_number(ls, r); 658 luaK_number(ls, r);
659 break; 659 break;
660 } 660 }
661 661
662 case STRING: /* simpleexp -> STRING */ 662 case STRING: /* simpleexp -> STRING */
663 /* must use `seminfo' before `next' */ 663 code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */
664 v->info = code_string(ls, ls->seminfo.ts);
665 next(ls); 664 next(ls);
666 break; 665 break;
667 666
668 case NIL: /* simpleexp -> NIL */ 667 case NIL: /* simpleexp -> NIL */
669 v->info = luaK_adjuststack(ls, -1); 668 luaK_adjuststack(ls, -1);
670 next(ls); 669 next(ls);
671 break; 670 break;
672 671
673 case '{': /* simpleexp -> constructor */ 672 case '{': /* simpleexp -> constructor */
674 v->info = constructor(ls); 673 constructor(ls);
675 break; 674 break;
676 675
677 case FUNCTION: /* simpleexp -> FUNCTION body */ 676 case FUNCTION: /* simpleexp -> FUNCTION body */
678 next(ls); 677 next(ls);
679 v->info = body(ls, 0, ls->linenumber); 678 body(ls, 0, ls->linenumber);
680 break; 679 break;
681 680
682 case '(': /* simpleexp -> '(' expr ')' */ 681 case '(': /* simpleexp -> '(' expr ')' */
@@ -694,13 +693,15 @@ static void simpleexp (LexState *ls, expdesc *v) {
694 return; 693 return;
695 } 694 }
696 v->k = VEXP; 695 v->k = VEXP;
696 v->info = NOJUMPS;
697} 697}
698 698
699 699
700static void exp1 (LexState *ls) { 700static int exp1 (LexState *ls) {
701 expdesc v; 701 expdesc v;
702 expr(ls, &v); 702 expr(ls, &v);
703 luaK_2stack(ls, &v); 703 luaK_2stack(ls, &v);
704 return v.info;
704} 705}
705 706
706 707
@@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) {
1052} 1053}
1053 1054
1054 1055
1055static int body (LexState *ls, int needself, int line) { 1056static void body (LexState *ls, int needself, int line) {
1056 /* body -> '(' parlist ')' chunk END */ 1057 /* body -> '(' parlist ')' chunk END */
1057 FuncState new_fs; 1058 FuncState new_fs;
1058 init_state(ls, &new_fs, ls->fs->f->source); 1059 init_state(ls, &new_fs, ls->fs->f->source);
@@ -1065,7 +1066,7 @@ static int body (LexState *ls, int needself, int line) {
1065 chunk(ls); 1066 chunk(ls);
1066 check_match(ls, END, FUNCTION, line); 1067 check_match(ls, END, FUNCTION, line);
1067 close_func(ls); 1068 close_func(ls);
1068 return func_onstack(ls, &new_fs); 1069 func_onstack(ls, &new_fs);
1069} 1070}
1070 1071
1071 1072
@@ -1076,7 +1077,7 @@ static void ret (LexState *ls) {
1076 check_debugline(ls); 1077 check_debugline(ls);
1077 next(ls); 1078 next(ls);
1078 explist(ls, &e); 1079 explist(ls, &e);
1079 luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0); 1080 luaK_retcode(ls, ls->fs->nlocalvar, &e);
1080 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ 1081 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
1081 optional(ls, ';'); 1082 optional(ls, ';');
1082 } 1083 }
diff --git a/lparser.h b/lparser.h
index a3568a6f..a64b8dda 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.7 2000/03/03 12:33:59 roberto Exp roberto $ 2** $Id: lparser.h,v 1.8 2000/03/03 14:58:26 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*/
@@ -8,7 +8,6 @@
8#define lparser_h 8#define lparser_h
9 9
10#include "lobject.h" 10#include "lobject.h"
11#include "lopcodes.h"
12#include "lzio.h" 11#include "lzio.h"
13 12
14 13
@@ -42,21 +41,18 @@
42#endif 41#endif
43 42
44 43
45#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \
46 MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B
47#error invalid limits
48#endif
49
50
51 44
52/* 45/*
53** Expression descriptor 46** Expression descriptor
54*/ 47*/
48
49#define NOJUMPS 0
50
55typedef enum { 51typedef enum {
56 VGLOBAL, /* info is constant index of global name */ 52 VGLOBAL, /* info is constant index of global name */
57 VLOCAL, /* info is stack index */ 53 VLOCAL, /* info is stack index */
58 VINDEXED, /* no info (table and index are on the stack) */ 54 VINDEXED, /* info is info of the index expression */
59 VEXP /* info is pc index of exp main operator */ 55 VEXP /* info is NOJUMPS if exp has no internal jumps */
60} expkind; 56} expkind;
61 57
62typedef struct expdesc { 58typedef struct expdesc {
@@ -65,12 +61,22 @@ typedef struct expdesc {
65} expdesc; 61} expdesc;
66 62
67 63
64/*
65** Expression List descriptor:
66** tells number of expressions in the list,
67** and gives the `info' of last expression.
68*/
69typedef struct listdesc {
70 int n;
71 int info; /* 0 if last expression has no internal jumps */
72} listdesc;
73
74
68/* state needed to generate code for a given function */ 75/* state needed to generate code for a given function */
69typedef struct FuncState { 76typedef struct FuncState {
70 TProtoFunc *f; /* current function header */ 77 TProtoFunc *f; /* current function header */
71 struct FuncState *prev; /* enclosing function */ 78 struct FuncState *prev; /* enclosing function */
72 int pc; /* next position to code */ 79 int pc; /* next position to code */
73 int last_pc; /* last instruction coded (for optimizations) */
74 int stacksize; /* number of values on activation register */ 80 int stacksize; /* number of values on activation register */
75 int nlocalvar; /* number of active local variables */ 81 int nlocalvar; /* number of active local variables */
76 int nupvalues; /* number of upvalues */ 82 int nupvalues; /* number of upvalues */