diff --git a/lib/arm/translator.rb b/lib/arm/translator.rb index b18aa8df..9e538845 100644 --- a/lib/arm/translator.rb +++ b/lib/arm/translator.rb @@ -40,7 +40,11 @@ module Arm def translate_SetSlot code # times 4 because arm works in bytes, but vm in words - ArmMachine.str( code.register , code.array , 4 * code.index ) + if(code.index.is_a? Numeric) + ArmMachine.str( code.register , code.array , 4 * code.index ) + else + ArmMachine.str( code.register , code.array , code.index ) + end end def translate_FunctionCall code diff --git a/lib/interpreter/interpreter.rb b/lib/interpreter/interpreter.rb index 675113c5..70defd1d 100644 --- a/lib/interpreter/interpreter.rb +++ b/lib/interpreter/interpreter.rb @@ -130,7 +130,11 @@ module Interpreter def execute_SetSlot value = get_register( @instruction.register ) object = get_register( @instruction.array ) - object.set_internal( @instruction.index , value ) + if( @instruction.index.is_a?(Numeric) ) + object.set_internal( @instruction.index , value ) + else + object.set_internal( get_register(@instruction.index) , value ) + end trigger(:object_changed, @instruction.array , @instruction.index) true end diff --git a/lib/register/boot.rb b/lib/register/boot.rb index 293d880f..fb20340d 100644 --- a/lib/register/boot.rb +++ b/lib/register/boot.rb @@ -140,7 +140,7 @@ module Register # have to define some dummies, just for the other to compile # TODO go through the virtual parfait layer and adjust function names to what they really are obj = @space.get_class_by_name(:Object) - [:main , :get_internal ].each do |f| + [:main , :get_internal , :set_internal ].each do |f| obj.add_instance_method Builtin::Object.send(f , nil) end obj = @space.get_class_by_name(:Kernel) diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index ca939aa2..5f7884a2 100644 --- a/lib/register/builtin/object.rb +++ b/lib/register/builtin/object.rb @@ -15,7 +15,7 @@ module Register # self[index] basically. Index is the first arg # return is stored in return_value - # (this method returns a new method off course, like all builting) + # (this method returns a new method off course, like all builtin) def get_internal context compiler = Soml::Compiler.new.create_method(:Object , :get_internal , []).init_method source = "get_internal" @@ -31,6 +31,24 @@ module Register return compiler.method end + # self[index] = val basically. Index is the first arg , vlaue the second + # no return + def set_internal context + compiler = Soml::Compiler.new.create_method(:Object , :set_internal , []).init_method + source = "set_internal" + #Load self by "calling" on_name + me = compiler.process( s(:name , :self) ) + # Load the index + index = compiler.use_reg :Integer + compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index ) + # Load the value + value = compiler.use_reg :Integer + compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(2), value ) + # do the set + compiler.add_code SetSlot.new( source , value , me , index) + return compiler.method + end + end extend ClassMethods end diff --git a/lib/register/instructions/set_slot.rb b/lib/register/instructions/set_slot.rb index 223b94f9..37a4ef7b 100644 --- a/lib/register/instructions/set_slot.rb +++ b/lib/register/instructions/set_slot.rb @@ -22,7 +22,8 @@ module Register @register = register @array = array @index = index - raise "not integer #{index}" unless index.is_a? Numeric + raise "index 0 " if index == 0 + raise "Not integer or reg #{index}" unless index.is_a?(Numeric) or RegisterValue.look_like_reg(index) raise "Not register #{register}" unless RegisterValue.look_like_reg(register) raise "Not register #{array}" unless RegisterValue.look_like_reg(array) end