ref: a476ffcc12421c576ed0658f0050a511adfc208f
parent: 33c60e4d7b9d598543fe19347bc3f6ef23ccb288
author: Tor Andersson <tor.andersson@artifex.com>
date: Sat Jan 11 07:47:08 EST 2014
Preserve regexp flags. Escape more characters when dumping strings.
--- a/js.h
+++ b/js.h
@@ -13,6 +13,10 @@
typedef struct js_StringNode js_StringNode;
typedef struct js_Ast js_Ast;
+#define JS_REGEXP_G 1
+#define JS_REGEXP_I 2
+#define JS_REGEXP_M 4
+
typedef int (*js_CFunction)(js_State *J);
js_State *js_newstate(void);
--- a/jsdump.c
+++ b/jsdump.c
@@ -92,17 +92,29 @@
static void pstr(const char *s)
{+ int c;
pc('"');- while (*s) {- if (*s == '"')
- ps("\\\"");- else
- pc(*s);
- ++s;
+ while ((c = *s++)) {+ switch (c) {+ case '"': ps("\\\""); break;+ case '\\': ps("\\\\"); break;+ case '\n': ps("\\n"); break;+ default: pc(c); break;
+ }
}
pc('"');}
+static void pregexp(const char *prog, int flags)
+{+ pc('/');+ ps(prog);
+ pc('/');+ if (flags & JS_REGEXP_G) pc('g');+ if (flags & JS_REGEXP_I) pc('i');+ if (flags & JS_REGEXP_M) pc('m');+}
+
static void pbin(int d, int i, js_Ast *exp, const char *op)
{ if (i) pc('(');@@ -127,7 +139,7 @@
case AST_IDENTIFIER: ps(exp->string); break;
case AST_NUMBER: printf("%.9g", exp->number); break;case AST_STRING: pstr(exp->string); break;
- case AST_REGEXP: pc('/'); ps(exp->string); pc('/'); break;+ case AST_REGEXP: pregexp(exp->string, exp->number); break;
case EXP_NULL: ps("null"); break; case EXP_TRUE: ps("true"); break;@@ -516,7 +528,7 @@
switch (node->type) { case AST_IDENTIFIER: pc(' '); ps(node->string); break; case AST_STRING: pc(' '); pstr(node->string); break;- case AST_REGEXP: printf(" /%s/", node->string); break;+ case AST_REGEXP: pc(' '); pregexp(node->string, node->number); break; case AST_NUMBER: printf(" %.9g", node->number); break;case STM_BLOCK: afun = sblock; break;
case STM_FUNC: case EXP_FUNC: cfun = sblock; break;
--- a/jslex.c
+++ b/jslex.c
@@ -361,6 +361,7 @@
static int lexregexp(js_State *J, const char **sp)
{const char *s;
+ int g, m, i;
int c;
textinit(J);
@@ -386,21 +387,25 @@
s = textend(J);
/* regexp flags */
- J->flags.g = J->flags.i = J->flags.m = 0;
+ g = i = m = 0;
c = PEEK();
while (isidentifierpart(c)) {- if (c == 'g') J->flags.g ++;
- else if (c == 'i') J->flags.i ++;
- else if (c == 'm') J->flags.m ++;
+ if (c == 'g') ++g;
+ else if (c == 'i') ++i;
+ else if (c == 'm') ++m;
else return jsP_error(J, "illegal flag in regular expression: %c", c);
c = NEXTPEEK();
}
- if (J->flags.g > 1 || J->flags.i > 1 || J->flags.m > 1)
+ if (g > 1 || i > 1 || m > 1)
return jsP_error(J, "duplicated flag in regular expression");
J->text = js_intern(J, s);
+ J->number = 0;
+ if (g) J->number += JS_REGEXP_G;
+ if (i) J->number += JS_REGEXP_I;
+ if (m) J->number += JS_REGEXP_M;
return TK_REGEXP;
}
--- a/jsparse.c
+++ b/jsparse.c
@@ -227,7 +227,7 @@
}
if (J->lookahead == TK_REGEXP) {a = jsP_newstrnode(J, AST_REGEXP, J->text);
- // TODO: flags
+ a->number = J->number;
next(J);
return a;
}
--- a/jsstate.h
+++ b/jsstate.h
@@ -21,7 +21,6 @@
int lookahead;
const char *text;
double number;
- struct { char g, i, m; } flags;js_Ast *ast; /* list of allocated nodes to free after parsing */
int strict;
--
⑨