Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 1664895074
Fetching contributors…

Cannot retrieve contributors at this time

1238 lines (1183 sloc) 57.104 kb
require 'sexp_processor' # for deep_clone FIX
require 'typed_sexp'
require 'pt_testcase'
require 'unique'
# TODO: str -> char * in ansi c
# TODO: add tests that mix types up to fuck up RubyC type checker
class R2CTestCase < ParseTreeTestCase
def self.add_skipped_tests *names
names.each do |name|
add_tests(name,
"Rewriter" => :same,
"TypeChecker" => :skip,
"CRewriter" => :skip,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
end
end
testcase_order.push(*%w(Ruby ParseTree Rewriter TypeChecker
CRewriter RubyToAnsiC RubyToRubyC))
# NOTE: all skipped tests are at the end of the file
add_tests("and",
"Rewriter" => :same,
"TypeChecker" => t(:and,
t(:call, nil, :a, t(:arglist), Type.bool),
t(:call, nil, :b, t(:arglist), Type.bool),
Type.bool),
"CRewriter" => :same,
"RubyToAnsiC" => "a() && b()",
"RubyToRubyC" => 'rb_funcall(self, rb_intern("a"), 0) && rb_funcall(self, rb_intern("b"), 0)')
add_tests("array",
"Rewriter" => :same,
"TypeChecker" => t(:array,
t(:lit, 1, Type.long),
t(:lit, :b, Type.symbol),
t(:str, "c", Type.str),
Type.hetero),
"CRewriter" => :same,
"RubyToAnsiC" => "1, \"b\", \"c\"",
"RubyToRubyC" => "LONG2NUM(1), ID2SYM(rb_intern(\"b\")), rb_str_new2(\"c\")")
add_tests("array_pct_W",
"Rewriter" => :same,
"TypeChecker" => t(:array,
t(:str, "a", Type.str),
t(:str, "b", Type.str),
t(:str, "c", Type.str)),
"CRewriter" => :same,
"RubyToAnsiC" => "\"a\", \"b\", \"c\"",
"RubyToRubyC" => "rb_str_new2(\"a\"), rb_str_new2(\"b\"), rb_str_new2(\"c\")")
add_tests("array_pct_w",
"Rewriter" => :same,
"TypeChecker" => t(:array,
t(:str, "a", Type.str),
t(:str, "b", Type.str),
t(:str, "c", Type.str)),
"CRewriter" => :same,
"RubyToAnsiC" => "\"a\", \"b\", \"c\"",
"RubyToRubyC" => "rb_str_new2(\"a\"), rb_str_new2(\"b\"), rb_str_new2(\"c\")")
add_tests("attrasgn_index_equals",
"Rewriter" => :same,
"TypeChecker" => t(:attrasgn,
t(:call, nil, :a, t(:arglist), Type.unknown),
:[]=,
t(:arglist,
t(:lit, 42, Type.long),
t(:lit, 24, Type.long))),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip) # TODO: rubyc should be ok with this
add_tests("attrasgn_index_equals_space",
"Rewriter" => :same,
"TypeChecker" => t(:block,
t(:lasgn, :a, t(:array), Type.unknown_list),
t(:attrasgn,
t(:lvar, :a, Type.unknown_list),
:[]=,
t(:arglist,
t(:lit, 42, Type.long),
t(:lit, 24, Type.long))), Type.unknown),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip) # TODO: rubyc should be ok with this
add_tests("attrset",
"Rewriter" => s(:defn, :writer=,
s(:args, :arg),
s(:scope,
s(:block,
s(:return,
s(:iasgn, :@writer, s(:lvar, :arg)))))),
"TypeChecker" => t(:defn, :writer=,
t(:args, t(:arg, Type.unknown)),
t(:scope,
t(:block,
t(:return,
t(:iasgn, :@writer,
t(:lvar, :arg, Type.unknown),
Type.unknown),
Type.void), Type.unknown), Type.void),
Type.function(Type.unknown,
[Type.unknown], Type.unknown)),
"CRewriter" => :same,
"RubyToAnsiC" => "void *\nwriter=(void * arg) {\nreturn self->writer = arg;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_writer_equals(VALUE self, VALUE arg) {\nreturn self->writer = arg;\n}")
add_tests("bools", # NOTE: not in pttc
"Rewriter" => :skip,
# TODO: why does return false have type void?
"TypeChecker" => t(:defn, :bools,
t(:args, t(:arg1, Type.value)),
t(:scope,
t(:block,
t(:if,
t(:call,
t(:lvar, :arg1, Type.value),
:nil?,
nil,
Type.bool),
t(:return,
t(:false, Type.bool),
Type.void),
t(:return,
t(:true, Type.bool),
Type.void),
Type.void),
Type.unknown),
Type.void),
Type.function(Type.unknown,
[Type.value], Type.bool)),
"CRewriter" => :same,
"RubyToAnsiC" => "bool\nbools(void * arg1) {\nif (arg1) {\nreturn 0;\n} else {\nreturn 1;\n}\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_bools(VALUE self, VALUE arg1) {\nif (NIL_P(arg1)) {\nreturn Qfalse;\n} else {\nreturn Qtrue;\n}\n}")
add_tests("case_stmt", # TODO: not in pttc
"Rewriter" => :skip,
"TypeChecker" => t(:defn, :case_stmt,
t(:args),
t(:scope,
t(:block,
t(:lasgn,
:var,
t(:lit, 2, Type.long),
Type.long),
t(:lasgn,
:result,
t(:str, "", Type.str),
Type.str),
t(:if,
t(:call,
t(:lvar, :var, Type.long),
:case_equal_long,
t(:arglist, t(:lit, 1, Type.long)),
Type.bool),
t(:block,
t(:call,
nil,
:puts,
t(:arglist,
t(:str, "something", Type.str)),
Type.void),
t(:lasgn,
:result,
t(:str, "red", Type.str),
Type.str),
Type.str),
t(:if,
t(:or,
t(:call,
t(:lvar, :var, Type.long),
:case_equal_long,
t(:arglist, t(:lit, 2, Type.long)),
Type.bool),
t(:call,
t(:lvar, :var, Type.long),
:case_equal_long,
t(:arglist, t(:lit, 3, Type.long)),
Type.bool),
Type.bool),
t(:lasgn,
:result,
t(:str, "yellow", Type.str),
Type.str),
t(:if,
t(:call,
t(:lvar, :var, Type.long),
:case_equal_long,
t(:arglist, t(:lit, 4, Type.long)),
Type.bool),
nil,
t(:lasgn,
:result,
t(:str, "green", Type.str),
Type.str),
Type.str),
Type.str),
Type.str),
t(:if,
t(:call,
t(:lvar, :result, Type.str),
:case_equal_str,
t(:arglist, t(:str, "red", Type.str)),
Type.bool),
t(:lasgn, :var, t(:lit, 1, Type.long), Type.long),
t(:if,
t(:call,
t(:lvar, :result, Type.str),
:case_equal_str,
t(:arglist, t(:str, "yellow", Type.str)),
Type.bool),
t(:lasgn, :var, t(:lit, 2, Type.long), Type.long),
t(:if,
t(:call,
t(:lvar, :result, Type.str),
:case_equal_str,
t(:arglist,
t(:str, "green", Type.str)),
Type.bool),
t(:lasgn,
:var,
t(:lit, 3, Type.long),
Type.long),
nil,
Type.long),
Type.long),
Type.long),
t(:return,
t(:lvar, :result, Type.str),
Type.void),
Type.unknown),
Type.void),
Type.function(Type.unknown, [], Type.str)),
"CRewriter" => :same,
# HACK: I don't like the semis after the if blocks, but it is a compromise right now
"RubyToAnsiC" => "str\ncase_stmt() {\nstr result;\nlong var;\nvar = 2;\nresult = \"\";\nif (case_equal_long(var, 1)) {\nputs(\"something\");\nresult = \"red\";\n} else {\nif (case_equal_long(var, 2) || case_equal_long(var, 3)) {\nresult = \"yellow\";\n} else {\nif (case_equal_long(var, 4)) {\n;\n} else {\nresult = \"green\";\n}\n}\n};\nif (case_equal_str(result, \"red\")) {\nvar = 1;\n} else {\nif (case_equal_str(result, \"yellow\")) {\nvar = 2;\n} else {\nif (case_equal_str(result, \"green\")) {\nvar = 3;\n}\n}\n};\nreturn result;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_case_stmt(VALUE self) {\nVALUE result;\nVALUE var;\nvar = LONG2NUM(2);\nresult = rb_str_new2(\"\");\nif (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(1))) {\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"something\"));\nresult = rb_str_new2(\"red\");\n} else {\nif (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(2)) || rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(3))) {\nresult = rb_str_new2(\"yellow\");\n} else {\nif (rb_funcall(var, rb_intern(\"===\"), 1, LONG2NUM(4))) {\n;\n} else {\nresult = rb_str_new2(\"green\");\n}\n}\n};\nif (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"red\"))) {\nvar = LONG2NUM(1);\n} else {\nif (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"yellow\"))) {\nvar = LONG2NUM(2);\n} else {\nif (rb_funcall(result, rb_intern(\"===\"), 1, rb_str_new2(\"green\"))) {\nvar = LONG2NUM(3);\n}\n}\n};\nreturn result;\n}")
add_tests("defn_args_none",
"Rewriter" => :same,
"TypeChecker" => t(:defn, :empty,
t(:args),
t(:scope,
t(:block,
t(:nil, Type.value),
Type.unknown),
Type.void),
Type.function(Type.unknown, [], Type.void)),
"CRewriter" => :same,
"RubyToAnsiC" => "void\nempty() {\nNULL;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_empty(VALUE self) {\nQnil;\n}")
add_tests("defn_is_something", # TODO: not in pttc
"Rewriter" => :skip,
"TypeChecker" => t(:defn, :something?,
t(:args),
t(:scope,
t(:block,
t(:nil, Type.value),
Type.unknown),
Type.void),
Type.function(Type.unknown, [], Type.void)),
"CRewriter" => :same,
"RubyToAnsiC" => "void\nis_something() {\nNULL;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_is_something(VALUE self) {\nQnil;\n}")
add_tests("defn_or",
"Rewriter" => :same,
"TypeChecker" => t(:defn, :|,
t(:args, t(:o, Type.unknown)),
t(:scope,
t(:block,
t(:nil, Type.value),
Type.unknown),
Type.void),
Type.function(Type.unknown, [Type.unknown],
Type.void)),
"CRewriter" => :same,
"RubyToAnsiC" => "void\nor(void * o) {\nNULL;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_or(VALUE self, VALUE o) {\nQnil;\n}")
add_tests("defn_zarray",
"Rewriter" => :same,
"TypeChecker" => t(:defn,
:zarray,
t(:args),
t(:scope,
t(:block,
t(:lasgn, :a, t(:array), Type.unknown_list),
t(:return,
t(:lvar,
:a, Type.unknown_list), Type.void),
Type.unknown), Type.void),
Type.function(Type.unknown, [], Type.unknown_list)),
"CRewriter" => :same,
"RubyToAnsiC" => "void *\nzarray() {\nvoid * a;\na = (void *) malloc(sizeof(void *) * 0);\nreturn a;\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_zarray(VALUE self) {\nVALUE a;\na = rb_ary_new2(0);\nreturn a;\n}")
add_tests("ensure",
"Rewriter" => :skip,
"TypeChecker" => t(:defn, :bbegin,
t(:args),
t(:scope,
t(:block,
t(:begin,
t(:ensure,
t(:rescue,
t(:call,
t(:lit, 1, Type.long),
:+,
t(:arglist, t(:lit, 1, Type.long)), Type.long),
t(:resbody,
t(:array, t(:const, :SyntaxError, Type.fucked)),
t(:block,
t(:lasgn, :e1, t(:gvar, :$!, Type.unknown),
Type.unknown),
t(:lit, 2, Type.long), Type.unknown),
t(:resbody,
t(:array, t(:const, :Exception, Type.fucked)),
t(:block,
t(:lasgn, :e2, t(:gvar, :$!, Type.unknown),
Type.unknown),
t(:lit, 3, Type.long), Type.unknown),
Type.unknown), Type.long),
t(:lit, 4, Type.long), Type.long),
t(:lit, 5, Type.long))), Type.unknown),
Type.void),
Type.function(Type.unknown, [], Type.void)),
"CRewriter" => :same,
"RubyToAnsiC" => :unsupported,
"RubyToRubyC" => :unsupported)
add_tests("global",
"Rewriter" => :same,
"TypeChecker" => :skip,
# TODO: test s(:gvar, :$stderr) != t(:gvar, $stderr, Type.file)
"TypeChecker" => t(:gvar, :$stderr, Type.file),
"CRewriter" => :same,
"RubyToAnsiC" => "stderr",
"RubyToRubyC" => "rb_gv_get(\"$stderr\")")
add_tests("interpolated", # TODO: not in pttc
"Rewriter" => :skip,
"TypeChecker" => t(:dstr,
"var is ",
t(:lvar, :argl, Type.long),
t(:str, ". So there.", Type.str),
Type.str),
"CRewriter" => :same,
"RubyToAnsiC" => :unsupported,
"RubyToRubyC" => "rb_funcall(rb_mKernel, rb_intern(\"sprintf\"), 4, rb_str_new2(\"%s%s%s\"), rb_str_new2(\"var is \"), argl, rb_str_new2(\". So there.\"))")
add_tests("iter", # TODO: not in pttc
"Rewriter" => :skip,
"TypeChecker" => t(:iter,
t(:call, nil, :loop, nil, Type.unknown),
t(:dasgn_curr, :temp_1, Type.unknown),
nil,
Type.unknown),
"CRewriter" => :skip, # HACK don't do rb_iterate stuff for loop
# "CRewriter" => [:defx,
# t(:iter,
# t(:call, nil, :loop, nil, Type.unknown),
# t(:args,
# t(:array, t(:dasgn_curr, :temp_1, Type.unknown), Type.void),
# t(:array, Type.void), Type.void),
# t(:call, nil, :temp_1, nil)),
# [t(:defx,
# :temp_2,
# t(:args, :temp_2, :temp_3),
# t(:scope, t(:block, nil)), Type.void)]],
"RubyToAnsiC" => "",
"RubyToRubyC" => "")
add_tests("iter_downto",
"Rewriter" => :same,
"TypeChecker" => t(:iter,
t(:call,
t(:lit, 3, Type.long),
:downto,
t(:arglist, t(:lit, 1, Type.long)),
Type.unknown),
t(:lasgn, :n, nil, Type.long),
t(:call, nil, :puts,
t(:arglist,
t(:call,
t(:lvar, :n, Type.long),
:to_s,
t(:arglist),
Type.str)),
Type.void),
Type.void),
"CRewriter" => :skip,
"RubyToAnsiC" => "n = 1;\nwhile (n <= 3) {\nputs(to_s(n));\nn = n + 1;\n}",
"RubyToRubyC" => "n = LONG2NUM(1);\nwhile (rb_funcall(n, rb_intern(\"<=\"), 1, LONG2NUM(3))) {\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(n, rb_intern(\"to_s\"), 0));\nn = rb_funcall(n, rb_intern(\"+\"), 1, LONG2NUM(1));\n}")
add_tests("iter_each_lvar",
"Rewriter" => :same,
"TypeChecker" => t(:block,
t(:lasgn, :array,
t(:array,
t(:lit, 1, Type.long),
t(:lit, 2, Type.long),
t(:lit, 3, Type.long)),
Type.long_list),
t(:iter,
t(:call,
t(:lvar, :array, Type.long_list),
:each,
t(:arglist), Type.unknown),
t(:lasgn, :x, nil, Type.long),
t(:call, nil, :puts,
t(:arglist,
t(:call,
t(:lvar, :x, Type.long),
:to_s,
t(:arglist),
Type.str)),
Type.void),
Type.void),
Type.unknown),
"CRewriter" => [:defx,
t(:block,
t(:lasgn, :array,
t(:array,
t(:lit, 1, Type.long),
t(:lit, 2, Type.long),
t(:lit, 3, Type.long)),
Type.long_list),
t(:iter,
t(:call,
t(:lvar, :array, Type.long_list),
:each,
t(:arglist), Type.unknown),
t(:args,
t(:array, t(:lvar, :x, Type.value), Type.void),
t(:array, t(:lvar, :static_temp_4, Type.value), Type.void),
Type.void),
:temp_1),
Type.unknown),
[t(:static, "static VALUE static_temp_4;", Type.fucked),
t(:defx,
:temp_1,
t(:args,
t(:temp_2, Type.value),
t(:temp_3, Type.value)),
t(:scope,
t(:block,
t(:lasgn, :x,
t(:lvar, :static_temp_4, Type.value),
Type.value),
t(:masgn,
t(:array),
t(:to_ary,
t(:lvar, :temp_2, Type.value))),
t(:call,
nil,
:puts,
t(:arglist,
t(:call,
t(:lvar, :x, Type.long),
:to_s,
t(:arglist),
Type.str)),
Type.void),
t(:lasgn,
:static_temp_4,
t(:lvar, :x, Type.value),
Type.value),
t(:return, t(:nil, Type.value)))),
Type.void)]],
"RubyToAnsiC" => :skip, # because eric sucks soooo much
# 'unsigned long index_x;
# for (index_x = 0; arrays[index_x] != NULL; ++index_x) {
# str x = arrays[index_x];
# puts(x);
# }',
"RubyToRubyC" => :skip # indeed, there is an masgn when defx created
# [:defx,
# "array = rb_ary_new2(3);
# rb_ary_store(array, 0, LONG2NUM(1));
# rb_ary_store(array, 1, LONG2NUM(2));
# rb_ary_store(array, 2, LONG2NUM(3));
# static_temp_4 = x;
# rb_iterate(rb_each, array, temp_1, Qnil);
# x = static_temp_4;
# ",
# ["static VALUE static_temp_4;",
# "static VALUE
# rrc_c_temp_1(VALUE temp_2, VALUE temp_3) {
# VALUE arrays;
# VALUE x;
# arrays = static_temp_4;
# x = temp_2;
# rb_funcall(self, rb_intern(\"puts\"), 1, x);
# static_temp_4 = arrays;
# return Qnil;
# }"]]
)
add_tests("iter_each_nested",
"Rewriter" => :same,
"TypeChecker" => t(:block,
t(:lasgn, :array1,
t(:array,
t(:lit, 1, Type.long),
t(:lit, 2, Type.long),
t(:lit, 3, Type.long)), Type.long_list),
t(:lasgn, :array2,
t(:array,
t(:lit, 4, Type.long),
t(:lit, 5, Type.long),
t(:lit, 6, Type.long),
t(:lit, 7, Type.long)), Type.long_list),
t(:iter,
t(:call,
t(:lvar, :array1, Type.long_list),
:each,
t(:arglist), Type.unknown),
t(:lasgn, :x, nil, Type.long),
t(:iter,
t(:call,
t(:lvar, :array2, Type.long_list),
:each,
t(:arglist), Type.unknown),
t(:lasgn, :y, nil, Type.long),
t(:block,
t(:call, nil, :puts,
t(:arglist,
t(:call,
t(:lvar, :x, Type.long),
:to_s,
t(:arglist), Type.str)),
Type.void),
t(:call, nil, :puts,
t(:arglist,
t(:call,
t(:lvar, :y, Type.long),
:to_s,
t(:arglist), Type.str)),
Type.void),
Type.unknown),
Type.void),
Type.void),
Type.unknown),
"CRewriter" => :skip,
"RubyToAnsiC" => 'while (argl >= 1) {
puts("hello");
argl = argl - 1;
}',
"RubyToRubyC" => 'while (rb_funcall(argl, rb_intern(">="), 1, LONG2NUM(1))) {
rb_funcall(self, rb_intern("puts"), 1, rb_str_new2("hello"));
argl = rb_funcall(argl, rb_intern("-"), 1, LONG2NUM(1));
}')
add_tests("iter_while",
"Rewriter" => :same,
"TypeChecker" => t(:block,
t(:lasgn, :argl,
t(:lit, 10, Type.long), Type.long),
t(:while,
t(:call,
t(:lvar, :argl, Type.long),
:>=,
t(:arglist, t(:lit, 1, Type.long)), Type.bool),
t(:block,
t(:call, nil, :puts,
t(:arglist,
t(:str, 'hello', Type.str)),
Type.void),
t(:lasgn, :argl,
t(:call,
t(:lvar, :argl, Type.long),
:-,
t(:arglist, t(:lit, 1, Type.long)),
Type.long),
Type.long),
Type.unknown), true),
Type.unknown),
"CRewriter" => :same,
"RubyToAnsiC" => "argl = 10;\nwhile (argl >= 1) {\nputs(\"hello\");\nargl = argl - 1;\n}\n",
"RubyToRubyC" => "argl = LONG2NUM(10);\nwhile (rb_funcall(argl, rb_intern(\">=\"), 1, LONG2NUM(1))) {\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"hello\"));\nargl = rb_funcall(argl, rb_intern(\"-\"), 1, LONG2NUM(1));\n}\n")
add_tests("ivar",
"Rewriter" => s(:defn, :reader,
s(:args),
s(:scope, s(:block,
s(:return, s(:ivar, :@reader))))),
"TypeChecker" => :skip,
"CRewriter" => :skip,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
# TODO: this might still be too much
add_tests("lasgn_array",
"Rewriter" => :same,
"TypeChecker" => t(:lasgn,
:var,
t(:array,
t(:str, "foo", Type.str),
t(:str, "bar", Type.str)),
Type.str_list),
"CRewriter" => :same,
"RubyToRubyC" => 'var = rb_ary_new2(2);
rb_ary_store(var, 0, rb_str_new2("foo"));
rb_ary_store(var, 1, rb_str_new2("bar"))',
"RubyToAnsiC" => 'var = (str) malloc(sizeof(str) * 2);
var[0] = "foo";
var[1] = "bar"')
add_tests("lasgn_call",
"Rewriter" => :same,
"TypeChecker" => t(:lasgn, :c,
t(:call,
t(:lit, 2, Type.long),
:+,
t(:arglist,
t(:lit, 3, Type.long)),
Type.long),
Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "c = 2 + 3", # FIX: probably not "c =
"RubyToRubyC" => 'c = rb_funcall(LONG2NUM(2), rb_intern("+"), 1, LONG2NUM(3))')
add_tests("lit_bool_false",
"Rewriter" => :same,
"TypeChecker" => t(:false, Type.bool),
"CRewriter" => :same,
"RubyToAnsiC" => "0",
"RubyToRubyC" => "Qfalse")
add_tests("lit_bool_true",
"Rewriter" => :same,
"TypeChecker" => t(:true, Type.bool),
"CRewriter" => :same,
"RubyToAnsiC" => "1",
"RubyToRubyC" => "Qtrue")
add_tests("lit_float",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 1.1, Type.float),
"CRewriter" => :same,
"RubyToAnsiC" => "1.1",
"RubyToRubyC" => "rb_float_new(1.1)")
add_tests("lit_long",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 1, Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "1",
"RubyToRubyC" => "LONG2NUM(1)")
add_tests("lit_long_negative",
"Rewriter" => :same,
"TypeChecker" => t(:lit, -1, Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "-1",
"RubyToRubyC" => "LONG2NUM(-1)")
add_tests("lit_range2",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 1..10, Type.range),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_range3",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 1...10, Type.range),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_regexp",
"Rewriter" => :same,
"TypeChecker" => t(:lit, /x/, Type.regexp),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_regexp_i_wwtt",
"Rewriter" => :same,
"TypeChecker" => t(:call,
t(:call, nil, :str, t(:arglist), Type.unknown),
:split,
t(:arglist, t(:lit, //i, Type.regexp)),
Type.unknown),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_regexp_n",
"Rewriter" => :same,
"TypeChecker" => t(:lit, /x/n, Type.regexp),
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_regexp_once",
"Rewriter" => :same,
"TypeChecker" => t(:lit, /x/, Type.regexp), # HACK - once?
"CRewriter" => :same,
"RubyToAnsiC" => :skip,
"RubyToRubyC" => :skip)
add_tests("lit_str", # TODO: not in pttc
"ParseTree" => s(:str, "x"),
"Rewriter" => :same,
"TypeChecker" => t(:str, "x", Type.str),
"CRewriter" => :same,
"RubyToAnsiC" => '"x"',
"RubyToRubyC" => 'rb_str_new2("x")')
add_tests("lit_sym",
"Rewriter" => :same,
"TypeChecker" => t(:lit, :x, Type.symbol),
"CRewriter" => :same,
"RubyToAnsiC" => '"x"', # HACK WRONG! (or... is it?
"RubyToRubyC" => 'ID2SYM(rb_intern("x"))')
add_tests("lit_sym_splat",
"Rewriter" => :same,
"TypeChecker" => t(:lit, :"*args", Type.symbol),
"CRewriter" => :same,
"RubyToAnsiC" => '"*args"',
"RubyToRubyC" => 'ID2SYM(rb_intern("*args"))')
add_tests("multi_args", # TODO: not in pttc
"Ruby" => "def multi_args(arg1, arg2)
arg3 = arg1 * arg2 * 7
puts arg3.to_s
return \"foo\"
end",
"ParseTree" => s(:defn, :multi_args,
s(:args, :arg1, :arg2),
s(:scope,
s(:block,
s(:lasgn,
:arg3,
s(:call,
s(:call,
s(:lvar, :arg1),
:*,
s(:arglist, s(:lvar, :arg2))),
:*,
s(:arglist, s(:lit, 7)))),
s(:call,
nil,
:puts,
s(:arglist, s(:call, s(:lvar, :arg3),
:to_s, s(:arglist)))),
s(:return, s(:str, "foo"))))),
"Rewriter" => :same,
"TypeChecker" => t(:defn, :multi_args,
t(:args,
t(:arg1, Type.long),
t(:arg2, Type.long)),
t(:scope,
t(:block,
t(:lasgn,
:arg3,
t(:call,
t(:call,
t(:lvar, :arg1, Type.long),
:*,
t(:arglist, t(:lvar, :arg2, Type.long)),
Type.long),
:*,
t(:arglist, t(:lit, 7, Type.long)),
Type.long),
Type.long),
t(:call,
nil,
:puts,
t(:arglist,
t(:call,
t(:lvar, :arg3, Type.long),
:to_s,
t(:arglist),
Type.str)),
Type.void),
t(:return, t(:str, "foo", Type.str),
Type.void),
Type.unknown),
Type.void),
Type.function(Type.unknown,
[Type.long, Type.long], Type.str)),
"CRewriter" => :same,
"RubyToRubyC" => "static VALUE
rrc_c_multi_args(VALUE self, VALUE arg1, VALUE arg2) {
VALUE arg3;
arg3 = rb_funcall(rb_funcall(arg1, rb_intern(\"*\"), 1, arg2), rb_intern(\"*\"), 1, LONG2NUM(7));
rb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(arg3, rb_intern(\"to_s\"), 0));
return rb_str_new2(\"foo\");
}",
"RubyToAnsiC" => "str
multi_args(long arg1, long arg2) {
long arg3;
arg3 = arg1 * arg2 * 7;
puts(to_s(arg3));
return \"foo\";
}")
add_tests("not",
"Rewriter" => :same,
"TypeChecker" => t(:not, t(:true, Type.bool), Type.bool),
"CRewriter" => :same,
"RubyToAnsiC" => "!(1)",
"RubyToRubyC" => "!(Qtrue)")
add_tests("or",
"Rewriter" => :same,
"TypeChecker" => t(:or,
t(:call, nil, :a, t(:arglist), Type.bool),
t(:call, nil, :b, t(:arglist), Type.bool),
Type.bool),
"CRewriter" => :same,
"RubyToAnsiC" => 'a() || b()',
"RubyToRubyC" => 'rb_funcall(self, rb_intern("a"), 0) || rb_funcall(self, rb_intern("b"), 0)')
add_tests("vcall",
"Rewriter" => :same,
"TypeChecker" => t(:call, nil, :method, t(:arglist), Type.unknown),
"CRewriter" => :same,
"RubyToAnsiC" => "method()",
"RubyToRubyC" => "rb_funcall(self, rb_intern(\"method\"), 0)")
add_tests("whiles", # TODO: not in pttc
"Ruby" => "def whiles
while false do
puts \"false\"
end
begin
puts \"true\"
end while false
end",
"ParseTree" => s(:defn,
:whiles,
s(:args),
s(:scope,
s(:block,
s(:while, s(:false),
s(:call, nil, :puts,
s(:arglist, s(:str, "false"))),
true),
s(:while, s(:false),
s(:call, nil, :puts,
s(:arglist, s(:str, "true"))),
false)))),
"Rewriter" => :same,
"TypeChecker" => t(:defn,
:whiles,
t(:args),
t(:scope,
t(:block,
t(:while,
t(:false, Type.bool),
t(:call,
nil,
:puts,
t(:arglist, t(:str, "false", Type.str)), Type.void),
true),
t(:while,
t(:false, Type.bool),
t(:call,
nil,
:puts,
t(:arglist, t(:str, "true", Type.str)), Type.void),
false),
Type.unknown),
Type.void),
Type.function(Type.unknown, [], Type.void)),
"CRewriter" => :same,
"RubyToAnsiC" => "void\nwhiles() {\nwhile (0) {\nputs(\"false\");\n};\n{\nputs(\"true\");\n} while (0);\n}",
"RubyToRubyC" => "static VALUE\nrrc_c_whiles(VALUE self) {\nwhile (Qfalse) {\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"false\"));\n};\n{\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"true\"));\n} while (Qfalse);\n}")
add_tests("zarray",
"Rewriter" => :same,
"TypeChecker" => t(:lasgn, :a, t(:array), Type.unknown_list),
"CRewriter" => :same,
# TODO: need to verify that our variable decl will be correct
"RubyToAnsiC" => "a = (void *) malloc(sizeof(void *) * 0)",
"RubyToRubyC" => "a = rb_ary_new2(0)")
add_tests("str_question_control__18",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 129, Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "129",
"RubyToRubyC" => "LONG2NUM(129)")
add_tests("str_question_escape__18",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 10, Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "10",
"RubyToRubyC" => "LONG2NUM(10)")
add_tests("str_question_literal__18",
"Rewriter" => :same,
"TypeChecker" => t(:lit, 97, Type.long),
"CRewriter" => :same,
"RubyToAnsiC" => "97",
"RubyToRubyC" => "LONG2NUM(97)")
i_suck_and_my_tests_are_order_dependent!
add_skipped_tests("alias",
"alias_ugh",
"argscat_inside",
"argscat_svalue",
"argspush",
"array_pct_W_dstr",
"array_pct_w_dstr",
"attrasgn",
"back_ref",
"begin",
"begin_def",
"begin_rescue_ensure",
"begin_rescue_ensure_all_empty",
"begin_rescue_twice",
"begin_rescue_twice_mri_verbose_flag",
"block_attrasgn",
"block_lasgn",
"block_mystery_block",
"block_pass_args_and_splat",
"block_pass_call_0",
"block_pass_call_1",
"block_pass_call_n",
"block_pass_fcall_0",
"block_pass_fcall_1",
"block_pass_fcall_n",
"block_pass_omgwtf",
"block_pass_splat",
"block_pass_thingy",
"block_stmt_after",
"block_stmt_after_mri_verbose_flag",
"block_stmt_before",
"block_stmt_before_mri_verbose_flag",
"block_stmt_both",
"block_stmt_both_mri_verbose_flag",
"bmethod",
"bmethod_noargs",
"bmethod_splat",
"break",
"break_arg",
"call",
"call_arglist",
"call_arglist_hash",
"call_arglist_norm_hash",
"call_arglist_norm_hash_splat",
"call_arglist_space",
"call_command",
"call_expr",
"call_index",
"call_index_no_args",
"call_index_space",
"call_no_space_symbol",
"call_unary_neg",
"case",
"case_nested",
"case_nested_inner_no_expr",
"case_no_expr",
"case_splat",
"cdecl",
"class_plain",
"class_scoped",
"class_scoped3",
"class_super_array",
"class_super_expr",
"class_super_object",
"colon2",
"colon3",
"const",
"constX",
"constY",
"constZ",
"cvar",
"cvasgn",
"cvasgn_cls_method",
"cvdecl",
"dasgn_0",
"dasgn_1",
"dasgn_2",
"dasgn_curr",
"dasgn_icky",
"dasgn_mixed",
"defined",
"defn_args_block",
"defn_args_mand",
"defn_args_mand_block",
"defn_args_mand_opt",
"defn_args_mand_opt_block",
"defn_args_mand_opt_splat",
"defn_args_mand_opt_splat_block",
"defn_args_mand_opt_splat_no_name",
"defn_args_mand_splat",
"defn_args_mand_splat_block",
"defn_args_mand_splat_no_name",
"defn_args_opt",
"defn_args_opt_block",
"defn_args_opt_splat",
"defn_args_opt_splat_block",
"defn_args_opt_splat_no_name",
"defn_args_splat",
"defn_args_splat_no_name",
"defn_rescue",
"defn_rescue_mri_verbose_flag",
"defn_something_eh",
"defn_splat_no_name",
"defs",
"defs_empty",
"defs_empty_args",
"defs_expr_wtf",
"dmethod",
"dot2",
"dot3",
"dregx",
"dregx_interp",
"dregx_interp_empty",
"dregx_n",
"dregx_once",
"dregx_once_n_interp",
"dstr",
"dstr_2",
"dstr_3",
"dstr_concat",
"dstr_gross",
"dstr_heredoc_expand",
"dstr_heredoc_windoze_sucks",
"dstr_heredoc_yet_again",
"dstr_nest",
"dstr_str_lit_start",
"dstr_the_revenge",
"dsym",
"dxstr",
"false",
"fbody",
"fcall_arglist",
"fcall_arglist_hash",
"fcall_arglist_norm_hash",
"fcall_arglist_norm_hash_splat",
"fcall_block",
"fcall_index_space",
"fcall_inside_parens",
"fcall_keyword",
"flip2",
"flip2_method",
"flip3",
"for",
"for_no_body",
"gasgn",
"gvar",
"gvar_underscore",
"gvar_underscore_blah",
"hash",
"hash_rescue",
"iasgn",
"if_block_condition",
"if_lasgn_short",
"if_nested",
"if_post",
"if_post_not",
"if_pre",
"if_pre_not",
"iter_args_ivar__18",
"iter_call_arglist_space",
"iter_dasgn_curr_dasgn_madness",
"iter_loop_empty",
"iter_masgn_2",
"iter_masgn_args_ivar__18",
"iter_masgn_args_splat",
"iter_masgn_args_splat_no_name",
"iter_masgn_splat",
"iter_masgn_splat_no_name",
"iter_shadowed_var",
"iter_upto",
"lambda_args_anon_star",
"lambda_args_anon_star_block",
"lambda_args_block",
"lambda_args_norm_anon_star",
"lambda_args_norm_anon_star_block",
"lambda_args_norm_block",
"lambda_args_norm_comma",
"lambda_args_norm_comma2",
"lambda_args_norm_star",
"lambda_args_norm_star_block",
"lambda_args_star",
"lambda_args_star_block",
"lvar_def_boundary",
"masgn",
"masgn_argscat",
"masgn_attrasgn",
"masgn_attrasgn_array_rhs",
"masgn_attrasgn_idx",
"masgn_cdecl",
"masgn_iasgn",
"masgn_masgn",
"masgn_splat_lhs",
"masgn_splat_no_name_to_ary",
"masgn_splat_no_name_trailing",
"masgn_splat_rhs_1",
"masgn_splat_rhs_n",
"masgn_splat_to_ary",
"masgn_splat_to_ary2",
"match",
"match2",
"match3",
"module",
"module2",
"module_scoped",
"module_scoped3",
"next",
"next_arg",
"nth_ref",
"op_asgn1",
"op_asgn1_ivar",
"op_asgn2",
"op_asgn2_self",
"op_asgn_and",
"op_asgn_and_ivar2",
"op_asgn_or",
"op_asgn_or_block",
"op_asgn_or_ivar",
"op_asgn_or_ivar2",
"or_big",
"or_big2",
"parse_floats_as_args",
"postexe",
"proc_args_0",
"proc_args_1",
"proc_args_2",
"proc_args_no",
"redo",
"rescue",
"rescue_block_body",
"rescue_block_body_3",
"rescue_block_body_ivar",
"rescue_block_nada",
"rescue_exceptions",
"rescue_iasgn_var_empty",
"rescue_lasgn",
"rescue_lasgn_var",
"rescue_lasgn_var_empty",
"retry",
"return_0",
"return_1",
"return_1_splatted",
"return_n",
"sclass",
"sclass_trailing_class",
"splat",
"splat_array",
"splat_break",
"splat_break_array",
"splat_fcall",
"splat_fcall_array",
"splat_lasgn",
"splat_lasgn_array",
"splat_lit_1",
"splat_lit_n",
"splat_next",
"splat_next_array",
"splat_return",
"splat_return_array",
"splat_super",
"splat_super_array",
"splat_yield",
"splat_yield_array",
"str",
"str_concat_newline",
"str_concat_space",
"str_heredoc",
"str_heredoc_call",
"str_heredoc_double",
"str_heredoc_empty",
"str_heredoc_indent",
"str_interp_file",
"structure_extra_block_for_dvar_scoping",
"structure_remove_begin_1",
"structure_remove_begin_2",
"structure_unused_literal_wwtt",
"super_0",
"super_1",
"super_1_array",
"super_block_pass",
"super_block_splat",
"super_n",
"svalue",
"ternary_nil_no_space",
"ternary_symbol_no_spaces",
"to_ary",
"true",
"undef",
"undef_2",
"undef_3",
"undef_block_1",
"undef_block_2",
"undef_block_3",
"undef_block_3_post",
"undef_block_wtf",
"unless_post",
"unless_post_not",
"unless_pre",
"unless_pre_not",
"until_post",
"until_post_not",
"until_pre",
"until_pre_mod",
"until_pre_not",
"until_pre_not_mod",
"valias",
"while_post",
"while_post2",
"while_post_not",
"while_pre",
"while_pre_mod",
"while_pre_nil",
"while_pre_not",
"while_pre_not_mod",
"xstr",
"yield_0",
"yield_1",
"yield_array_0",
"yield_array_1",
"yield_array_n",
"yield_n",
"zsuper")
end
Jump to Line
Something went wrong with that request. Please try again.