implement literal %W %w %s

refactor string parsing
This commit is contained in:
FUKUZAWA-Tadashi
2013-03-12 21:54:17 +09:00
parent 7872bee700
commit 44fbfc5184
6 changed files with 921 additions and 820 deletions
+73 -5
View File
@@ -955,6 +955,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)
{
@@ -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;