summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authortakahashim <[email protected]>2015-09-25 02:44:54 +0900
committertakahashim <[email protected]>2015-09-26 09:41:38 +0900
commitf187fdd996c8275ace52fe6e204ebbc3dad7cd31 (patch)
tree81069c1274eef535d04da45a1d55364b81305029
parent524a038876657a9cb062ec1e27015662e648d45f (diff)
downloadmruby-f187fdd996c8275ace52fe6e204ebbc3dad7cd31.tar.gz
mruby-f187fdd996c8275ace52fe6e204ebbc3dad7cd31.zip
support Regexp literal option: //n and //u
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c20
-rw-r--r--mrbgems/mruby-compiler/core/parse.y22
2 files changed, 33 insertions, 9 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index 3853814ec..f2bbf3497 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -2216,7 +2216,8 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_REGX:
if (val) {
char *p1 = (char*)tree->car;
- char *p2 = (char*)tree->cdr;
+ char *p2 = (char*)tree->cdr->car;
+ char *p3 = (char*)tree->cdr->cdr;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1));
@@ -2226,11 +2227,22 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
push();
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
- if (p2) {
+ if (p2 || p3) {
push();
- off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
- genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ if (p2) {
+ off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
+ genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ } else {
+ genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ }
argc++;
+ if (p3) {
+ push();
+ off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
+ genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ argc++;
+ pop();
+ }
pop();
}
pop();
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 097d63ac4..2b0591769 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -761,9 +761,9 @@ new_dsym(parser_state *p, node *a)
/* (:str . (a . a)) */
static node*
-new_regx(parser_state *p, const char *p1, const char* p2)
+new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
{
- return cons((node*)NODE_REGX, cons((node*)p1, (node*)p2));
+ return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
}
/* (:dregx . a) */
@@ -3986,6 +3986,8 @@ parse_string(parser_state *p)
char *s = strndup(tok(p), toklen(p));
char flags[3];
char *flag = flags;
+ char enc = '\0';
+ char *encp;
char *dup;
newtok(p);
@@ -3994,6 +3996,8 @@ parse_string(parser_state *p)
case 'i': f |= 1; break;
case 'x': f |= 2; break;
case 'm': f |= 4; break;
+ case 'u': f |= 16; break;
+ case 'n': f |= 32; break;
default: tokadd(p, re_opt); break;
}
}
@@ -4009,12 +4013,20 @@ parse_string(parser_state *p)
if (f & 1) *flag++ = 'i';
if (f & 2) *flag++ = 'x';
if (f & 4) *flag++ = 'm';
- dup = strndup(flags, (size_t)(flag - flags));
+ if (f & 16) enc = 'u';
+ if (f & 32) enc = 'n';
}
- else {
+ if (flag > flags) {
+ dup = strndup(flags, (size_t)(flag - flags));
+ } else {
dup = NULL;
}
- yylval.nd = new_regx(p, s, dup);
+ if (enc) {
+ encp = strndup(&enc, 1);
+ } else {
+ encp = NULL;
+ }
+ yylval.nd = new_regx(p, s, dup, encp);
return tREGEXP;
}