diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index 26b5b54b..2e210da9 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -24,6 +24,27 @@ module Risc @source_used = false end + # Infer the type from a symbol. In the simplest case the symbol is the class name. + # But in building, sometimes variations are needed, so next_message or caller work + # too (and both return "Message") + # A general "_reg"/"_obj"/"_const" or "_tmp" at the end of the name will be removed + # An error is raised if the symbol/object can not be inferred + def infer_type( name ) + as_string = name.to_s + parts = as_string.split("_") + if( ["reg" , "obj" , "tmp" , "self" , "const", "1" , "2"].include?( parts.last ) ) + parts.pop + as_string = parts.join("_") + end + as_string = "word" if as_string == "name" + as_string = "message" if as_string == "next_message" + as_string = "message" if as_string == "caller" + sym = as_string.camelise.to_sym + clazz = Parfait.object_space.get_class_by_name(sym) + raise "Not implemented/found object #{name}:#{sym}" unless clazz + return clazz.instance_type + end + def if_zero( label ) @source_used = true add_code Risc::IsZero.new(@source , label) diff --git a/test/risc/test_builder2.rb b/test/risc/test_builder2.rb new file mode 100644 index 00000000..1b56fc79 --- /dev/null +++ b/test/risc/test_builder2.rb @@ -0,0 +1,51 @@ +require_relative "../helper" + +module Risc + class TestBuilderInfer < MiniTest::Test + + def setup + Parfait.boot!(Parfait.default_test_options) + Risc.boot! + method = FakeCallable.new + @compiler = Risc::MethodCompiler.new( method, SlotMachine::Label.new( "source_name", "return_label") ) + @builder = @compiler.builder(method) + end + def test_list + assert_equal :List , @builder.infer_type(:list).class_name + end + def test_name + assert_equal :Word , @builder.infer_type(:name).class_name + end + def test_word + assert_equal :Word , @builder.infer_type(:word).class_name + end + def test_caller + assert_equal :Message , @builder.infer_type(:caller).class_name + end + def test_caller_reg + assert_equal :Message , @builder.infer_type(:caller_reg).class_name + end + def test_caller_tmp + assert_equal :Message , @builder.infer_type(:caller_tmp).class_name + end + def test_caller_obj + assert_equal :Message , @builder.infer_type(:caller_obj).class_name + end + def test_caller_const + assert_equal :Message , @builder.infer_type(:caller_const).class_name + end + def test_caller_self + assert_equal :Message , @builder.infer_type(:caller_self).class_name + end + def test_caller_1 + assert_equal :Message , @builder.infer_type(:caller_1).class_name + end + def test_message + assert_equal :Message , @builder.infer_type(:message).class_name + end + def test_next_message + assert_equal :Message , @builder.infer_type(:next_message).class_name + end + + end +end