Commit 22393503 authored by take_cheeze's avatar take_cheeze

Add test for backquote.

* Implement code generation of NODE_DXSTR.
* Fix NOVAL NODE_XSTR.
parent be58f1c9
......@@ -2087,14 +2087,48 @@ codegen(codegen_scope *s, node *tree, int val)
gen_literal_array(s, tree, TRUE, val);
break;
case NODE_DXSTR:
{
node *n;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
if (val == NOVAL) { push(); }
genop(s, MKOP_A(OP_OCLASS, cursp()));
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
push();
codegen(s, tree->car, VAL);
n = tree->cdr;
while (n) {
if ((intptr_t)n->car->car == NODE_XSTR) {
n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR;
mrb_assert(!n->cdr); /* must be the end */
}
codegen(s, n->car, VAL);
pop(); pop();
genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
push();
n = n->cdr;
}
pop();
pop();
sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
if (val == NOVAL) { pop(); }
else { push(); }
mrb_gc_arena_restore(s->mrb, ai);
}
break;
case NODE_XSTR:
if (val) {
{
char *p = (char*)tree->car;
size_t len = (intptr_t)tree->cdr;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
int off = new_lit(s, mrb_str_new(s->mrb, p, len));
if (val == NOVAL) { push(); }
genop(s, MKOP_A(OP_OCLASS, cursp()));
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
push();
......@@ -2102,8 +2136,9 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
if (val == NOVAL) { pop(); }
else { push(); }
mrb_gc_arena_restore(s->mrb, ai);
push();
}
break;
......
......@@ -226,3 +226,31 @@ assert('splat in case statement') do
assert_equal [5], resultb
assert_equal [3,8], resultc
end
assert('External command execution.') do
class << Kernel
sym = '`'.to_sym
alias_method :old_cmd, sym
results = []
define_method(sym) do |str|
results.push str
str
end
`test` # NOVAL NODE_XSTR
`test dynamic #{sym}` # NOVAL NODE_DXSTR
assert_equal ['test', 'test dynamic `'], results
t = `test` # VAL NODE_XSTR
assert_equal 'test', t
assert_equal ['test', 'test dynamic `', 'test'], results
t = `test dynamic #{sym}` # VAL NODE_DXSTR
assert_equal 'test dynamic `', t
assert_equal ['test', 'test dynamic `', 'test', 'test dynamic `'], results
alias_method sym, :old_cmd
end
true
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment