shithub: libmujs

Download patch

ref: 45e2f80a80b796cdb4f4c50c30bc0ff2b765a6e2
parent: 08c76bd5343c15ac8e2d0f0b519c1a3ffae45856
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 9 20:35:37 EST 2014

Clean up interface between lexer and parser.

--- a/js-ast.c
+++ b/js-ast.c
@@ -6,7 +6,7 @@
 	js_Ast *node = malloc(sizeof(js_Ast));
 
 	node->type = type;
-	node->line = J->yyline;
+	node->line = J->line;
 	node->a = a;
 	node->b = b;
 	node->c = c;
@@ -20,14 +20,14 @@
 	return node;
 }
 
-js_Ast *jsP_newsnode(js_State *J, int type, const char *s)
+js_Ast *jsP_newstrnode(js_State *J, int type, const char *s)
 {
 	js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0);
-	node->s = js_intern(J, s);
+	node->s = s;
 	return node;
 }
 
-js_Ast *jsP_newnnode(js_State *J, int type, double n)
+js_Ast *jsP_newnumnode(js_State *J, int type, double n)
 {
 	js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0);
 	node->n = n;
--- a/js-ast.h
+++ b/js-ast.h
@@ -117,8 +117,8 @@
 };
 
 js_Ast *jsP_newnode(js_State *J, int type, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d);
-js_Ast *jsP_newsnode(js_State *J, int type, const char *s);
-js_Ast *jsP_newnnode(js_State *J, int type, double n);
+js_Ast *jsP_newstrnode(js_State *J, int type, const char *s);
+js_Ast *jsP_newnumnode(js_State *J, int type, double n);
 void jsP_freeast(js_State *J);
 
 void printast(js_Ast *n, int level);
--- a/js-lex.c
+++ b/js-lex.c
@@ -39,8 +39,10 @@
 static inline int findkeyword(js_State *J, const char *s)
 {
 	int i = findword(s, keywords, nelem(keywords));
-	if (i >= 0)
+	if (i >= 0) {
+		J->text = keywords[i];
 		return TK_BREAK + i; /* first keyword + i */
+	}
 
 	if (findword(s, futurewords, nelem(futurewords)) >= 0)
 		return jsP_error(J, "'%s' is a future reserved word", s);
@@ -47,6 +49,7 @@
 	if (J->strict && findword(s, strictfuturewords, nelem(strictfuturewords)) >= 0)
 		return jsP_error(J, "'%s' is a strict mode future reserved word", s);
 
+	J->text = js_intern(J, s);
 	return TK_IDENTIFIER;
 }
 
@@ -59,25 +62,26 @@
 
 static void textinit(js_State *J)
 {
-	if (!J->yytext) {
-		J->yycap = 4096;
-		J->yytext = malloc(J->yycap);
+	if (!J->buf.text) {
+		J->buf.cap = 4096;
+		J->buf.text = malloc(J->buf.cap);
 	}
-	J->yylen = 0;
+	J->buf.len = 0;
 }
 
 static inline void textpush(js_State *J, int c)
 {
-	if (J->yylen >= J->yycap) {
-		J->yycap = J->yycap * 2;
-		J->yytext = realloc(J->yytext, J->yycap);
+	if (J->buf.len >= J->buf.cap) {
+		J->buf.cap = J->buf.cap * 2;
+		J->buf.text = realloc(J->buf.text, J->buf.cap);
 	}
-	J->yytext[J->yylen++] = c;
+	J->buf.text[J->buf.len++] = c;
 }
 
-static inline void textend(js_State *J)
+static inline char *textend(js_State *J)
 {
 	textpush(J, 0);
+	return J->buf.text;
 }
 
 static inline int iswhite(int c)
@@ -200,7 +204,7 @@
 		*sp += 2;
 		if (!ishex(PEEK()))
 			return jsP_error(J, "0x not followed by hexademical digit");
-		J->yynumber = lexhex(sp);
+		J->number = lexhex(sp);
 		return TK_NUMBER;
 	}
 
@@ -215,7 +219,7 @@
 	if (isidentifierstart(PEEK()))
 		return jsP_error(J, "number with letter suffix");
 
-	J->yynumber = n;
+	J->number = n;
 	return TK_NUMBER;
 }
 
@@ -260,6 +264,7 @@
 
 static inline int lexstring(js_State *J, const char **sp, int q)
 {
+	const char *s;
 	int c = GET();
 
 	textinit(J);
@@ -276,8 +281,9 @@
 		c = GET();
 	}
 
-	textend(J);
+	s = textend(J);
 
+	J->text = js_intern(J, s);
 	return TK_STRING;
 }
 
