diff options
| author | FUKUZAWA-Tadashi <[email protected]> | 2013-03-12 21:54:17 +0900 |
|---|---|---|
| committer | FUKUZAWA-Tadashi <[email protected]> | 2013-03-17 21:27:37 +0900 |
| commit | 44fbfc51849e6bad4f7238ad2fd9724af331cea2 (patch) | |
| tree | 81a351041f22d32e2e819dd94a5789474d038a7d /src/codegen.c | |
| parent | 7872bee70013ed0763942f6097ca0a61000fc92a (diff) | |
| download | mruby-44fbfc51849e6bad4f7238ad2fd9724af331cea2.tar.gz mruby-44fbfc51849e6bad4f7238ad2fd9724af331cea2.zip | |
implement literal %W %w %s
refactor string parsing
Diffstat (limited to 'src/codegen.c')
| -rw-r--r-- | src/codegen.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/src/codegen.c b/src/codegen.c index b9b52ad10..b80a030cb 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -956,6 +956,71 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) } static void +gen_send_intern(codegen_scope *s) +{ + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0)); + push(); +} +static void +gen_literal_array(codegen_scope *s, node *tree, int sym, int val) +{ + if (val) { + int i = 0, j = 0; + + while (tree) { + switch ((intptr_t)tree->car->car) { + case NODE_STR: + if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0)) + break; + /* fall through */ + case NODE_BEGIN: + codegen(s, tree->car, VAL); + ++j; + break; + + case NODE_LITERAL_DELIM: + if (j > 0) { + j = 0; + ++i; + if (sym) + gen_send_intern(s); + } + break; + + default: + codegen_error(s, "compiler bug on %W %w %I %i"); + } + if (j >= 2) { + pop(); pop(); + genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); + push(); + j = 1; + } + tree = tree->cdr; + } + if (j > 0) { + j = 0; + ++i; + if (sym) + gen_send_intern(s); + } + pop_n(i); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i)); + push(); + } + else { + while (tree) { + switch ((intptr_t)tree->car->car) { + case NODE_BEGIN: case NODE_BLOCK: + codegen(s, tree->car, NOVAL); + } + tree = tree->cdr; + } + } +} + +static void raise_error(codegen_scope *s, const char *msg) { int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); @@ -1933,9 +1998,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_HEREDOC: - /*if(tree == NULL){printf("heredoc error 1\n");exit(11);}*/ tree = ((struct mrb_parser_heredoc_info *)tree)->doc; - /*if(tree == NULL){printf("heredoc error 2\n");exit(12);}*/ /* fall through */ case NODE_DSTR: if (val) { @@ -1963,6 +2026,13 @@ codegen(codegen_scope *s, node *tree, int val) } break; + case NODE_WORDS: + gen_literal_array(s, tree, FALSE, val); + break; + case NODE_LITERAL_DELIM: + codegen_error(s, "compiler bug on %W %w %I %i"); + break; + case NODE_REGX: if (val) { char *p1 = (char*)tree->car; @@ -2061,9 +2131,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_DSYM: codegen(s, tree, val); if (val) { - pop(); - genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0)); - push(); + gen_send_intern(s); } break; |
