commit 68267ed878a2ea668aa97b40c5d9cacbe0e57831
parent fd25d4ad85302a84551ac6ed915435c035a978e4
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 29 Jan 1999 11:48:36 -0200
negative numerals do not need a MINUSOPeration; go directly to contant
table.
Diffstat:
M | lparser.c | | | 95 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/lparser.c b/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 1.8 1999/01/15 11:38:33 roberto Exp roberto $
+** $Id: lparser.c,v 1.9 1999/01/21 18:38:39 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -123,7 +123,6 @@ static void parlist (LexState *ls);
static void part (LexState *ls, constdesc *cd);
static void recfield (LexState *ls);
static void ret (LexState *ls);
-static void simpleexp (LexState *ls, vardesc *v);
static void statlist (LexState *ls);
static void var_or_func (LexState *ls, vardesc *v);
static void var_or_func_tail (LexState *ls, vardesc *v);
@@ -262,7 +261,7 @@ static int real_constant (FuncState *fs, real r) {
static void code_number (LexState *ls, real f) {
int i;
- if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
+ if (0 <= f && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */
else
code_constant(ls, real_constant(ls->fs, f));
@@ -900,6 +899,9 @@ static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP,
LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP};
+#define INDNOT 0
+#define INDMINUS 1
+
#define MAXOPS 20
typedef struct {
@@ -941,7 +943,7 @@ static void push (LexState *ls, stack_op *s, int op) {
static void prefix (LexState *ls, stack_op *s) {
while (ls->token == NOT || ls->token == '-') {
- push(ls, s, ls->token==NOT?0:1);
+ push(ls, s, ls->token==NOT?INDNOT:INDMINUS);
next(ls);
}
}
@@ -954,80 +956,85 @@ static void pop_to (LexState *ls, stack_op *s, int prio) {
}
}
-static void exp2 (LexState *ls, vardesc *v) {
- stack_op s;
- int op;
- s.top = 0;
- prefix(ls, &s);
- simpleexp(ls, v);
- while ((op = is_in(ls->token, binop)) >= 0) {
- op += FIRSTBIN;
- lua_pushvar(ls, v);
- /* '^' is right associative, so must 'simulate' a higher priority */
- pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
- push(ls, &s, op);
- next(ls);
- prefix(ls, &s);
- simpleexp(ls, v);
- lua_pushvar(ls, v);
- }
- if (s.top > 0) {
- lua_pushvar(ls, v);
- pop_to(ls, &s, 0);
- }
-}
-
-
-static void simpleexp (LexState *ls, vardesc *v) {
+static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
check_debugline(ls);
switch (ls->token) {
- case '(': /* simpleexp -> '(' exp0 ')' */
+ case NUMBER: { /* simpleexp -> NUMBER */
+ real r = ls->seminfo.r;
next(ls);
- exp0(ls, v);
- check(ls, ')');
- break;
-
- case NUMBER: /* simpleexp -> NUMBER */
- code_number(ls, ls->seminfo.r);
- next(ls);
- v->k = VEXP; v->info = 0;
+ /* dirty trick: check whether is a -NUMBER not followed by "^" */
+ /* (because the priority of "^" is closer than "-"...) */
+ if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
+ s->top--;
+ r = -r;
+ }
+ code_number(ls, r);
break;
+ }
case STRING: /* simpleexp -> STRING */
code_string(ls, ls->seminfo.ts); /* must use before "next" */
next(ls);
- v->k = VEXP; v->info = 0;
break;
case NIL: /* simpleexp -> NIL */
adjuststack(ls, -1);
next(ls);
- v->k = VEXP; v->info = 0;
break;
case '{': /* simpleexp -> constructor */
constructor(ls);
- v->k = VEXP; v->info = 0;
break;
case FUNCTION: { /* simpleexp -> FUNCTION body */
int line = ls->linenumber;
next(ls);
body(ls, 0, line);
- v->k = VEXP; v->info = 0;
break;
}
+ case '(': /* simpleexp -> '(' exp0 ')' */
+ next(ls);
+ exp0(ls, v);
+ check(ls, ')');
+ return;
+
case NAME: case '%':
var_or_func(ls, v);
- break;
+ return;
default:
luaX_error(ls, "<expression> expected");
- break;
+ return;
+ }
+ v->k = VEXP; v->info = 0;
+}
+
+
+static void exp2 (LexState *ls, vardesc *v) {
+ stack_op s;
+ int op;
+ s.top = 0;
+ prefix(ls, &s);
+ simpleexp(ls, v, &s);
+ while ((op = is_in(ls->token, binop)) >= 0) {
+ op += FIRSTBIN;
+ lua_pushvar(ls, v);
+ /* '^' is right associative, so must 'simulate' a higher priority */
+ pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
+ push(ls, &s, op);
+ next(ls);
+ prefix(ls, &s);
+ simpleexp(ls, v, &s);
+ lua_pushvar(ls, v);
+ }
+ if (s.top > 0) {
+ lua_pushvar(ls, v);
+ pop_to(ls, &s, 0);
}
}
+
static void var_or_func (LexState *ls, vardesc *v) {
/* var_or_func -> ['%'] NAME var_or_func_tail */
if (optional(ls, '%')) { /* upvalue? */