@@ -302,6 +308,7 @@
 
 static int lexregexp(js_State *J, const char **sp)
 {
+	const char *s;
 	int c;
 
 	textinit(J);
@@ -324,23 +331,24 @@
 		}
 	}
 
-	textend(J);
+	s = textend(J);
 
 	/* regexp flags */
-	J->yyflags.g = J->yyflags.i = J->yyflags.m = 0;
+	J->flags.g = J->flags.i = J->flags.m = 0;
 
 	c = PEEK();
 	while (isidentifierpart(c)) {
-		if (c == 'g') J->yyflags.g ++;
-		else if (c == 'i') J->yyflags.i ++;
-		else if (c == 'm') J->yyflags.m ++;
+		if (c == 'g') J->flags.g ++;
+		else if (c == 'i') J->flags.i ++;
+		else if (c == 'm') J->flags.m ++;
 		else return jsP_error(J, "illegal flag in regular expression: %c", c);
 		c = NEXTPEEK();
 	}
 
-	if (J->yyflags.g > 1 || J->yyflags.i > 1 || J->yyflags.m > 1)
+	if (J->flags.g > 1 || J->flags.i > 1 || J->flags.m > 1)
 		return jsP_error(J, "duplicated flag in regular expression");
 
+	J->text = js_intern(J, s);
 	return TK_REGEXP;
 }
 
@@ -372,7 +380,7 @@
 			/* consume CR LF as one unit */
 			if (c == '\r' && PEEK() == '\n')
 				NEXT();
-			J->yyline++;
+			J->line++;
 			J->newline = 1;
 			if (isnlthcontext(J->lasttoken))
 				return ';';
@@ -408,7 +416,7 @@
 
 			textend(J);
 
-			return findkeyword(J, J->yytext);
+			return findkeyword(J, J->buf.text);
 		}
 
 		if (c >= '0' && c <= '9') {
@@ -535,17 +543,15 @@
 	}
 }
 
-void jsP_initlex(js_State *J, const char *source)
+void jsP_initlex(js_State *J, const char *filename, const char *source)
 {
-	J->yysource = source;
-	J->yyline = 1;
+	J->filename = filename;
+	J->source = source;
+	J->line = 1;
 	J->lasttoken = 0;
 }
 
 int jsP_lex(js_State *J)
 {
-	int t = lex(J, &J->yysource);
-	// TODO: move yytext/yynumber into jsP_lval
-	J->lasttoken = t;
-	return t;
+	return J->lasttoken = lex(J, &J->source);
 }
--- a/js-load.c
+++ b/js-load.c
@@ -1,22 +1,14 @@
 #include "js.h"
 #include "js-parse.h"
 
-static int jsP_loadstring(js_State *J, const char *source)
+static int jsP_loadstring(js_State *J, const char *filename, const char *source)
 {
-	int t;
-
-	jsP_initlex(J, source);
-	t = jsP_parse(J);
-	printf("parse result = %d\n", t);
-
-	return 0;
+	return jsP_parse(J, filename, source);
 }
 
-
 int js_loadstring(js_State *J, const char *source)
 {
-	J->yyfilename = "(string)";
-	return jsP_loadstring(J, source);
+	return jsP_loadstring(J, "(string)", source);
 }
 
 int js_loadfile(js_State *J, const char *filename)
@@ -48,8 +40,7 @@
 
 	s[n] = 0; /* zero-terminate string containing file data */
 
-	J->yyfilename = filename;
-	t = jsP_loadstring(J, s);
+	t = jsP_loadstring(J, filename, s);
 
 	free(s);
 	fclose(f);
--- a/js-parse.c
+++ b/js-parse.c
@@ -68,12 +68,12 @@
 	"'void'", "'while'", "'with'",
 };
 
-static void next(js_State *J)
+static inline void next(js_State *J)
 {
 	J->lookahead = jsP_lex(J);
 }
 
