From b1a5146ea8f8665df5edf2b26dcadc028d7929f7 Mon Sep 17 00:00:00 2001 From: mattn Date: Fri, 15 Feb 2013 04:38:27 +0900 Subject: Pluggable Regexp --- src/codegen.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/codegen.c') diff --git a/src/codegen.c b/src/codegen.c index 1f6d16477..a3e2995a0 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1910,6 +1910,23 @@ codegen(codegen_scope *s, node *tree, int val) } break; + case NODE_REGX: + if (val) { + char *p = (char*)tree->car; + size_t len = (intptr_t)tree->cdr; + int ai = mrb_gc_arena_save(s->mrb); + struct RClass* c = mrb_class_get(s->mrb, "Regexp"); + mrb_value args[1]; + args[0] = mrb_str_new(s->mrb, p, len); + int off = new_lit(s, + mrb_class_new_instance(s->mrb, 1, args, c)); + + mrb_gc_arena_restore(s->mrb, ai); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + push(); + } + break; + case NODE_SYM: if (val) { int sym = new_sym(s, sym(tree)); -- cgit v1.2.3 From 6aee0485fc5fa32b33be4f84fc588a94e3439d6c Mon Sep 17 00:00:00 2001 From: mattn Date: Fri, 15 Feb 2013 09:22:59 +0900 Subject: Should be OP_LOADL --- src/codegen.c | 4 ++-- src/string.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/codegen.c') diff --git a/src/codegen.c b/src/codegen.c index a3e2995a0..d1242a29f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1915,14 +1915,14 @@ codegen(codegen_scope *s, node *tree, int val) char *p = (char*)tree->car; size_t len = (intptr_t)tree->cdr; int ai = mrb_gc_arena_save(s->mrb); - struct RClass* c = mrb_class_get(s->mrb, "Regexp"); + struct RClass* c = mrb_class_get(s->mrb, "Regexp"); mrb_value args[1]; args[0] = mrb_str_new(s->mrb, p, len); int off = new_lit(s, mrb_class_new_instance(s->mrb, 1, args, c)); mrb_gc_arena_restore(s->mrb, ai); - genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); push(); } break; diff --git a/src/string.c b/src/string.c index a778e4ed4..98f2fca46 100644 --- a/src/string.c +++ b/src/string.c @@ -652,6 +652,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr) static mrb_value mrb_str_match(mrb_state *mrb, mrb_value self/* x */) { + mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp Class not implemented"); return mrb_nil_value(); } -- cgit v1.2.3 From e0f25b1fda0c9c67526885fafdabf35d4d4039b7 Mon Sep 17 00:00:00 2001 From: mattn Date: Fri, 15 Feb 2013 13:55:41 +0900 Subject: ready to pass second argument of Regexp.new --- src/codegen.c | 13 ++++++++----- src/parse.y | 55 ++++++++++++++++++++++++++++++------------------------- src/re.h | 7 +------ 3 files changed, 39 insertions(+), 36 deletions(-) (limited to 'src/codegen.c') diff --git a/src/codegen.c b/src/codegen.c index d1242a29f..86cb5eb87 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -16,6 +16,7 @@ #include #include #include +#include "re.h" typedef mrb_ast_node node; typedef struct mrb_parser_state parser_state; @@ -1912,12 +1913,14 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_REGX: if (val) { - char *p = (char*)tree->car; - size_t len = (intptr_t)tree->cdr; + char *p1 = (char*)tree->car; + //char *p2 = (char*)tree->cdr; int ai = mrb_gc_arena_save(s->mrb); - struct RClass* c = mrb_class_get(s->mrb, "Regexp"); - mrb_value args[1]; - args[0] = mrb_str_new(s->mrb, p, len); + struct RClass* c = mrb_class_get(s->mrb, REGEXP_CLASS); + mrb_value args[2]; + args[0] = mrb_str_new(s->mrb, p1, strlen(p1)); + // TODO: Some regexp implementation does not have second argument + //args[1] = mrb_str_new(s->mrb, p2, strlen(p2)); int off = new_lit(s, mrb_class_new_instance(s->mrb, 1, args, c)); diff --git a/src/parse.y b/src/parse.y index 518985ea6..9af8682c1 100644 --- a/src/parse.y +++ b/src/parse.y @@ -708,11 +708,11 @@ new_dsym(parser_state *p, node *a) return cons((node*)NODE_DSYM, new_dstr(p, a)); } -// (:str . (s . len)) +// (:str . (a . a)) static node* -new_regx(parser_state *p, const char *s, int len) +new_regx(parser_state *p, const char *p1, const char* p2) { - return cons((node*)NODE_REGX, cons((node*)strndup(s, len), (node*)(intptr_t)len)); + return cons((node*)NODE_REGX, cons((node*)p1, (node*)p2)); } // (:backref . n) @@ -3401,26 +3401,6 @@ read_escape(parser_state *p) } } -static void -regx_options(parser_state *p) -{ - int c; - - newtok(p); - while (c = nextc(p), ISALPHA(c)) { - tokadd(p, c); - } - - pushback(p, c); - if (toklen(p)) { - char msg[128]; - tokfix(p); - snprintf(msg, sizeof(msg), "unknown regexp option %s - %s", - toklen(p) > 1 ? "s" : "", tok(p)); - yyerror(p, msg); - } -} - static int parse_string(parser_state *p, int term) { @@ -3465,8 +3445,33 @@ parse_string(parser_state *p, int term) p->sterm = 0; if (p->regexp) { - //regx_options(p); - yylval.nd = new_regx(p, tok(p), toklen(p)); + int f = 0; + int c; + char* s; + s = strndup(tok(p), toklen(p)); + newtok(p); + while (c = nextc(p), ISALPHA(c)) { + switch (c) { + case 'i': f |= 1; break; + case 'x': f |= 2; break; + case 'm': f |= 4; break; + default: tokadd(p, c); break; + } + } + pushback(p, c); + if (toklen(p)) { + char msg[128]; + free(s); + tokfix(p); + snprintf(msg, sizeof(msg), "unknown regexp option %s - %s", + toklen(p) > 1 ? "s" : "", tok(p)); + yyerror(p, msg); + } + char flag[4] = {0}; + if (f & 1) strcat(flag, "i"); + if (f & 2) strcat(flag, "x"); + if (f & 4) strcat(flag, "m"); + yylval.nd = new_regx(p, s, strdup(flag)); p->regexp = 0; return tREGEXP; diff --git a/src/re.h b/src/re.h index eafe50dc8..64dbd60dc 100644 --- a/src/re.h +++ b/src/re.h @@ -7,12 +7,7 @@ #ifndef RE_H #define RE_H -//#include -#include - -#include "node.h" -#include "st.h" - +//#define REGEXP_CLASS "HsRegexp" #define REGEXP_CLASS "Regexp" #endif -- cgit v1.2.3