From 40f4e931f317f56725cba0b61ed82c0688a821f6 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 14 Feb 2001 15:19:28 -0200 Subject: [PATCH] more liberal syntax for expressions --- lparser.c | 151 +++++++++++++++++++++++++----------------------------- 1 file changed, 70 insertions(+), 81 deletions(-) diff --git a/lparser.c b/lparser.c index bee1ef28..53aabca6 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.131 2001/02/09 18:37:33 roberto Exp roberto $ +** $Id: lparser.c,v 1.132 2001/02/09 20:22:29 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -352,7 +352,7 @@ static void close_func (LexState *ls) { luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ f->sizelineinfo = fs->nlineinfo; - lua_assert(luaG_checkcode(f)); + lua_assert(luaG_checkcode(L, f)); ls->fs = fs->prev; lua_assert(fs->bl == NULL); } @@ -433,60 +433,6 @@ static void funcargs (LexState *ls, int slf) { } -static void var_or_func_tail (LexState *ls, expdesc *v) { - for (;;) { - switch (ls->t.token) { - case '.': { /* var_or_func_tail -> '.' NAME */ - next(ls); - luaK_tostack(ls, v, 1); /* `v' must be on stack */ - luaK_kstr(ls, checkname(ls)); - v->k = VINDEXED; - break; - } - case '[': { /* var_or_func_tail -> '[' exp1 ']' */ - next(ls); - luaK_tostack(ls, v, 1); /* `v' must be on stack */ - v->k = VINDEXED; - exp1(ls); - check(ls, ']'); - break; - } - case ':': { /* var_or_func_tail -> ':' NAME funcargs */ - next(ls); - luaK_tostack(ls, v, 1); /* `v' must be on stack */ - luaK_code1(ls->fs, OP_PUSHSELF, checkname(ls)); - funcargs(ls, 1); - v->k = VEXP; - v->u.l.t = v->u.l.f = NO_JUMP; - break; - } - case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ - luaK_tostack(ls, v, 1); /* `v' must be on stack */ - funcargs(ls, 0); - v->k = VEXP; - v->u.l.t = v->u.l.f = NO_JUMP; - break; - } - default: return; /* should be follow... */ - } - } -} - - -static void var_or_func (LexState *ls, expdesc *v) { - /* var_or_func -> ['%'] NAME var_or_func_tail */ - if (optional(ls, '%')) { /* upvalue? */ - pushupvalue(ls, str_checkname(ls)); - v->k = VEXP; - v->u.l.t = v->u.l.f = NO_JUMP; - } - else /* variable name */ - singlevar(ls, str_checkname(ls), v); - var_or_func_tail(ls, v); -} - - - /* ** {====================================================================== ** Rules for Constructors @@ -615,47 +561,51 @@ static void constructor (LexState *ls) { ** ======================================================================= */ - -static void simpleexp (LexState *ls, expdesc *v) { +static void primaryexp (LexState *ls, expdesc *v) { FuncState *fs = ls->fs; switch (ls->t.token) { - case TK_NUMBER: { /* simpleexp -> NUMBER */ + case TK_NUMBER: { lua_Number r = ls->t.seminfo.r; next(ls); luaK_number(fs, r); break; } - case TK_STRING: { /* simpleexp -> STRING */ + case TK_STRING: { code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ next(ls); break; } - case TK_NIL: { /* simpleexp -> NIL */ + case TK_NIL: { luaK_adjuststack(fs, -1); next(ls); break; } - case '{': { /* simpleexp -> constructor */ + case '{': { /* constructor */ constructor(ls); break; } - case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ + case TK_FUNCTION: { next(ls); body(ls, 0, ls->linenumber); break; } - case '(': { /* simpleexp -> '(' expr ')' */ + case '(': { next(ls); expr(ls, v); check(ls, ')'); return; } - case TK_NAME: case '%': { - var_or_func(ls, v); + case TK_NAME: { + singlevar(ls, str_checkname(ls), v); return; } + case '%': { + next(ls); /* skip `%' */ + pushupvalue(ls, str_checkname(ls)); + break; + } default: { - luaK_error(ls, " expected"); + luaK_error(ls, "unexpected symbol"); return; } } @@ -664,10 +614,46 @@ static void simpleexp (LexState *ls, expdesc *v) { } -static void exp1 (LexState *ls) { - expdesc v; - expr(ls, &v); - luaK_tostack(ls, &v, 1); +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ + primaryexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* '.' NAME */ + next(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + luaK_kstr(ls, checkname(ls)); + v->k = VINDEXED; + break; + } + case '[': { /* '[' exp1 ']' */ + next(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + v->k = VINDEXED; + exp1(ls); + check(ls, ']'); + break; + } + case ':': { /* ':' NAME funcargs */ + next(ls); + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + luaK_code1(ls->fs, OP_PUSHSELF, checkname(ls)); + funcargs(ls, 1); + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_tostack(ls, v, 1); /* `v' must be on stack */ + funcargs(ls, 0); + v->k = VEXP; + v->u.l.t = v->u.l.f = NO_JUMP; + break; + } + default: return; /* should be follow... */ + } + } } @@ -748,6 +734,13 @@ static void expr (LexState *ls, expdesc *v) { subexpr(ls, v, -1); } + +static void exp1 (LexState *ls) { + expdesc v; + expr(ls, &v); + luaK_tostack(ls, &v, 1); +} + /* }==================================================================== */ @@ -781,10 +774,10 @@ static void block (LexState *ls) { static int assignment (LexState *ls, expdesc *v, int nvars) { int left = 0; /* number of values left in the stack after assignment */ luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); - if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ + if (ls->t.token == ',') { /* assignment -> ',' simpleexp assignment */ expdesc nv; next(ls); - var_or_func(ls, &nv); + simpleexp(ls, &nv); check_condition(ls, (nv.k != VEXP), "syntax error"); left = assignment(ls, &nv, nvars+1); } @@ -998,15 +991,15 @@ static void funcstat (LexState *ls, int line) { static void namestat (LexState *ls) { - /* stat -> func | ['%'] NAME assignment */ + /* stat -> func | assignment */ FuncState *fs = ls->fs; expdesc v; - var_or_func(ls, &v); + simpleexp(ls, &v); if (v.k == VEXP) { /* stat -> func */ check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ luaK_setcallreturns(fs, 0); /* call statement uses no results */ } - else { /* stat -> ['%'] NAME assignment */ + else { /* stat -> assignment */ int left = assignment(ls, &v, 1); luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ } @@ -1072,10 +1065,6 @@ static int stat (LexState *ls) { localstat(ls); return 0; } - case TK_NAME: case '%': { /* stat -> namestat */ - namestat(ls); - return 0; - } case TK_RETURN: { /* stat -> retstat */ retstat(ls); return 1; /* must be last statement */ @@ -1085,7 +1074,7 @@ static int stat (LexState *ls) { return 1; /* must be last statement */ } default: { - luaK_error(ls, " expected"); + namestat(ls); return 0; /* to avoid warnings */ } }