implement ivar assignment
This commit is contained in:
parent
680fc7ecce
commit
83f2459a8a
@ -1,6 +1,18 @@
|
|||||||
module Vm
|
module Vm
|
||||||
module Assignment
|
module Assignment
|
||||||
|
|
||||||
|
def on_IvarAssignment( statement )
|
||||||
|
value = assignment_value(statement)
|
||||||
|
name = check_name(statement.name.name)
|
||||||
|
index = @method.for_type.variable_index( name)
|
||||||
|
raise "No such ivar #{name} #{@method.for_type}" unless index
|
||||||
|
value_type = @method.for_type.type_at( index )
|
||||||
|
raise "Argument Type mismatch #{value.type}!=#{value_type}" unless value.type == value_type
|
||||||
|
value_reg = use_reg(:value_type)
|
||||||
|
add_slot_to_reg(statement , :message , :receiver , value_reg )
|
||||||
|
add_reg_to_slot(statement , value , value_reg , index + 1 ) # one for type
|
||||||
|
end
|
||||||
|
|
||||||
def on_LocalAssignment( statement )
|
def on_LocalAssignment( statement )
|
||||||
do_assignment_for( statement , :local )
|
do_assignment_for( statement , :local )
|
||||||
end
|
end
|
||||||
@ -12,7 +24,7 @@ module Vm
|
|||||||
private
|
private
|
||||||
|
|
||||||
def do_assignment_for( statement , type )
|
def do_assignment_for( statement , type )
|
||||||
value = assignemnt_value(statement)
|
value = assignment_value(statement)
|
||||||
name = check_name(statement.name.name)
|
name = check_name(statement.name.name)
|
||||||
index = @method.send( "has_#{type}" , name)
|
index = @method.send( "has_#{type}" , name)
|
||||||
raise "No such #{type} #{name} #{@method.inspect}" unless index
|
raise "No such #{type} #{name} #{@method.inspect}" unless index
|
||||||
@ -27,7 +39,7 @@ module Vm
|
|||||||
add_reg_to_slot(statement , value , named_list , index + 1 ) # one for type
|
add_reg_to_slot(statement , value , named_list , index + 1 ) # one for type
|
||||||
end
|
end
|
||||||
|
|
||||||
def assignemnt_value(statement)
|
def assignment_value(statement)
|
||||||
reset_regs # statements reset registers, ie have all at their disposal
|
reset_regs # statements reset registers, ie have all at their disposal
|
||||||
value = process(statement.value)
|
value = process(statement.value)
|
||||||
raise "Not register #{v}" unless value.is_a?(Register::RegisterValue)
|
raise "Not register #{v}" unless value.is_a?(Register::RegisterValue)
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
require_relative '../helper'
|
require_relative '../helper'
|
||||||
|
|
||||||
module Register
|
module Register
|
||||||
|
module SpaceHack
|
||||||
|
# test hack to in place change object type
|
||||||
|
def add_space_field(name,type)
|
||||||
|
class_type = Parfait.object_space.get_class_by_name(:Space).instance_type
|
||||||
|
class_type.send(:private_add_instance_variable, name , type)
|
||||||
|
end
|
||||||
|
end
|
||||||
module ExpressionHelper
|
module ExpressionHelper
|
||||||
|
include SpaceHack
|
||||||
|
|
||||||
def check
|
def check
|
||||||
Register.machine.boot unless Register.machine.booted
|
Register.machine.boot unless Register.machine.booted
|
||||||
@ -14,17 +22,13 @@ module Register
|
|||||||
produced
|
produced
|
||||||
end
|
end
|
||||||
|
|
||||||
# test hack to in place change object type
|
|
||||||
def add_space_field(name,type)
|
|
||||||
class_type = Parfait.object_space.get_class_by_name(:Space).instance_type
|
|
||||||
class_type.send(:private_add_instance_variable, name , type)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Statements
|
module Statements
|
||||||
include AST::Sexp
|
include AST::Sexp
|
||||||
include Compiling
|
include Compiling
|
||||||
|
include SpaceHack
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Register.machine.boot # force boot to reset main
|
Register.machine.boot # force boot to reset main
|
||||||
end
|
end
|
||||||
|
@ -14,9 +14,16 @@ module Register
|
|||||||
assert_nil msg = check_nil , msg
|
assert_nil msg = check_nil , msg
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_assign_local
|
def test_assign_ivar_notpresent
|
||||||
Parfait.object_space.get_main.add_local(:r , :Integer)
|
@input =s(:statements, s(:i_assignment, s(:name, :r), s(:int, 5)))
|
||||||
@input =s(:statements, s(:l_assignment, s(:name, :r), s(:int, 5)))
|
@expect = []
|
||||||
|
assert_raises{ check_nil }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_assign_ivar
|
||||||
|
add_space_field(:r , :Integer)
|
||||||
|
|
||||||
|
@input =s(:statements, s(:i_assignment, s(:name, :r), s(:int, 5)))
|
||||||
|
|
||||||
@expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg ,
|
@expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg ,
|
||||||
RegToSlot, Label, FunctionReturn]
|
RegToSlot, Label, FunctionReturn]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user