diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index 0cb9dc58..c161e490 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -2,6 +2,8 @@ module Risc class Builder + attr_reader :built + def initialize(compiler) @compiler = compiler end @@ -11,15 +13,28 @@ module Risc name = args[0].to_s.capitalize.to_sym type = Risc.resolve_type(name , @compiler) reg = @compiler.use_reg( type ) + reg.builder = self puts reg reg end + def build(&block) + instance_eval(&block) + return built + end + def add_instruction(ins) + if(built) + built << ins + else + @built = ins + end + end end class RValue end + def self.build(compiler, &block) - Builder.new(compiler).instance_eval( &block ) + Builder.new(compiler).build( &block ) end # if a symbol is given, it may be the message or the new_message. diff --git a/lib/risc/risc_value.rb b/lib/risc/risc_value.rb index 9c38a9f1..ab74627e 100644 --- a/lib/risc/risc_value.rb +++ b/lib/risc/risc_value.rb @@ -4,9 +4,11 @@ module Risc class RiscValue - attr_accessor :symbol , :type , :value + attr_reader :symbol , :type , :value - def initialize r , type , value = nil + attr_accessor :builder + + def initialize( r , type , value = nil) raise "wrong type for register init #{r}" unless r.is_a? Symbol raise "double r #{r}" if r.to_s[0,1] == "rr" raise "not reg #{r}" unless self.class.look_like_reg r @@ -62,10 +64,14 @@ module Risc when RValue raise "not yet" when Parfait::Object - Risc.load_constant("#{load.class} to #{self.type}" , load , self) + ins = Risc.load_constant("#{load.class} to #{self.type}" , load , self) + when RiscValue + ins = Risc.transfer("#{load.type} to #{self.type}" , load , self) else raise "not implemented" end + builder.add_instruction(ins) if builder + return ins end end diff --git a/test/risc/test_builder.rb b/test/risc/test_builder.rb index 5e742b76..7333d0aa 100644 --- a/test/risc/test_builder.rb +++ b/test/risc/test_builder.rb @@ -2,5 +2,23 @@ require_relative "../helper" module Risc class TestBuilder < MiniTest::Test + + def setup + Risc.machine.boot + init = Parfait.object_space.get_init + compiler = Risc::MethodCompiler.new( init ) + @builder = Builder.new(compiler) + end + def test_has_build + assert_nil @builder.build{ } + end + def test_has_build_and_returns_built + r1 = RiscValue.new(:r1 , :Space) + built = @builder.build{ space << r1 } + assert_equal Transfer , built.class + end + def test_has_attribute + assert_nil @builder.built + end end end diff --git a/test/risc/test_risc_value.rb b/test/risc/test_risc_value.rb index a2a30610..77e628a9 100644 --- a/test/risc/test_risc_value.rb +++ b/test/risc/test_risc_value.rb @@ -1,6 +1,37 @@ require_relative "../helper" -module Risc - class TestRegisterValue < MiniTest::Test +class FakeBuilder + attr_reader :built + def add_instruction(ins) + @built = ins + end +end +module Risc + class TestRegisterValue < MiniTest::Test + + def setup + Risc.machine.boot + @r0 = RiscValue.new(:r0 , :Message) + @r1 = RiscValue.new(:r1 , :Space) + end + + def test_r0 + assert_equal :r0 , @r0.symbol + end + + def test_load_space + move = @r0 << Parfait.object_space + assert_equal LoadConstant , move.class + end + def test_transfer + transfer = @r0 << @r1 + assert_equal Transfer , transfer.class + end + def test_calls_builder + builder = FakeBuilder.new + @r0.builder = builder + @r0 << @r1 + assert_equal Transfer , builder.built.class + end end end