-static int accept(js_State *J, int t)
+static inline int accept(js_State *J, int t)
 {
 	if (J->lookahead == t) {
 		next(J);
@@ -82,7 +82,7 @@
 	return 0;
 }
 
-static void expect(js_State *J, int t)
+static inline void expect(js_State *J, int t)
 {
 	if (accept(J, t))
 		return;
@@ -103,7 +103,7 @@
 static js_Ast *identifier(js_State *J)
 {
 	if (J->lookahead == TK_IDENTIFIER) {
-		js_Ast *a = jsP_newsnode(J, AST_IDENTIFIER, J->yytext);
+		js_Ast *a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
 		next(J);
 		return a;
 	}
@@ -121,7 +121,7 @@
 static js_Ast *identifiername(js_State *J)
 {
 	if (J->lookahead == TK_IDENTIFIER || J->lookahead >= TK_BREAK) {
-		js_Ast *a = jsP_newsnode(J, AST_IDENTIFIER, J->yytext);
+		js_Ast *a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
 		next(J);
 		return a;
 	}
@@ -172,10 +172,10 @@
 {
 	js_Ast *name;
 	if (J->lookahead == TK_NUMBER) {
-		name = jsP_newnnode(J, AST_NUMBER, J->yynumber);
+		name = jsP_newnumnode(J, AST_NUMBER, J->number);
 		next(J);
 	} else if (J->lookahead == TK_STRING) {
-		name = jsP_newsnode(J, AST_STRING, J->yytext);
+		name = jsP_newstrnode(J, AST_STRING, J->text);
 		next(J);
 	} else {
 		name = identifiername(J);
@@ -187,7 +187,7 @@
 {
 	js_Ast *name, *value, *arg, *body;
 
-	if (J->lookahead == TK_IDENTIFIER && !strcmp(J->yytext, "get")) {
+	if (J->lookahead == TK_IDENTIFIER && !strcmp(J->text, "get")) {
 		next(J);
 		name = propname(J);
 		expect(J, '(');
@@ -196,7 +196,7 @@
 		return EXP2(PROP_GET, name, body);
 	}
 
-	if (J->lookahead == TK_IDENTIFIER && !strcmp(J->yytext, "set")) {
+	if (J->lookahead == TK_IDENTIFIER && !strcmp(J->text, "set")) {
 		next(J);
 		name = propname(J);
 		expect(J, '(');
@@ -234,17 +234,17 @@
 {
 	js_Ast *a;
 	if (J->lookahead == TK_IDENTIFIER) {
-		a = jsP_newsnode(J, AST_IDENTIFIER, J->yytext);
+		a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
 		next(J);
 		return a;
 	}
 	if (J->lookahead == TK_STRING) {
-		a = jsP_newsnode(J, AST_STRING, J->yytext);
+		a = jsP_newstrnode(J, AST_STRING, J->text);
 		next(J);
 		return a;
 	}
 	if (J->lookahead == TK_NUMBER) {
-		a = jsP_newnnode(J, AST_NUMBER, J->yynumber);
+		a = jsP_newnumnode(J, AST_NUMBER, J->number);
 		next(J);
 		return a;
 	}
@@ -808,7 +808,7 @@
 {
 	va_list ap;
 
-	fprintf(stderr, "syntax error: %s:%d: ", J->yyfilename, J->yyline);
+	fprintf(stderr, "syntax error: %s:%d: ", J->filename, J->line);
 
 	va_start(ap, fmt);
 	vfprintf(stderr, fmt, ap);
@@ -820,8 +820,10 @@
 	return 0;
 }
 
-int jsP_parse(js_State *J)
+int jsP_parse(js_State *J, const char *filename, const char *source)
 {
+	jsP_initlex(J, filename, source);
+
 	if (setjmp(J->jb)) {
 		jsP_freeast(J);
 		return 1;
--- a/js-state.c
+++ b/js-state.c
@@ -9,7 +9,7 @@
 
 void js_close(js_State *J)
 {
-	free(J->yytext);
+	free(J->buf.text);
 	free(J);
 }
 
--- a/js.h
+++ b/js.h
@@ -28,9 +28,9 @@
 
 typedef struct js_Ast js_Ast;
 
-void jsP_initlex(js_State *J, const char *source);
+void jsP_initlex(js_State *J, const char *filename, const char *source);
 int jsP_lex(js_State *J);
-int jsP_parse(js_State *J);
+int jsP_parse(js_State *J, const char *filename, const char *source);
 int jsP_error(js_State *J, const char *fmt, ...);
 
 void js_printstringtree(js_State *J);
@@ -37,24 +37,28 @@
 
 struct js_State
 {
-	const char *yyfilename;
-	const char *yysource;
-	int yyline;
+	jmp_buf jb; /* setjmp buffer for error handling in parser */
 
-	char *yytext;
-	size_t yylen, yycap;
-	double yynumber;
-	struct { int g, i, m; } yyflags;
+	js_StringNode *strings;
+
+	/* input */
+	const char *filename;
+	const char *source;
+	int line;
+
+	/* lexer */
+	struct { char *text; size_t len, cap; } buf;
 	int lasttoken;
 	int newline;
 
-	int strict;
-
+	/* parser */
 	int lookahead;
-	jmp_buf jb; /* setjmp buffer for error handling in parser */
+	const char *text;
+	double number;
+	struct { char g, i, m; } flags;
 	js_Ast *ast; /* list of allocated nodes to free after parsing */
 
-	js_StringNode *strings;
+	int strict;
 };
 
 #endif