move type resolution to compiler
from risc_value. also unite mock compilers
This commit is contained in:
parent
e3673e579c
commit
3343017dba
@ -136,7 +136,7 @@ module Risc
|
|||||||
case name
|
case name
|
||||||
when :receiver
|
when :receiver
|
||||||
message = Risc.message_reg
|
message = Risc.message_reg
|
||||||
ret_type = message.resolve_new_type(:receiver, compiler)
|
ret_type = compiler.slot_type(:receiver, message.type)
|
||||||
ret = compiler.use_reg( ret_type )
|
ret = compiler.use_reg( ret_type )
|
||||||
add_slot_to_reg(" load self" , message , :receiver , ret )
|
add_slot_to_reg(" load self" , message , :receiver , ret )
|
||||||
return ret
|
return ret
|
||||||
|
@ -65,6 +65,22 @@ module Risc
|
|||||||
return reg
|
return reg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# resolve the type of the slot, by inferring from it's name, using the type
|
||||||
|
# scope related slots are resolved by the compiler by methood/block
|
||||||
|
def slot_type( slot , type)
|
||||||
|
case slot
|
||||||
|
when :frame , :arguments , :receiver
|
||||||
|
new_type = self.resolve_type(slot)
|
||||||
|
when Symbol
|
||||||
|
new_type = type.type_for(slot)
|
||||||
|
raise "Not found object #{slot}: in #{type}" unless new_type
|
||||||
|
else
|
||||||
|
raise "Not implemented object #{slot}:#{slot.class}"
|
||||||
|
end
|
||||||
|
#puts "RESOLVE in #{@type.class_name} #{slot}->#{type}"
|
||||||
|
return new_type
|
||||||
|
end
|
||||||
|
|
||||||
def copy( reg , source )
|
def copy( reg , source )
|
||||||
copied = use_reg reg.type
|
copied = use_reg reg.type
|
||||||
add_code Register.transfer( source , reg , copied )
|
add_code Register.transfer( source , reg , copied )
|
||||||
|
@ -22,6 +22,7 @@ module Risc
|
|||||||
def initialize( reg , type , extra = {})
|
def initialize( reg , type , extra = {})
|
||||||
raise "Not Hash #{extra}" unless extra.is_a?(Hash)
|
raise "Not Hash #{extra}" unless extra.is_a?(Hash)
|
||||||
raise "not reg #{reg}" unless self.class.look_like_reg( reg )
|
raise "not reg #{reg}" unless self.class.look_like_reg( reg )
|
||||||
|
raise "No type " unless type
|
||||||
type = Parfait.object_space.get_type_by_class_name(type) if type.is_a?(Symbol)
|
type = Parfait.object_space.get_type_by_class_name(type) if type.is_a?(Symbol)
|
||||||
@type = type
|
@type = type
|
||||||
@symbol = reg
|
@symbol = reg
|
||||||
@ -53,7 +54,7 @@ module Risc
|
|||||||
# overwrite the message)
|
# overwrite the message)
|
||||||
# We get the type with resolve_new_type
|
# We get the type with resolve_new_type
|
||||||
def get_new_left(slot, compiler)
|
def get_new_left(slot, compiler)
|
||||||
new_type = resolve_new_type(slot , compiler)
|
new_type = compiler.slot_type(slot , type)
|
||||||
if( @symbol == :r0 )
|
if( @symbol == :r0 )
|
||||||
new_left = compiler.use_reg( new_type )
|
new_left = compiler.use_reg( new_type )
|
||||||
else
|
else
|
||||||
@ -62,22 +63,6 @@ module Risc
|
|||||||
new_left
|
new_left
|
||||||
end
|
end
|
||||||
|
|
||||||
# resolve the type of the slot, by inferring from it's name, using the type
|
|
||||||
# scope related slots are resolved by the compiler
|
|
||||||
def resolve_new_type(slot, compiler)
|
|
||||||
case slot
|
|
||||||
when :frame , :arguments , :receiver
|
|
||||||
type = compiler.resolve_type(slot)
|
|
||||||
when Symbol
|
|
||||||
type = @type.type_for(slot)
|
|
||||||
raise "Not found object #{slot}: in #{@type}" unless type
|
|
||||||
else
|
|
||||||
raise "Not implemented object #{slot}:#{slot.class}"
|
|
||||||
end
|
|
||||||
#puts "RESOLVE in #{@type.class_name} #{slot}->#{type}"
|
|
||||||
return type
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
s = "#{symbol}:#{type}"
|
s = "#{symbol}:#{type}"
|
||||||
s += ":#{value}" if value
|
s += ":#{value}" if value
|
||||||
|
@ -1,21 +1,6 @@
|
|||||||
require_relative '../helper'
|
require_relative '../helper'
|
||||||
|
|
||||||
module Mom
|
module Mom
|
||||||
class CompilerMock
|
|
||||||
# resolve a symbol to a type. Allowed symbols are :frame , :receiver and arguments
|
|
||||||
# which return the respective types, otherwise nil
|
|
||||||
def resolve_type( name )
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
def use_reg( type )
|
|
||||||
Risc.tmp_reg(type )
|
|
||||||
end
|
|
||||||
def reset_regs
|
|
||||||
|
|
||||||
end
|
|
||||||
def add_constant(c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class InstructionMock < Instruction
|
class InstructionMock < Instruction
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,7 +5,7 @@ module Mom
|
|||||||
class TestSlotDefinitionConstant < MiniTest::Test
|
class TestSlotDefinitionConstant < MiniTest::Test
|
||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
@compiler = CompilerMock.new
|
@compiler = Risc::FakeCompiler.new
|
||||||
@definition = SlotDefinition.new(StringConstant.new("hi") , [])
|
@definition = SlotDefinition.new(StringConstant.new("hi") , [])
|
||||||
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
||||||
end
|
end
|
||||||
|
@ -4,7 +4,7 @@ module Mom
|
|||||||
class TestSlotDefinitionKnown1 < MiniTest::Test
|
class TestSlotDefinitionKnown1 < MiniTest::Test
|
||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
@compiler = CompilerMock.new
|
@compiler = Risc::FakeCompiler.new
|
||||||
@definition = SlotDefinition.new(:message , :caller)
|
@definition = SlotDefinition.new(:message , :caller)
|
||||||
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
||||||
end
|
end
|
||||||
|
@ -4,7 +4,7 @@ module Mom
|
|||||||
class TestSlotDefinitionKnown2 < MiniTest::Test
|
class TestSlotDefinitionKnown2 < MiniTest::Test
|
||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
@compiler = CompilerMock.new
|
@compiler = Risc::FakeCompiler.new
|
||||||
@definition = SlotDefinition.new(:message , [:caller , :type])
|
@definition = SlotDefinition.new(:message , [:caller , :type])
|
||||||
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
@instruction = @definition.to_register(@compiler , InstructionMock.new)
|
||||||
end
|
end
|
||||||
|
@ -11,11 +11,11 @@ module Mom
|
|||||||
end
|
end
|
||||||
def test_fail_on_right
|
def test_fail_on_right
|
||||||
@load = SlotLoad.new( [:message, :caller] , [:receiver,:type] )
|
@load = SlotLoad.new( [:message, :caller] , [:receiver,:type] )
|
||||||
assert_raises {@load.to_risc(CompilerMock.new)}
|
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
||||||
end
|
end
|
||||||
def test_fail_on_left_long
|
def test_fail_on_left_long
|
||||||
@load = SlotLoad.new( [:message, :caller , :type] , [:receiver,:type] )
|
@load = SlotLoad.new( [:message, :caller , :type] , [:receiver,:type] )
|
||||||
assert_raises {@load.to_risc(CompilerMock.new)}
|
assert_raises {@load.to_risc(Risc::FakeCompiler.new)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ module Mom
|
|||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
@load = SlotLoad.new( [:message, :caller] , [:message,:type] )
|
@load = SlotLoad.new( [:message, :caller] , [:message,:type] )
|
||||||
@compiler = CompilerMock.new
|
@compiler = Risc::FakeCompiler.new
|
||||||
@instruction = @load.to_risc(@compiler)
|
@instruction = @load.to_risc(@compiler)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ module Mom
|
|||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
@load = SlotLoad.new( [:message, :caller, :type] , [:message, :caller , :type] )
|
@load = SlotLoad.new( [:message, :caller, :type] , [:message, :caller , :type] )
|
||||||
@compiler = CompilerMock.new
|
@compiler = Risc::FakeCompiler.new
|
||||||
@instruction = @load.to_risc(@compiler)
|
@instruction = @load.to_risc(@compiler)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
require_relative "../helper"
|
require_relative "../helper"
|
||||||
|
|
||||||
module Risc
|
module Risc
|
||||||
class FakeCompiler
|
|
||||||
def resolve_type(name)
|
|
||||||
Parfait.object_space.types.values.first
|
|
||||||
end
|
|
||||||
def use_reg(type)
|
|
||||||
RegisterValue.new(:r1 , type)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class TestRegisterValue < MiniTest::Test
|
class TestRegisterValue < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@ -25,13 +16,6 @@ module Risc
|
|||||||
def test_resolves_index_fail
|
def test_resolves_index_fail
|
||||||
assert_raises {@r0.resolve_index(:something)}
|
assert_raises {@r0.resolve_index(:something)}
|
||||||
end
|
end
|
||||||
def test_revolve_new_type_0
|
|
||||||
assert_equal :Message, @r0.resolve_new_type(:caller , @compiler)
|
|
||||||
end
|
|
||||||
def test_revolve_new_type_1
|
|
||||||
# returned by FakeCompiler , not real
|
|
||||||
assert_equal "BinaryCode_Type", @r1.resolve_new_type(:receiver , @compiler).name
|
|
||||||
end
|
|
||||||
def test_get_new_left_0
|
def test_get_new_left_0
|
||||||
assert_equal RegisterValue , @r0.get_new_left(:caller , @compiler).class
|
assert_equal RegisterValue , @r0.get_new_left(:caller , @compiler).class
|
||||||
end
|
end
|
||||||
|
17
test/support/fake_compiler.rb
Normal file
17
test/support/fake_compiler.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module Risc
|
||||||
|
class FakeCompiler
|
||||||
|
def slot_type(slot,type)
|
||||||
|
type.type_for(slot)
|
||||||
|
end
|
||||||
|
def resolve_type(name)
|
||||||
|
Parfait.object_space.types.values.first
|
||||||
|
end
|
||||||
|
def use_reg(type)
|
||||||
|
RegisterValue.new(:r1 , type)
|
||||||
|
end
|
||||||
|
def reset_regs
|
||||||
|
end
|
||||||
|
def add_constant(c)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user