Improve line number tracking in parser.

Associate statements with their initial keyword, and expressions
with their operator token.
This commit is contained in:
Tor Andersson
2019-03-07 13:06:47 +01:00
parent 6a592abfc4
commit 914ae72a24
4 changed files with 91 additions and 36 deletions

View File

@@ -51,7 +51,7 @@ static void checkfutureword(JF, js_Ast *exp)
} }
} }
static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *body, int script, int default_strict) static js_Function *newfun(js_State *J, int line, js_Ast *name, js_Ast *params, js_Ast *body, int script, int default_strict)
{ {
js_Function *F = js_malloc(J, sizeof *F); js_Function *F = js_malloc(J, sizeof *F);
memset(F, 0, sizeof *F); memset(F, 0, sizeof *F);
@@ -61,7 +61,7 @@ static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *bo
++J->gccounter; ++J->gccounter;
F->filename = js_intern(J, J->filename); F->filename = js_intern(J, J->filename);
F->line = name ? name->line : params ? params->line : body ? body->line : 1; F->line = line;
F->script = script; F->script = script;
F->strict = default_strict; F->strict = default_strict;
F->name = name ? name->string : ""; F->name = name ? name->string : "";
@@ -354,11 +354,11 @@ static void cobject(JF, js_Ast *list)
emit(J, F, OP_INITPROP); emit(J, F, OP_INITPROP);
break; break;
case EXP_PROP_GET: case EXP_PROP_GET:
emitfunction(J, F, newfun(J, NULL, NULL, kv->c, 0, F->strict)); emitfunction(J, F, newfun(J, prop->line, NULL, NULL, kv->c, 0, F->strict));
emit(J, F, OP_INITGETTER); emit(J, F, OP_INITGETTER);
break; break;
case EXP_PROP_SET: case EXP_PROP_SET:
emitfunction(J, F, newfun(J, NULL, kv->b, kv->c, 0, F->strict)); emitfunction(J, F, newfun(J, prop->line, NULL, kv->b, kv->c, 0, F->strict));
emit(J, F, OP_INITSETTER); emit(J, F, OP_INITSETTER);
break; break;
} }
@@ -586,7 +586,7 @@ static void cexp(JF, js_Ast *exp)
break; break;
case EXP_FUN: case EXP_FUN:
emitfunction(J, F, newfun(J, exp->a, exp->b, exp->c, 0, F->strict)); emitfunction(J, F, newfun(J, exp->line, exp->a, exp->b, exp->c, 0, F->strict));
break; break;
case EXP_IDENTIFIER: case EXP_IDENTIFIER:
@@ -1321,7 +1321,7 @@ static void cfundecs(JF, js_Ast *list)
while (list) { while (list) {
js_Ast *stm = list->a; js_Ast *stm = list->a;
if (stm->type == AST_FUNDEC) { if (stm->type == AST_FUNDEC) {
emitfunction(J, F, newfun(J, stm->a, stm->b, stm->c, 0, F->strict)); emitfunction(J, F, newfun(J, stm->line, stm->a, stm->b, stm->c, 0, F->strict));
emitstring(J, F, OP_INITVAR, stm->a->string); emitstring(J, F, OP_INITVAR, stm->a->string);
} }
list = list->b; list = list->b;
@@ -1378,10 +1378,10 @@ static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body)
js_Function *jsC_compilefunction(js_State *J, js_Ast *prog) js_Function *jsC_compilefunction(js_State *J, js_Ast *prog)
{ {
return newfun(J, prog->a, prog->b, prog->c, 0, J->default_strict); return newfun(J, prog->line, prog->a, prog->b, prog->c, 0, J->default_strict);
} }
js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict) js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict)
{ {
return newfun(J, NULL, NULL, prog, 1, default_strict); return newfun(J, prog->line, NULL, NULL, prog, 1, default_strict);
} }

View File

