get block resolution to use the extra
block_compiler puts in the extra, that we get out when resolving the type Thus block args work, though only by assuming direct call
This commit is contained in:
parent
280ea8a8c4
commit
ff8b95f21a
@ -16,6 +16,20 @@ module Risc
|
|||||||
"#{@method.self_type.name}.init"
|
"#{@method.self_type.name}.init"
|
||||||
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 method/block
|
||||||
|
#
|
||||||
|
# This mainly calls super, and only for :caller adds extra info
|
||||||
|
# Using the info, means assuming that the block is not passed around (FIXME in 2020)
|
||||||
|
def slot_type( slot , type)
|
||||||
|
new_type = super
|
||||||
|
if slot == :caller
|
||||||
|
extra_info = { type_frame: @method.frame_type ,
|
||||||
|
type_arguments: @method.arguments_type ,
|
||||||
|
type_self: @method.self_type}
|
||||||
|
end
|
||||||
|
return new_type , extra_info
|
||||||
|
end
|
||||||
# determine how given name need to be accsessed.
|
# determine how given name need to be accsessed.
|
||||||
# For blocks the options are args or frame
|
# For blocks the options are args or frame
|
||||||
# or then the methods arg or frame
|
# or then the methods arg or frame
|
||||||
|
@ -66,7 +66,7 @@ module Risc
|
|||||||
end
|
end
|
||||||
|
|
||||||
# resolve the type of the slot, by inferring from it's name, using the type
|
# 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
|
# scope related slots are resolved by the compiler by method/block
|
||||||
def slot_type( slot , type)
|
def slot_type( slot , type)
|
||||||
case slot
|
case slot
|
||||||
when :frame
|
when :frame
|
||||||
|
@ -9,7 +9,7 @@ module Risc
|
|||||||
# results of dsl operations (like <<) back to the builder
|
# results of dsl operations (like <<) back to the builder
|
||||||
class RegisterValue
|
class RegisterValue
|
||||||
|
|
||||||
attr_reader :symbol , :type , :value
|
attr_reader :symbol , :type , :extra
|
||||||
|
|
||||||
attr_accessor :builder
|
attr_accessor :builder
|
||||||
|
|
||||||
@ -20,13 +20,14 @@ module Risc
|
|||||||
# be :value, or :value_XX or :type_XX to indicate value or type information
|
# be :value, or :value_XX or :type_XX to indicate value or type information
|
||||||
# for an XX instance
|
# for an XX instance
|
||||||
def initialize( reg , type , extra = {})
|
def initialize( reg , type , extra = {})
|
||||||
|
extra = {} unless 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
|
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
|
||||||
@value = extra
|
@extra = extra
|
||||||
end
|
end
|
||||||
|
|
||||||
# using the registers type, resolve the slot to an index
|
# using the registers type, resolve the slot to an index
|
||||||
@ -54,18 +55,19 @@ 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 = compiler.slot_type(slot , type)
|
new_type = extra["type_#{slot}".to_sym]
|
||||||
|
new_type , extra = compiler.slot_type(slot , type) unless new_type
|
||||||
if( @symbol == :r0 )
|
if( @symbol == :r0 )
|
||||||
new_left = compiler.use_reg( new_type )
|
new_left = compiler.use_reg( new_type , extra)
|
||||||
else
|
else
|
||||||
new_left = RegisterValue.new( @symbol , new_type)
|
new_left = RegisterValue.new( @symbol , new_type , extra)
|
||||||
end
|
end
|
||||||
new_left
|
new_left
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
s = "#{symbol}:#{type}"
|
s = "#{symbol}:#{type}"
|
||||||
s += ":#{value}" if value
|
s += ":#{extra}" unless extra.empty?
|
||||||
s
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -93,11 +95,11 @@ module Risc
|
|||||||
end
|
end
|
||||||
|
|
||||||
#helper method to calculate with register symbols
|
#helper method to calculate with register symbols
|
||||||
def next_reg_use( type , value = nil )
|
def next_reg_use( type , extra = {} )
|
||||||
int = @symbol[1,3].to_i
|
int = @symbol[1,3].to_i
|
||||||
raise "No more registers #{self}" if int > 11
|
raise "No more registers #{self}" if int > 11
|
||||||
sym = "r#{int + 1}".to_sym
|
sym = "r#{int + 1}".to_sym
|
||||||
RegisterValue.new( sym , type, value)
|
RegisterValue.new( sym , type, extra)
|
||||||
end
|
end
|
||||||
|
|
||||||
def rxf_reference_name
|
def rxf_reference_name
|
||||||
|
@ -15,6 +15,7 @@ module Arm
|
|||||||
end
|
end
|
||||||
module ArmHelper
|
module ArmHelper
|
||||||
def setup
|
def setup
|
||||||
|
Parfait.boot!
|
||||||
@machine = Arm::ArmMachine
|
@machine = Arm::ArmMachine
|
||||||
@binary = FakeBin.new
|
@binary = FakeBin.new
|
||||||
Risc::Position.clear_positions
|
Risc::Position.clear_positions
|
||||||
|
@ -39,7 +39,7 @@ module Vool
|
|||||||
assert_equal 1, @block.frame_type.variable_index(:local)
|
assert_equal 1, @block.frame_type.variable_index(:local)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
class TestBlockMethod #< MiniTest::Test
|
class TestBlockMethod < MiniTest::Test
|
||||||
include MomCompile
|
include MomCompile
|
||||||
def setup
|
def setup
|
||||||
Parfait.boot!
|
Parfait.boot!
|
||||||
|
@ -19,6 +19,9 @@ module Risc
|
|||||||
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
|
||||||
|
def test_get_new_left_no_extra
|
||||||
|
assert @r0.get_new_left(:caller , @compiler).extra.empty?
|
||||||
|
end
|
||||||
def test_get_new_left_0_reg
|
def test_get_new_left_0_reg
|
||||||
assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol
|
assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol
|
||||||
end
|
end
|
||||||
@ -28,5 +31,10 @@ module Risc
|
|||||||
def test_get_new_left_1_reg
|
def test_get_new_left_1_reg
|
||||||
assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol
|
assert_equal :r1 , @r0.get_new_left(:caller , @compiler).symbol
|
||||||
end
|
end
|
||||||
|
def test_get_left_uses_extra
|
||||||
|
@r1 = RegisterValue.new(:r1 , :Space , type_arguments: @r0.type)
|
||||||
|
# works with nil as compiler, because extra is used
|
||||||
|
assert_equal :Message , @r1.get_new_left(:arguments , nil).type.class_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ module Risc
|
|||||||
def resolve_type(name)
|
def resolve_type(name)
|
||||||
Parfait.object_space.types.values.first
|
Parfait.object_space.types.values.first
|
||||||
end
|
end
|
||||||
def use_reg(type)
|
def use_reg(type , extra = {})
|
||||||
RegisterValue.new(:r1 , type)
|
RegisterValue.new(:r1 , type)
|
||||||
end
|
end
|
||||||
def reset_regs
|
def reset_regs
|
||||||
|
Loading…
Reference in New Issue
Block a user