shithub: libmujs

Download patch

ref: db3ae4ed23db3e5a63dac755cbd0af9c53909a68
parent: f323d6a9717496be399b9306b2baa8ac1c5707a3
author: Tor Andersson <[email protected]>
date: Mon Dec 23 18:13:24 EST 2013

Move yytext and yynumber into js_State.

Make yytext dynamically allocated and grown.

--- a/js-lex.c
+++ b/js-lex.c
@@ -67,6 +67,28 @@
 	{"with", JS_WITH},
 };
 
+static inline js_Token findkeyword(const char *s)
+{
+	int m, l, r;
+	int c;
+
+	l = 0;
+	r = nelem(keywords) - 1;
+
+	while (l <= r) {
+		m = (l + r) >> 1;
+		c = strcmp(s, keywords[m].string);
+		if (c < 0)
+			r = m - 1;
+		else if (c > 0)
+			l = m + 1;
+		else
+			return keywords[m].token;
+	}
+
+	return JS_IDENTIFIER;
+}
+
 const char *tokenstrings[] = {
 	"ERROR", "EOF", "(identifier)", "null", "true", "false", "(number)",
 	"(string)", "(regexp)", "\\n", "{", "}", "(", ")", "[", "]", ".", ";",
@@ -89,34 +111,34 @@
 	return tokenstrings[t];
 }
 
-#define UNGET() (*sp)--
-
-#define GET() *(*sp)++
+#define GET() (*(*sp)++)
+#define UNGET() ((*sp)--)
 #define PEEK() (**sp)
 #define NEXT() ((*sp)++)
 #define NEXTPEEK() (NEXT(), PEEK())
 #define LOOK(x) (PEEK() == x ? (NEXT(), 1) : 0)
 
-static inline js_Token findkeyword(const char *s)
+static void textinit(js_State *J)
 {
-	int m, l, r;
-	int c;
+	if (!J->yytext) {
+		J->yycap = 4096;
+		J->yytext = malloc(J->yycap);
+	}
+	J->yylen = 0;
+}
 
-	l = 0;
-	r = nelem(keywords) - 1;
-
-	while (l <= r) {
-		m = (l + r) >> 1;
-		c = strcmp(s, keywords[m].string);
-		if (c < 0)
-			r = m - 1;
-		else if (c > 0)
-			l = m + 1;
-		else
-			return keywords[m].token;
+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);
 	}
+	J->yytext[J->yylen++] = c;
+}
 
-	return JS_IDENTIFIER;
+static inline void textend(js_State *J)
+{
+	textpush(J, 0);
 }
 
 static inline int iswhite(int c)
@@ -129,29 +151,6 @@
 	return c == 0xa || c == 0xd || c == 0x2028 || c == 0x2029;
 }
 
-static inline void lexlinecomment(const char **sp)
-{
-	int c = PEEK();
-	while (c && !isnewline(c)) {
-		c = NEXTPEEK();
-	}
-}
-
-static inline int lexcomment(const char **sp)
-{
-	while (1) {
-		int c = GET();
-		if (c == '*') {
-			while (c == '*')
-				c = GET();
-			if (c == '/')
-				return 0;
-		} else if (c == 0) {
-			return -1;
-		}
-	}
-}
-
 static inline int isidentifierstart(int c)
 {
 	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '$' || c == '_';
@@ -183,6 +182,29 @@
 	return 0;
 }
 
+static inline void lexlinecomment(const char **sp)
+{
+	int c = PEEK();
+	while (c && !isnewline(c)) {
+		c = NEXTPEEK();
+	}
+}
+
+static inline int lexcomment(const char **sp)
+{
+	while (1) {
+		int c = GET();
+		if (c == '*') {
+			while (c == '*')
+				c = GET();
+			if (c == '/')
+				return 0;
+		} else if (c == 0) {
+			return -1;
+		}
+	}
+}
+
 static inline double lexhex(const char **sp)
 {
 	double n = 0;
@@ -231,7 +253,7 @@
 	return 0;
 }
 