@@ -143,6 +143,11 @@ static void ps(const char *s)
fputs(s, stdout); fputs(s, stdout);
} }
static void pn(int n)
{
printf("%d", n);
}
static void in(int d) static void in(int d)
{ {
if (minify < 1) if (minify < 1)
@@ -702,6 +707,8 @@ static void snode(int d, js_Ast *node)
pc('('); pc('(');
ps(astname[node->type]); ps(astname[node->type]);
pc(':');
pn(node->line);
switch (node->type) { switch (node->type) {
default: break; default: break;
case AST_IDENTIFIER: pc(' '); ps(node->string); break; case AST_IDENTIFIER: pc(' '); ps(node->string); break;

1
jsi.h
View File

@@ -179,7 +179,6 @@ struct js_State
/* parser state */ /* parser state */
int astdepth; int astdepth;
int astline;
int lookahead; int lookahead;
const char *text; const char *text;
double number; double number;

103
jsparse.c
View File

@@ -2,18 +2,18 @@
#include "jslex.h" #include "jslex.h"
#include "jsparse.h" #include "jsparse.h"
#define LIST(h) jsP_newnode(J, AST_LIST, h, 0, 0, 0) #define LIST(h) jsP_newnode(J, AST_LIST, 0, h, 0, 0, 0)
#define EXP0(x) jsP_newnode(J, EXP_ ## x, 0, 0, 0, 0) #define EXP0(x) jsP_newnode(J, EXP_ ## x, line, 0, 0, 0, 0)
#define EXP1(x,a) jsP_newnode(J, EXP_ ## x, a, 0, 0, 0) #define EXP1(x,a) jsP_newnode(J, EXP_ ## x, line, a, 0, 0, 0)
#define EXP2(x,a,b) jsP_newnode(J, EXP_ ## x, a, b, 0, 0) #define EXP2(x,a,b) jsP_newnode(J, EXP_ ## x, line, a, b, 0, 0)
#define EXP3(x,a,b,c) jsP_newnode(J, EXP_ ## x, a, b, c, 0) #define EXP3(x,a,b,c) jsP_newnode(J, EXP_ ## x, line, a, b, c, 0)
#define STM0(x) jsP_newnode(J, STM_ ## x, 0, 0, 0, 0) #define STM0(x) jsP_newnode(J, STM_ ## x, line, 0, 0, 0, 0)
#define STM1(x,a) jsP_newnode(J, STM_ ## x, a, 0, 0, 0) #define STM1(x,a) jsP_newnode(J, STM_ ## x, line, a, 0, 0, 0)
#define STM2(x,a,b) jsP_newnode(J, STM_ ## x, a, b, 0, 0) #define STM2(x,a,b) jsP_newnode(J, STM_ ## x, line, a, b, 0, 0)
#define STM3(x,a,b,c) jsP_newnode(J, STM_ ## x, a, b, c, 0) #define STM3(x,a,b,c) jsP_newnode(J, STM_ ## x, line, a, b, c, 0)
#define STM4(x,a,b,c,d) jsP_newnode(J, STM_ ## x, a, b, c, d) #define STM4(x,a,b,c,d) jsP_newnode(J, STM_ ## x, line, a, b, c, d)
static js_Ast *expression(js_State *J, int notin); static js_Ast *expression(js_State *J, int notin);
static js_Ast *assignment(js_State *J, int notin); static js_Ast *assignment(js_State *J, int notin);
@@ -59,12 +59,12 @@ static void jsP_warning(js_State *J, const char *fmt, ...)
js_report(J, buf); js_report(J, buf);
} }
static js_Ast *jsP_newnode(js_State *J, enum js_AstType type, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d) static js_Ast *jsP_newnode(js_State *J, enum js_AstType type, int line, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d)
{ {
js_Ast *node = js_malloc(J, sizeof *node); js_Ast *node = js_malloc(J, sizeof *node);
node->type = type; node->type = type;
node->line = J->astline; node->line = line;
node->a = a; node->a = a;
node->b = b; node->b = b;
node->c = c; node->c = c;
@@ -100,14 +100,14 @@ static js_Ast *jsP_list(js_Ast *head)
static js_Ast *jsP_newstrnode(js_State *J, enum js_AstType type, const char *s) static js_Ast *jsP_newstrnode(js_State *J, enum js_AstType type, const char *s)
{ {
js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0); js_Ast *node = jsP_newnode(J, type, J->lexline, 0, 0, 0, 0);
node->string = s; node->string = s;
return node; return node;
} }
static js_Ast *jsP_newnumnode(js_State *J, enum js_AstType type, double n) static js_Ast *jsP_newnumnode(js_State *J, enum js_AstType type, double n)
{ {
js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0); js_Ast *node = jsP_newnode(J, type, J->lexline, 0, 0, 0, 0);
node->number = n; node->number = n;
return node; return node;
} }
@@ -138,7 +138,6 @@ void jsP_freeparse(js_State *J)
static void jsP_next(js_State *J) static void jsP_next(js_State *J)
{ {
J->lookahead = jsY_lex(J); J->lookahead = jsY_lex(J);
J->astline = J->lexline;
} }
#define jsP_accept(J,x) (J->lookahead == x ? (jsP_next(J), 1) : 0) #define jsP_accept(J,x) (J->lookahead == x ? (jsP_next(J), 1) : 0)
@@ -188,6 +187,7 @@ static js_Ast *identifiername(js_State *J)
static js_Ast *arrayelement(js_State *J) static js_Ast *arrayelement(js_State *J)
{ {
int line = J->lexline;
if (J->lookahead == ',') if (J->lookahead == ',')
return EXP0(UNDEF); return EXP0(UNDEF);
return assignment(J, 0); return assignment(J, 0);
@@ -224,6 +224,7 @@ static js_Ast *propname(js_State *J)
static js_Ast *propassign(js_State *J) static js_Ast *propassign(js_State *J)
{ {
js_Ast *name, *value, *arg, *body; js_Ast *name, *value, *arg, *body;
int line = J->lexline;
name = propname(J); name = propname(J);
@@ -278,7 +279,7 @@ static js_Ast *parameters(js_State *J)
return jsP_list(head); return jsP_list(head);
} }
static js_Ast *fundec(js_State *J) static js_Ast *fundec(js_State *J, int line)
{ {
js_Ast *a, *b, *c; js_Ast *a, *b, *c;
a = identifier(J); a = identifier(J);
@@ -286,10 +287,10 @@ static js_Ast *fundec(js_State *J)
b = parameters(J); b = parameters(J);
jsP_expect(J, ')'); jsP_expect(J, ')');
c = funbody(J); c = funbody(J);
return jsP_newnode(J, AST_FUNDEC, a, b, c, 0); return jsP_newnode(J, AST_FUNDEC, line, a, b, c, 0);
} }
static js_Ast *funstm(js_State *J) static js_Ast *funstm(js_State *J, int line)
{ {
js_Ast *a, *b, *c; js_Ast *a, *b, *c;
a = identifier(J); a = identifier(J);
@@ -301,7 +302,7 @@ static js_Ast *funstm(js_State *J)
return STM1(VAR, LIST(EXP2(VAR, a, EXP3(FUN, a, b, c)))); return STM1(VAR, LIST(EXP2(VAR, a, EXP3(FUN, a, b, c))));
} }
static js_Ast *funexp(js_State *J) static js_Ast *funexp(js_State *J, int line)
{ {
js_Ast *a, *b, *c; js_Ast *a, *b, *c;
a = identifieropt(J); a = identifieropt(J);
@@ -317,6 +318,7 @@ static js_Ast *funexp(js_State *J)
static js_Ast *primary(js_State *J) static js_Ast *primary(js_State *J)
{ {
js_Ast *a; js_Ast *a;
int line = J->lexline;
if (J->lookahead == TK_IDENTIFIER) { if (J->lookahead == TK_IDENTIFIER) {
a = jsP_newstrnode(J, EXP_IDENTIFIER, J->text); a = jsP_newstrnode(J, EXP_IDENTIFIER, J->text);
@@ -344,9 +346,21 @@ static js_Ast *primary(js_State *J)
if (jsP_accept(J, TK_NULL)) return EXP0(NULL); if (jsP_accept(J, TK_NULL)) return EXP0(NULL);
if (jsP_accept(J, TK_TRUE)) return EXP0(TRUE); if (jsP_accept(J, TK_TRUE)) return EXP0(TRUE);
if (jsP_accept(J, TK_FALSE)) return EXP0(FALSE); if (jsP_accept(J, TK_FALSE)) return EXP0(FALSE);
if (jsP_accept(J, '{')) { a = EXP1(OBJECT, objectliteral(J)); jsP_expect(J, '}'); return a; } if (jsP_accept(J, '{')) {
if (jsP_accept(J, '[')) { a = EXP1(ARRAY, arrayliteral(J)); jsP_expect(J, ']'); return a; } a = EXP1(OBJECT, objectliteral(J));
if (jsP_accept(J, '(')) { a = expression(J, 0); jsP_expect(J, ')'); return a; } jsP_expect(J, '}');
return a;
}
if (jsP_accept(J, '[')) {
a = EXP1(ARRAY, arrayliteral(J));
jsP_expect(J, ']');
return a;
}
if (jsP_accept(J, '(')) {
a = expression(J, 0);
jsP_expect(J, ')');
return a;
}
jsP_error(J, "unexpected token in expression: %s", jsY_tokenstring(J->lookahead)); jsP_error(J, "unexpected token in expression: %s", jsY_tokenstring(J->lookahead));
} }
@@ -366,6 +380,7 @@ static js_Ast *arguments(js_State *J)
static js_Ast *newexp(js_State *J) static js_Ast *newexp(js_State *J)
{ {
js_Ast *a, *b; js_Ast *a, *b;
int line = J->lexline;
if (jsP_accept(J, TK_NEW)) { if (jsP_accept(J, TK_NEW)) {
a = memberexp(J); a = memberexp(J);
@@ -378,7 +393,7 @@ static js_Ast *newexp(js_State *J)
} }
if (jsP_accept(J, TK_FUNCTION)) if (jsP_accept(J, TK_FUNCTION))
return funexp(J); return funexp(J, line);
return primary(J); return primary(J);
} }
@@ -386,9 +401,11 @@ static js_Ast *newexp(js_State *J)
static js_Ast *memberexp(js_State *J) static js_Ast *memberexp(js_State *J)
{ {
js_Ast *a = newexp(J); js_Ast *a = newexp(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; } if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; }
if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; } if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; }
POPREC(); POPREC();
@@ -398,9 +415,11 @@ loop:
static js_Ast *callexp(js_State *J) static js_Ast *callexp(js_State *J)
{ {
js_Ast *a = newexp(J); js_Ast *a = newexp(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; } if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; }
if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; } if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; }
if (jsP_accept(J, '(')) { a = EXP2(CALL, a, arguments(J)); jsP_expect(J, ')'); goto loop; } if (jsP_accept(J, '(')) { a = EXP2(CALL, a, arguments(J)); jsP_expect(J, ')'); goto loop; }
@@ -411,6 +430,7 @@ loop:
static js_Ast *postfix(js_State *J) static js_Ast *postfix(js_State *J)
{ {
js_Ast *a = callexp(J); js_Ast *a = callexp(J);
int line = J->lexline;
if (!J->newline && jsP_accept(J, TK_INC)) return EXP1(POSTINC, a); if (!J->newline && jsP_accept(J, TK_INC)) return EXP1(POSTINC, a);
if (!J->newline && jsP_accept(J, TK_DEC)) return EXP1(POSTDEC, a); if (!J->newline && jsP_accept(J, TK_DEC)) return EXP1(POSTDEC, a);
return a; return a;
@@ -419,6 +439,7 @@ static js_Ast *postfix(js_State *J)
static js_Ast *unary(js_State *J) static js_Ast *unary(js_State *J)
{ {
js_Ast *a; js_Ast *a;
int line = J->lexline;
INCREC(); INCREC();
if (jsP_accept(J, TK_DELETE)) a = EXP1(DELETE, unary(J)); if (jsP_accept(J, TK_DELETE)) a = EXP1(DELETE, unary(J));
else if (jsP_accept(J, TK_VOID)) a = EXP1(VOID, unary(J)); else if (jsP_accept(J, TK_VOID)) a = EXP1(VOID, unary(J));
@@ -437,9 +458,11 @@ static js_Ast *unary(js_State *J)
static js_Ast *multiplicative(js_State *J) static js_Ast *multiplicative(js_State *J)
{ {
js_Ast *a = unary(J); js_Ast *a = unary(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, '*')) { a = EXP2(MUL, a, unary(J)); goto loop; } if (jsP_accept(J, '*')) { a = EXP2(MUL, a, unary(J)); goto loop; }
if (jsP_accept(J, '/')) { a = EXP2(DIV, a, unary(J)); goto loop; } if (jsP_accept(J, '/')) { a = EXP2(DIV, a, unary(J)); goto loop; }
if (jsP_accept(J, '%')) { a = EXP2(MOD, a, unary(J)); goto loop; } if (jsP_accept(J, '%')) { a = EXP2(MOD, a, unary(J)); goto loop; }
@@ -450,9 +473,11 @@ loop:
static js_Ast *additive(js_State *J) static js_Ast *additive(js_State *J)
{ {
js_Ast *a = multiplicative(J); js_Ast *a = multiplicative(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, '+')) { a = EXP2(ADD, a, multiplicative(J)); goto loop; } if (jsP_accept(J, '+')) { a = EXP2(ADD, a, multiplicative(J)); goto loop; }
if (jsP_accept(J, '-')) { a = EXP2(SUB, a, multiplicative(J)); goto loop; } if (jsP_accept(J, '-')) { a = EXP2(SUB, a, multiplicative(J)); goto loop; }
POPREC(); POPREC();
@@ -462,9 +487,11 @@ loop:
static js_Ast *shift(js_State *J) static js_Ast *shift(js_State *J)
{ {
js_Ast *a = additive(J); js_Ast *a = additive(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, TK_SHL)) { a = EXP2(SHL, a, additive(J)); goto loop; } if (jsP_accept(J, TK_SHL)) { a = EXP2(SHL, a, additive(J)); goto loop; }
if (jsP_accept(J, TK_SHR)) { a = EXP2(SHR, a, additive(J)); goto loop; } if (jsP_accept(J, TK_SHR)) { a = EXP2(SHR, a, additive(J)); goto loop; }
if (jsP_accept(J, TK_USHR)) { a = EXP2(USHR, a, additive(J)); goto loop; } if (jsP_accept(J, TK_USHR)) { a = EXP2(USHR, a, additive(J)); goto loop; }
@@ -475,9 +502,11 @@ loop:
static js_Ast *relational(js_State *J, int notin) static js_Ast *relational(js_State *J, int notin)
{ {
js_Ast *a = shift(J); js_Ast *a = shift(J);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, '<')) { a = EXP2(LT, a, shift(J)); goto loop; } if (jsP_accept(J, '<')) { a = EXP2(LT, a, shift(J)); goto loop; }
if (jsP_accept(J, '>')) { a = EXP2(GT, a, shift(J)); goto loop; } if (jsP_accept(J, '>')) { a = EXP2(GT, a, shift(J)); goto loop; }
if (jsP_accept(J, TK_LE)) { a = EXP2(LE, a, shift(J)); goto loop; } if (jsP_accept(J, TK_LE)) { a = EXP2(LE, a, shift(J)); goto loop; }
@@ -491,9 +520,11 @@ loop:
static js_Ast *equality(js_State *J, int notin) static js_Ast *equality(js_State *J, int notin)
{ {
js_Ast *a = relational(J, notin); js_Ast *a = relational(J, notin);
int line;
SAVEREC(); SAVEREC();
loop: loop:
INCREC(); INCREC();
line = J->lexline;
if (jsP_accept(J, TK_EQ)) { a = EXP2(EQ, a, relational(J, notin)); goto loop; } if (jsP_accept(J, TK_EQ)) { a = EXP2(EQ, a, relational(J, notin)); goto loop; }
if (jsP_accept(J, TK_NE)) { a = EXP2(NE, a, relational(J, notin)); goto loop; } if (jsP_accept(J, TK_NE)) { a = EXP2(NE, a, relational(J, notin)); goto loop; }
if (jsP_accept(J, TK_STRICTEQ)) { a = EXP2(STRICTEQ, a, relational(J, notin)); goto loop; } if (jsP_accept(J, TK_STRICTEQ)) { a = EXP2(STRICTEQ, a, relational(J, notin)); goto loop; }
@@ -506,9 +537,11 @@ static js_Ast *bitand(js_State *J, int notin)
{ {
js_Ast *a = equality(J, notin); js_Ast *a = equality(J, notin);
SAVEREC(); SAVEREC();
int line = J->lexline;
while (jsP_accept(J, '&')) { while (jsP_accept(J, '&')) {
INCREC(); INCREC();
a = EXP2(BITAND, a, equality(J, notin)); a = EXP2(BITAND, a, equality(J, notin));
line = J->lexline;
} }
POPREC(); POPREC();
return a; return a;
@@ -518,9 +551,11 @@ static js_Ast *bitxor(js_State *J, int notin)
{ {
js_Ast *a = bitand(J, notin); js_Ast *a = bitand(J, notin);
SAVEREC(); SAVEREC();
int line = J->lexline;
while (jsP_accept(J, '^')) { while (jsP_accept(J, '^')) {
INCREC(); INCREC();
a = EXP2(BITXOR, a, bitand(J, notin)); a = EXP2(BITXOR, a, bitand(J, notin));
line = J->lexline;
} }
POPREC(); POPREC();
return a; return a;
@@ -530,9 +565,11 @@ static js_Ast *bitor(js_State *J, int notin)
{ {
js_Ast *a = bitxor(J, notin); js_Ast *a = bitxor(J, notin);
SAVEREC(); SAVEREC();
int line = J->lexline;
while (jsP_accept(J, '|')) { while (jsP_accept(J, '|')) {
INCREC(); INCREC();
a = EXP2(BITOR, a, bitxor(J, notin)); a = EXP2(BITOR, a, bitxor(J, notin));
line = J->lexline;
} }
POPREC(); POPREC();
return a; return a;
@@ -541,6 +578,7 @@ static js_Ast *bitor(js_State *J, int notin)
static js_Ast *logand(js_State *J, int notin) static js_Ast *logand(js_State *J, int notin)
{ {
js_Ast *a = bitor(J, notin); js_Ast *a = bitor(J, notin);
int line = J->lexline;
if (jsP_accept(J, TK_AND)) { if (jsP_accept(J, TK_AND)) {
INCREC(); INCREC();
a = EXP2(LOGAND, a, logand(J, notin)); a = EXP2(LOGAND, a, logand(J, notin));
@@ -552,6 +590,7 @@ static js_Ast *logand(js_State *J, int notin)
static js_Ast *logor(js_State *J, int notin) static js_Ast *logor(js_State *J, int notin)
{ {
js_Ast *a = logand(J, notin); js_Ast *a = logand(J, notin);
int line = J->lexline;
if (jsP_accept(J, TK_OR)) { if (jsP_accept(J, TK_OR)) {
INCREC(); INCREC();
a = EXP2(LOGOR, a, logor(J, notin)); a = EXP2(LOGOR, a, logor(J, notin));
@@ -563,6 +602,7 @@ static js_Ast *logor(js_State *J, int notin)
static js_Ast *conditional(js_State *J, int notin) static js_Ast *conditional(js_State *J, int notin)
{ {
js_Ast *a = logor(J, notin); js_Ast *a = logor(J, notin);
int line = J->lexline;
if (jsP_accept(J, '?')) { if (jsP_accept(J, '?')) {
js_Ast *b, *c; js_Ast *b, *c;
INCREC(); INCREC();
@@ -578,6 +618,7 @@ static js_Ast *conditional(js_State *J, int notin)
static js_Ast *assignment(js_State *J, int notin) static js_Ast *assignment(js_State *J, int notin)
{ {
js_Ast *a = conditional(J, notin); js_Ast *a = conditional(J, notin);
int line = J->lexline;
INCREC(); INCREC();
if (jsP_accept(J, '=')) a = EXP2(ASS, a, assignment(J, notin)); if (jsP_accept(J, '=')) a = EXP2(ASS, a, assignment(J, notin));
else if (jsP_accept(J, TK_MUL_ASS)) a = EXP2(ASS_MUL, a, assignment(J, notin)); else if (jsP_accept(J, TK_MUL_ASS)) a = EXP2(ASS_MUL, a, assignment(J, notin));
@@ -599,9 +640,11 @@ static js_Ast *expression(js_State *J, int notin)
{ {
js_Ast *a = assignment(J, notin); js_Ast *a = assignment(J, notin);
SAVEREC(); SAVEREC();
int line = J->lexline;
while (jsP_accept(J, ',')) { while (jsP_accept(J, ',')) {
INCREC(); INCREC();
a = EXP2(COMMA, a, assignment(J, notin)); a = EXP2(COMMA, a, assignment(J, notin));
line = J->lexline;
} }
POPREC(); POPREC();
return a; return a;
@@ -612,6 +655,7 @@ static js_Ast *expression(js_State *J, int notin)
static js_Ast *vardec(js_State *J, int notin) static js_Ast *vardec(js_State *J, int notin)
{ {
js_Ast *a = identifier(J); js_Ast *a = identifier(J);
int line = J->lexline;
if (jsP_accept(J, '=')) if (jsP_accept(J, '='))
return EXP2(VAR, a, assignment(J, notin)); return EXP2(VAR, a, assignment(J, notin));
return EXP1(VAR, a); return EXP1(VAR, a);
@@ -640,6 +684,7 @@ static js_Ast *statementlist(js_State *J)
static js_Ast *caseclause(js_State *J) static js_Ast *caseclause(js_State *J)
{ {
js_Ast *a, *b; js_Ast *a, *b;
int line = J->lexline;
if (jsP_accept(J, TK_CASE)) { if (jsP_accept(J, TK_CASE)) {
a = expression(J, 0); a = expression(J, 0);
@@ -671,6 +716,7 @@ static js_Ast *caselist(js_State *J)
static js_Ast *block(js_State *J) static js_Ast *block(js_State *J)
{ {
js_Ast *a; js_Ast *a;
int line = J->lexline;
jsP_expect(J, '{'); jsP_expect(J, '{');
a = statementlist(J); a = statementlist(J);
jsP_expect(J, '}'); jsP_expect(J, '}');
@@ -686,7 +732,7 @@ static js_Ast *forexpression(js_State *J, int end)
return a; return a;
} }
static js_Ast *forstatement(js_State *J) static js_Ast *forstatement(js_State *J, int line)
{ {
js_Ast *a, *b, *c, *d; js_Ast *a, *b, *c, *d;
jsP_expect(J, '('); jsP_expect(J, '(');
@@ -730,6 +776,7 @@ static js_Ast *statement(js_State *J)
{ {
js_Ast *a, *b, *c, *d; js_Ast *a, *b, *c, *d;
js_Ast *stm; js_Ast *stm;
int line = J->lexline;
INCREC(); INCREC();
@@ -779,7 +826,7 @@ static js_Ast *statement(js_State *J)
} }
else if (jsP_accept(J, TK_FOR)) { else if (jsP_accept(J, TK_FOR)) {
stm = forstatement(J); stm = forstatement(J, line);
} }
else if (jsP_accept(J, TK_CONTINUE)) { else if (jsP_accept(J, TK_CONTINUE)) {
@@ -851,7 +898,7 @@ static js_Ast *statement(js_State *J)
else if (jsP_accept(J, TK_FUNCTION)) { else if (jsP_accept(J, TK_FUNCTION)) {
jsP_warning(J, "function statements are not standard"); jsP_warning(J, "function statements are not standard");
stm = funstm(J); stm = funstm(J, line);
} }
/* labelled statement or expression statement */ /* labelled statement or expression statement */
@@ -881,8 +928,9 @@ static js_Ast *statement(js_State *J)
static js_Ast *scriptelement(js_State *J) static js_Ast *scriptelement(js_State *J)
{ {
int line = J->lexline;
if (jsP_accept(J, TK_FUNCTION)) if (jsP_accept(J, TK_FUNCTION))
return fundec(J); return fundec(J, line);
return statement(J); return statement(J);
} }
@@ -1008,6 +1056,7 @@ js_Ast *jsP_parse(js_State *J, const char *filename, const char *source)
js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body) js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body)
{ {
js_Ast *p = NULL; js_Ast *p = NULL;
int line = 0;
if (params) { if (params) {
jsY_initlex(J, filename, params); jsY_initlex(J, filename, params);
jsP_next(J); jsP_next(J);