|
|
@ -1,6 +1,6 @@ |
|
|
|
%{ |
|
|
|
/* |
|
|
|
** $Id: lua.stx,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ |
|
|
|
** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ |
|
|
|
** Syntax analizer and code generator |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -94,6 +94,22 @@ 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"); |
|
|
|
currState->f->code[pc] = n&0xFF; |
|
|
|
currState->f->code[pc+1] = n>>8; |
|
|
|
} |
|
|
|
|
|
|
|
static void code_word (int n) |
|
|
|
{ |
|
|
|
code_byte(n&0xFF); |
|
|
|
code_byte(n>>8); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void deltastack (int delta) |
|
|
|
{ |
|
|
|
currState->stacksize += delta; |
|
|
@ -112,9 +128,25 @@ static void code_opcode (OpCode op, int delta) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void code_push (OpCode op) |
|
|
|
static void code_opborw(OpCode opbyte, int arg, int delta) |
|
|
|
{ |
|
|
|
code_opcode(op, 1); |
|
|
|
if (arg <= 255) { |
|
|
|
code_opcode(opbyte, delta); |
|
|
|
code_byte(arg); |
|
|
|
} |
|
|
|
else { |
|
|
|
code_opcode(opbyte+1, delta); |
|
|
|
code_word(arg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) |
|
|
|
{ |
|
|
|
if (firstop+arg < opbyte) |
|
|
|
code_opcode(firstop+arg, delta); |
|
|
|
else |
|
|
|
code_opborw(opbyte, arg, delta); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -133,31 +165,9 @@ static void code_pop (OpCode op) |
|
|
|
#define code_unop(op) code_neutralop(op) |
|
|
|
|
|
|
|
|
|
|
|
static void code_word_at (int pc, int n) |
|
|
|
{ |
|
|
|
Word w = n; |
|
|
|
if (w != n) |
|
|
|
luaY_error("block too big"); |
|
|
|
currState->f->code[pc] = n&0xFF; |
|
|
|
currState->f->code[pc+1] = n>>8; |
|
|
|
} |
|
|
|
|
|
|
|
static void code_word (int n) |
|
|
|
{ |
|
|
|
code_byte(n&0xFF); |
|
|
|
code_byte(n>>8); |
|
|
|
} |
|
|
|
|
|
|
|
static void code_constant (int c) |
|
|
|
{ |
|
|
|
if (c <= 255) { |
|
|
|
code_push(PUSHCONSTANTB); |
|
|
|
code_byte(c); |
|
|
|
} |
|
|
|
else { |
|
|
|
code_push(PUSHCONSTANT); |
|
|
|
code_word(c); |
|
|
|
} |
|
|
|
code_opborw(PUSHCONSTANTB, c, 1); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -216,18 +226,8 @@ static int real_constant (real r) |
|
|
|
static void code_number (real f) |
|
|
|
{ |
|
|
|
Word i; |
|
|
|
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) { |
|
|
|
/* f has an (short) integer value */ |
|
|
|
if (i <= 2) code_push(PUSH0 + i); |
|
|
|
else if (i <= 255) { |
|
|
|
code_push(PUSHBYTE); |
|
|
|
code_byte(i); |
|
|
|
} |
|
|
|
else { |
|
|
|
code_push(PUSHWORD); |
|
|
|
code_word(i); |
|
|
|
} |
|
|
|
} |
|
|
|
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) |
|
|
|
code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */ |
|
|
|
else |
|
|
|
code_constant(real_constant(f)); |
|
|
|
} |
|
|
@ -344,12 +344,7 @@ static void pushupvalue (TaggedString *n) |
|
|
|
if (aux_localname(n, currState) >= 0) |
|
|
|
luaY_syntaxerror("cannot access an upvalue in current scope", n->str); |
|
|
|
i = indexupvalue(n); |
|
|
|
if (i == 0) |
|
|
|
code_push(PUSHUPVALUE0); |
|
|
|
else { |
|
|
|
code_push(PUSHUPVALUE); |
|
|
|
code_byte(i); |
|
|
|
} |
|
|
|
code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -366,18 +361,10 @@ void luaY_codedebugline (int line) |
|
|
|
|
|
|
|
static void adjuststack (int n) |
|
|
|
{ |
|
|
|
if (n > 0) { |
|
|
|
code_opcode(POPS, -n); |
|
|
|
code_byte(n); |
|
|
|
} |
|
|
|
else if (n < 0) { |
|
|
|
if (n == -1) |
|
|
|
code_push(PUSHNIL); |
|
|
|
else { |
|
|
|
code_opcode(PUSHNILS, -n); |
|
|
|
code_byte(-n); |
|
|
|
} |
|
|
|
} |
|
|
|
if (n > 0) |
|
|
|
code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */ |
|
|
|
else if (n < 0) |
|
|
|
code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -426,29 +413,12 @@ static void code_args (int dots) |
|
|
|
|
|
|
|
static void lua_pushvar (vardesc number) |
|
|
|
{ |
|
|
|
if (number > 0) { /* global var */ |
|
|
|
number--; |
|
|
|
if (number <= 255) { |
|
|
|
code_push(PUSHGLOBALB); |
|
|
|
code_byte(number); |
|
|
|
} |
|
|
|
else { |
|
|
|
code_push(PUSHGLOBAL); |
|
|
|
code_word(number); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (number < 0) { /* local var */ |
|
|
|
number = (-number) - 1; |
|
|
|
if (number < 10) |
|
|
|
code_push(PUSHLOCAL0 + number); |
|
|
|
else { |
|
|
|
code_push(PUSHLOCAL); |
|
|
|
code_byte(number); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
if (number > 0) /* global var */ |
|
|
|
code_opborw(GETGLOBALB, number-1, 1); |
|
|
|
else if (number < 0) /* local var */ |
|
|
|
code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); |
|
|
|
else |
|
|
|
code_pop(GETTABLE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -456,26 +426,10 @@ static void storevar (vardesc number) |
|
|
|
{ |
|
|
|
if (number == 0) /* indexed var */ |
|
|
|
code_opcode(SETTABLE0, -3); |
|
|
|
else if (number > 0) { /* global var */ |
|
|
|
number--; |
|
|
|
if (number <= 255) { |
|
|
|
code_pop(SETGLOBALB); |
|
|
|
code_byte(number); |
|
|
|
} |
|
|
|
else { |
|
|
|
code_pop(SETGLOBAL); |
|
|
|
code_word(number); |
|
|
|
} |
|
|
|
} |
|
|
|
else { /* number < 0 - local var */ |
|
|
|
number = (-number) - 1; |
|
|
|
if (number < 10) |
|
|
|
code_pop(SETLOCAL0 + number); |
|
|
|
else { |
|
|
|
code_pop(SETLOCAL); |
|
|
|
code_byte(number); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (number > 0) /* global var */ |
|
|
|
code_opborw(SETGLOBALB, number-1, -1); |
|
|
|
else /* number < 0 - local var */ |
|
|
|
code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -535,8 +489,7 @@ static void func_onstack (TProtoFunc *f) |
|
|
|
currState->f->consts[c].value.tf = (currState+1)->f; |
|
|
|
for (i=0; i<nupvalues; i++) |
|
|
|
lua_pushvar((currState+1)->upvalues[i]); |
|
|
|
code_constant(c); |
|
|
|
code_opcode(CLOSURE, -nupvalues); |
|
|
|
code_opborw(CLOSUREB, c, 1-nupvalues); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -771,7 +724,7 @@ expr : '(' expr ')' { $$ = $2; } |
|
|
|
| varexp { $$ = 0;} |
|
|
|
| NUMBER { code_number($1); $$ = 0; } |
|
|
|
| STRING { code_string($1); $$ = 0; } |
|
|
|
| NIL {code_push(PUSHNIL); $$ = 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; } |
|
|
@ -779,14 +732,9 @@ expr : '(' expr ')' { $$ = $2; } |
|
|
|
; |
|
|
|
|
|
|
|
table : |
|
|
|
{ |
|
|
|
code_push(CREATEARRAY); |
|
|
|
$<vInt>$ = currState->pc; code_word(0); |
|
|
|
} |
|
|
|
'{' fieldlist '}' |
|
|
|
{ |
|
|
|
code_word_at($<vInt>1, $3); |
|
|
|
} |
|
|
|
{ code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); } |
|
|
|
'{' fieldlist '}' |
|
|
|
{ code_word_at($<vInt>1, $3); } |
|
|
|
; |
|
|
|
|
|
|
|
functioncall : funcvalue funcParams |
|
|
@ -801,8 +749,7 @@ functioncall : funcvalue funcParams |
|
|
|
funcvalue : varexp { $$ = 0; } |
|
|
|
| varexp ':' NAME |
|
|
|
{ |
|
|
|
code_push(PUSHSELF); |
|
|
|
code_word(string_constant($3, currState)); |
|
|
|
code_opborw(PUSHSELFB, string_constant($3, currState), 1); |
|
|
|
$$ = 1; |
|
|
|
} |
|
|
|
; |
|
|
@ -909,15 +856,8 @@ varlist1 : var |
|
|
|
; |
|
|
|
|
|
|
|
var : singlevar { $$ = $1; } |
|
|
|
| varexp '[' expr1 ']' |
|
|
|
{ |
|
|
|
$$ = 0; /* indexed variable */ |
|
|
|
} |
|
|
|
| varexp '.' NAME |
|
|
|
{ |
|
|
|
code_string($3); |
|
|
|
$$ = 0; /* indexed variable */ |
|
|
|
} |
|
|
|
| varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ |
|
|
|
| varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */ |
|
|
|
; |
|
|
|
|
|
|
|
singlevar : NAME { $$ = singlevar($1, currState); } |
|
|
|