-static inline js_Token lexnumber(const char **sp, double *yynumber)
+static inline js_Token lexnumber(js_State *J, const char **sp)
 {
 	double n;
 
@@ -239,7 +261,7 @@
 		*sp += 2;
 		if (!ishex(PEEK()))
 			return JS_ERROR;
-		*yynumber = lexhex(sp);
+		J->yynumber = lexhex(sp);
 		return JS_NUMBER;
 	}
 
@@ -254,7 +276,7 @@
 	if (isidentifierstart(PEEK()))
 		return JS_ERROR;
 
-	*yynumber = n;
+	J->yynumber = n;
 	return JS_NUMBER;
 }
 
@@ -288,11 +310,12 @@
 	}
 }
 
-static inline js_Token lexstring(int q, const char **sp, char *yytext, size_t yylen)
+static inline js_Token lexstring(js_State *J, const char **sp, int q)
 {
-	char *p = yytext;
 	int c = GET();
 
+	textinit(J);
+
 	while (c != q) {
 		if (c == 0 || isnewline(c))
 			return JS_ERROR;
@@ -300,18 +323,17 @@
 		if (c == '\\')
 			c = lexescape(sp);
 
-		if (p - yytext >= yylen)
-			return JS_ERROR;
-		*p++ = c;
+		textpush(J, c);
+
 		c = GET();
 	}
 
-	*p = 0;
+	textend(J);
 
 	return JS_STRING;
 }
 
-js_Token js_lex(js_State *J, const char **sp, char *yytext, size_t yylen, double *yynumber)
+js_Token js_lex(js_State *J, const char **sp)
 {
 	int c = GET();
 	while (c) {
@@ -335,27 +357,24 @@
 		}
 
 		if (isidentifierstart(c)) {
-			char *p = yytext;
+			textinit(J);
+			textpush(J, c);
 
-			*p++ = c;
-
 			c = PEEK();
 			while (isidentifierpart(c)) {
-				if (p - yytext >= yylen)
-					return JS_ERROR;
-				*p++ = c;
+				textpush(J, c);
 				c = NEXTPEEK();
 			}
 
-			*p = 0;
+			textend(J);
 
-			return findkeyword(yytext);
+			return findkeyword(J->yytext);
 		}
 
 		if (c == '.') {
 			if (isdec(PEEK())) {
 				UNGET();
-				return lexnumber(sp, yynumber);
+				return lexnumber(J, sp);
 			}
 			return JS_PERIOD;
 		}
@@ -362,11 +381,11 @@
 
 		if (c >= '0' && c <= '9') {
 			UNGET();
-			return lexnumber(sp, yynumber);
+			return lexnumber(J, sp);
 		}
 
 		if (c == '\'' || c == '"')
-			return lexstring(c, sp, yytext, yylen);
+			return lexstring(J, sp, c);
 
 		switch (c) {
 		case '{': return JS_LCURLY;
--- a/js-load.c
+++ b/js-load.c
@@ -2,19 +2,17 @@
 
 int js_loadstring(js_State *J, const char *source)
 {
-	char yytext[512];
-	double yynumber;
 	js_Token t;
 
 	do {
-		t = js_lex(J, &source, yytext, sizeof yytext, &yynumber);
+		t = js_lex(J, &source);
 
 		if (t == JS_NUMBER)
-			printf("%g\n", yynumber);
+			printf("%g\n", J->yynumber);
 		else if (t == JS_IDENTIFIER)
-			printf("id:%s\n", yytext);
+			printf("id:%s\n", J->yytext);
 		else if (t == JS_STRING)
-			printf("'%s'\n", yytext);
+			printf("'%s'\n", J->yytext);
 		else
 			printf("%s\n", js_tokentostring(t));
 	} while (t != JS_EOF && t != JS_ERROR);
--- a/js.h
+++ b/js.h
@@ -152,11 +152,12 @@
 
 struct js_State
 {
-	char yytext[512];
-	int top;
+	char *yytext;
+	size_t yylen, yycap;
+	double yynumber;
 };
 
-js_Token js_lex(js_State *J, const char **sp, char *yytext, size_t yylen, double *yynumber);
+js_Token js_lex(js_State *J, const char **sp);
 const char *js_tokentostring(js_Token t);
 
 #endif