|
@@ -1,6 +1,6 @@
|
|
|
%{
|
|
|
/*
|
|
|
-** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
|
|
|
+** $Id: lua.stx,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
|
|
|
** Syntax analizer and code generator
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -96,15 +96,24 @@ static void code_byte (Byte c)
|
|
|
|
|
|
static void code_word_at (int pc, int n)
|
|
|
{
|
|
|
- Word w = n;
|
|
|
- if (w != n)
|
|
|
- luaY_error("block too big");
|
|
|
+ if (n > MAX_WORD)
|
|
|
+ luaY_error("construction too big; unable to compile");
|
|
|
currState->f->code[pc] = n&0xFF;
|
|
|
currState->f->code[pc+1] = n>>8;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static void fix_jump (int pc, OpCode op, int n)
|
|
|
+{
|
|
|
+ currState->f->code[pc] = op;
|
|
|
+ code_word_at(pc+1, n);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static void code_word (int n)
|
|
|
{
|
|
|
+ if (n > MAX_WORD)
|
|
|
+ luaY_error("construction too big; unable to compile");
|
|
|
code_byte(n&0xFF);
|
|
|
code_byte(n>>8);
|
|
|
}
|
|
@@ -128,16 +137,25 @@ static void code_opcode (OpCode op, int delta)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void code_opborw(OpCode opbyte, int arg, int delta)
|
|
|
+static void code_opb (OpCode opbyte, int arg, int delta)
|
|
|
{
|
|
|
- if (arg <= 255) {
|
|
|
- code_opcode(opbyte, delta);
|
|
|
- code_byte(arg);
|
|
|
- }
|
|
|
- else {
|
|
|
- code_opcode(opbyte+1, delta);
|
|
|
- code_word(arg);
|
|
|
- }
|
|
|
+ code_opcode(opbyte, delta);
|
|
|
+ code_byte(arg);
|
|
|
+}
|
|
|
+
|
|
|
+static void code_opw (OpCode opbyte, int arg, int delta)
|
|
|
+{
|
|
|
+ code_opcode(opbyte, delta);
|
|
|
+ code_word(arg);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void code_opborw (OpCode opbyte, int arg, int delta)
|
|
|
+{
|
|
|
+ if (arg <= 255)
|
|
|
+ code_opb(opbyte, arg, delta);
|
|
|
+ else
|
|
|
+ code_opw(opbyte+1, arg, delta);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -167,7 +185,7 @@ static void code_pop (OpCode op)
|
|
|
|
|
|
static void code_constant (int c)
|
|
|
{
|
|
|
- code_opborw(PUSHCONSTANTB, c, 1);
|
|
|
+ code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -235,9 +253,8 @@ static void code_number (real f)
|
|
|
|
|
|
static void flush_record (int n)
|
|
|
{
|
|
|
- if (n == 0) return;
|
|
|
- code_opcode(SETMAP, -2*n);
|
|
|
- code_byte(n);
|
|
|
+ if (n > 0)
|
|
|
+ code_opb(SETMAP, n, -2*n);
|
|
|
}
|
|
|
|
|
|
static void flush_list (int m, int n)
|
|
@@ -245,10 +262,8 @@ static void flush_list (int m, int n)
|
|
|
if (n == 0) return;
|
|
|
if (m == 0)
|
|
|
code_opcode(SETLIST0, -n);
|
|
|
- else if (m < 255) {
|
|
|
- code_opcode(SETLIST, -n);
|
|
|
- code_byte(m);
|
|
|
- }
|
|
|
+ else if (m < 255)
|
|
|
+ code_opb(SETLIST, m, -n);
|
|
|
else
|
|
|
luaY_error("list constructor too long");
|
|
|
code_byte(n);
|
|
@@ -352,8 +367,7 @@ void luaY_codedebugline (int line)
|
|
|
{
|
|
|
static int lastline = 0;
|
|
|
if (lua_debug && line != lastline) {
|
|
|
- code_neutralop(SETLINE);
|
|
|
- code_word(line);
|
|
|
+ code_opw(SETLINE, line, 0);
|
|
|
lastline = line;
|
|
|
}
|
|
|
}
|
|
@@ -399,13 +413,10 @@ static void adjust_mult_assign (int vars, long exps)
|
|
|
|
|
|
static void code_args (int dots)
|
|
|
{
|
|
|
- if (!dots) {
|
|
|
- code_opcode(ARGS, currState->nlocalvar);
|
|
|
- code_byte(currState->nlocalvar);
|
|
|
- }
|
|
|
+ if (!dots)
|
|
|
+ code_opb(ARGS, currState->nlocalvar, currState->nlocalvar);
|
|
|
else {
|
|
|
- code_opcode(VARARGS, currState->nlocalvar+1);
|
|
|
- code_byte(currState->nlocalvar);
|
|
|
+ code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1);
|
|
|
add_localvar(luaS_new("arg"));
|
|
|
}
|
|
|
}
|
|
@@ -414,7 +425,7 @@ static void code_args (int dots)
|
|
|
static void lua_pushvar (vardesc number)
|
|
|
{
|
|
|
if (number > 0) /* global var */
|
|
|
- code_opborw(GETGLOBALB, number-1, 1);
|
|
|
+ code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1);
|
|
|
else if (number < 0) /* local var */
|
|
|
code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1);
|
|
|
else
|
|
@@ -456,19 +467,19 @@ static void codeIf (int thenAdd, int elseAdd)
|
|
|
currState->pc -= sizeof(Word)+1;
|
|
|
elseinit = currState->pc;
|
|
|
}
|
|
|
- else {
|
|
|
- currState->f->code[elseAdd] = JMP;
|
|
|
- code_word_at(elseAdd+1, currState->pc-elseinit);
|
|
|
- }
|
|
|
- currState->f->code[thenAdd] = IFFJMP;
|
|
|
- code_word_at(thenAdd+1, elseinit-(thenAdd+sizeof(Word)+1));
|
|
|
+ else
|
|
|
+ fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1));
|
|
|
+ fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1));
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void code_shortcircuit (int pc, Byte jmp)
|
|
|
+static void code_shortcircuit (OpCode op, int pos)
|
|
|
{
|
|
|
- currState->f->code[pc] = jmp;
|
|
|
- code_word_at(pc+1, currState->pc - (pc + sizeof(Word)+1));
|
|
|
+ int dist = currState->pc - (pos+1);
|
|
|
+ if (dist > 255)
|
|
|
+ luaY_error("and/or expression too long");
|
|
|
+ currState->f->code[pos] = op;
|
|
|
+ currState->f->code[pos+1] = dist;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -582,7 +593,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname)
|
|
|
%token <vReal> NUMBER
|
|
|
%token <pTStr> NAME STRING
|
|
|
|
|
|
-%type <vInt> PrepJump, PrepJumpPop
|
|
|
+%type <vInt> PrepJump, PrepJumpPop, PrepJumpSC
|
|
|
%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
|
|
|
counter (which has list length); if <= 0, -list lenght */
|
|
|
%type <vLong> functioncall, expr /* if != 0, points to function return
|
|
@@ -620,18 +631,15 @@ sc : /* empty */ | ';' ;
|
|
|
stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END
|
|
|
{ codeIf($4, $6); }
|
|
|
|
|
|
- | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block PrepJump END
|
|
|
+ | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END
|
|
|
{
|
|
|
- currState->f->code[$5] = IFFJMP;
|
|
|
- code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1));
|
|
|
- currState->f->code[$7] = UPJMP;
|
|
|
- code_word_at($7+1, currState->pc - ($<vInt>2));
|
|
|
+ code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0);
|
|
|
+ fix_jump($5, IFFJMP, currState->pc - ($5+1));
|
|
|
}
|
|
|
|
|
|
- | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 PrepJumpPop
|
|
|
+ | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1
|
|
|
{
|
|
|
- currState->f->code[$6] = IFFUPJMP;
|
|
|
- code_word_at($6+1, currState->pc - ($<vInt>2));
|
|
|
+ code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1);
|
|
|
}
|
|
|
|
|
|
| varlist1 '=' exprlist1
|
|
@@ -699,6 +707,10 @@ PrepJump : /* empty */
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+PrepJumpSC : /* empty */
|
|
|
+ { $$ = currState->pc; code_opcode(0, -1); code_byte(0); }
|
|
|
+ ;
|
|
|
+
|
|
|
PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ }
|
|
|
;
|
|
|
|
|
@@ -726,13 +738,13 @@ expr : '(' expr ')' { $$ = $2; }
|
|
|
| STRING { code_string($1); $$ = 0; }
|
|
|
| NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
|
|
|
| functioncall { $$ = $1; }
|
|
|
- | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
|
|
|
- | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
|
|
|
| FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
|
|
|
+ | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; }
|
|
|
+ | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; }
|
|
|
;
|
|
|
|
|
|
table :
|
|
|
- { code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); }
|
|
|
+ { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); }
|
|
|
'{' fieldlist '}'
|
|
|
{ code_word_at($<vInt>1, $3); }
|
|
|
;
|