Preserve regexp flags. Escape more characters when dumping strings.

This commit is contained in:
Tor Andersson
2014-01-11 12:47:08 +01:00
parent 33c60e4d7b
commit a476ffcc12
5 changed files with 35 additions and 15 deletions
+4
View File
@@ -13,6 +13,10 @@ typedef struct js_State js_State;
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);
+20 -8
View File
@@ -92,17 +92,29 @@ static void pobject(int d, js_Ast *list)
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 @@ static void pexpi(int d, int i, js_Ast *exp)
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 @@ static void snode(int d, js_Ast *node)
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;
+10 -5
View File
@@ -361,6 +361,7 @@ static int isregexpcontext(int last)
static int lexregexp(js_State *J, const char **sp)
{
const char *s;
int g, m, i;
int c;
textinit(J);
@@ -386,21 +387,25 @@ static int lexregexp(js_State *J, const char **sp)
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;
}
+1 -1
View File
@@ -227,7 +227,7 @@ static js_Ast *primary(js_State *J)
}
if (J->lookahead == TK_REGEXP) {
a = jsP_newstrnode(J, AST_REGEXP, J->text);
// TODO: flags
a->number = J->number;
next(J);
return a;
}
-1
View File
@@ -21,7 +21,6 @@ struct js_State
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;