From 27407fc1f5fc4e0d97dadeda5939efa62fe7e380 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 2 Feb 1999 17:41:17 -0200 Subject: new syntax: assignment expressions + better order for opcodes --- lparser.c | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'lparser.c') diff --git a/lparser.c b/lparser.c index 8d632038..a960dc13 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.12 1999/02/02 13:47:31 roberto Exp roberto $ +** $Id: lparser.c,v 1.13 1999/02/02 17:57:49 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -114,6 +114,7 @@ static void chunk (LexState *ls); static void constructor (LexState *ls); static void decinit (LexState *ls, listdesc *d); static void exp0 (LexState *ls, vardesc *v); +static void Gexp (LexState *ls, vardesc *v); static void exp1 (LexState *ls); static void exp2 (LexState *ls, vardesc *v); static void explist (LexState *ls, listdesc *e); @@ -162,7 +163,7 @@ static int code_oparg_at (LexState *ls, int pc, OpCode op, int arg, int delta) { return 2; /* code size (opcode + 1 byte) */ } else if (arg <= MAX_WORD) { - code[pc] = (Byte)(op+1); + code[pc] = (Byte)(op-1); code[pc+1] = (Byte)(arg>>8); code[pc+2] = (Byte)(arg&0xFF); return 3; /* code size (opcode + 1 word) */ @@ -429,6 +430,15 @@ static void code_args (LexState *ls, int nparams, int dots) { } +static void unloaddot (LexState *ls, vardesc *v) { + /* dotted variables must be stored like regular indexed vars */ + if (v->k == VDOT) { + code_constant(ls, v->info); + v->k = VINDEXED; + } +} + + static void lua_pushvar (LexState *ls, vardesc *var) { switch (var->k) { case VLOCAL: @@ -452,16 +462,16 @@ static void lua_pushvar (LexState *ls, vardesc *var) { } -static void storevar (LexState *ls, vardesc *var) { +static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { switch (var->k) { case VLOCAL: - code_oparg(ls, SETLOCAL, var->info, -1); + code_oparg(ls, codes[0], var->info, -1); break; case VGLOBAL: - code_oparg(ls, SETGLOBAL, var->info, -1); + code_oparg(ls, codes[1], var->info, -1); break; case VINDEXED: - code_opcode(ls, SETTABLE0, -3); + code_opcode(ls, codes[2], -3); break; default: LUA_INTERNALERROR("invalid var kind to store"); @@ -469,6 +479,12 @@ static void storevar (LexState *ls, vardesc *var) { } +static void storevar (LexState *ls, vardesc *var) { + static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0}; + genstorevar(ls, var, codes); +} + + static int fix_jump (LexState *ls, int pc, OpCode op, int n) { /* jump is relative to position following jump instruction */ return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); @@ -932,6 +948,21 @@ static void exp0 (LexState *ls, vardesc *v) { } +static void Gexp (LexState *ls, vardesc *v) { + /* Gexp -> exp0 | var '=' exp1 */ + static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP}; + exp0(ls, v); + if (ls->token == '=' && v->k != VEXP) { /* assignment expression? */ + next(ls); /* skip '=' */ + unloaddot(ls, v); + exp1(ls); + genstorevar(ls, v, codes); + deltastack(ls, 1); /* DUP operations push an extra value */ + v->k = VEXP; v->info = 0; + } +} + + static void push (LexState *ls, stack_op *s, int op) { if (s->top == MAXOPS) luaX_error(ls, "expression too complex"); @@ -993,9 +1024,9 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { ifpart(ls, 1, ls->linenumber); break; - case '(': /* simpleexp -> '(' exp0 ')' */ + case '(': /* simpleexp -> '(' Gexp ')' */ next(ls); - exp0(ls, v); + Gexp(ls, v); check(ls, ')'); return; @@ -1206,13 +1237,10 @@ static void decinit (LexState *ls, listdesc *d) { } } + static int assignment (LexState *ls, vardesc *v, int nvars) { int left = 0; - /* dotted variables must be stored like regular indexed vars */ - if (v->k == VDOT) { - code_constant(ls, v->info); - v->k = VINDEXED; - } + unloaddot(ls, v); if (ls->token == ',') { /* assignment -> ',' NAME assignment */ vardesc nv; next(ls); -- cgit v1.2.3-55-g6feb