diff --git a/lib/register/builtin/compile_helper.rb b/lib/register/builtin/compile_helper.rb new file mode 100644 index 00000000..cd0e5828 --- /dev/null +++ b/lib/register/builtin/compile_helper.rb @@ -0,0 +1,28 @@ + +module Register + module Builtin + module CompileHelper + + def self_and_arg(compiler , source) + #Load self by "calling" on_name + me = compiler.process( Typed::Tree::NameExpression.new( :self) ) + # Load the argument + index = compiler.use_reg :Integer + compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index ) + return me , index + end + + def compiler_for( method_name , args) + Typed::Compiler.new.create_method(:Object , method_name , args ).init_method + end + + # Load the value + def do_load(compiler, source) + value = compiler.use_reg :Integer + compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(2), value ) + value + end + + end + end +end diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index 302c603c..7f99a835 100644 --- a/lib/register/builtin/object.rb +++ b/lib/register/builtin/object.rb @@ -1,22 +1,18 @@ -require "ast/sexp" +require_relative "compile_helper" module Register module Builtin class Object module ClassMethods - include AST::Sexp + include CompileHelper # self[index] basically. Index is the first arg # return is stored in return_value # (this method returns a new method off course, like all builtin) def get_internal_word context - compiler = Typed::Compiler.new.create_method(:Object , :get_internal_word , {:index => :Integer}).init_method + compiler = compiler_for(:get_internal_word , {:index => :Integer}) source = "get_internal_word" - #Load self by "calling" on_name - me = compiler.process( Typed::Tree::NameExpression.new( :self) ) - # Load the argument - index = compiler.use_reg :Integer - compiler.add_code Register.get_slot(source , :message , Parfait::Message.get_indexed(1), index ) + me , index = self_and_arg(compiler,source) # reduce me to me[index] compiler.add_code GetSlot.new( source , me , index , me) # and put it back into the return value @@ -27,17 +23,11 @@ module Register # self[index] = val basically. Index is the first arg , value the second # no return def set_internal_word context - compiler = Typed::Compiler.new.create_method(:Object , :set_internal_word , - {:index => :Integer, :value => :Object} ).init_method + compiler = compiler_for(:set_internal_word , {:index => :Integer, :value => :Object} ) source = "set_internal_word" - #Load self by "calling" on_name - me = compiler.process( Typed::Tree::NameExpression.new( :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 ) + me , index = self_and_arg(compiler,source) + value = do_load(compiler,source) + # do the set compiler.add_code SetSlot.new( source , value , me , index) return compiler.method diff --git a/lib/register/machine.rb b/lib/register/machine.rb index 2c276f2c..c125caa7 100644 --- a/lib/register/machine.rb +++ b/lib/register/machine.rb @@ -26,14 +26,27 @@ module Register # now we just instantiate ArmTranslater and pass instructions def translate_arm translator = Arm::Translator.new + methods = collect_methods + translate_methods( methods , translator) + label = @init.next + @init = translator.translate( @init) + @init.append label + end + + def collect_methods methods = [] self.space.types.each do |hash , t| t.instance_methods.each do |f| methods << f end end + methods + end + + def translate_methods(methods , translator ) methods.each do |method| instruction = method.instructions + puts method.name while instruction.next nekst = instruction.next t = translator.translate(nekst) # returning nil means no replace @@ -44,12 +57,8 @@ module Register instruction = nekst end end - label = @init.next - @init = translator.translate( @init) - @init.append label end - # Objects are data and get assembled after functions def add_object o return false if @objects[o.object_id] diff --git a/lib/typed/compiler.rb b/lib/typed/compiler.rb index 9ce47759..5e3d681f 100644 --- a/lib/typed/compiler.rb +++ b/lib/typed/compiler.rb @@ -138,6 +138,9 @@ module Typed unless instruction.is_a?(Register::Instruction) raise instruction.to_s end + if( instruction.class.name.split("::").first == "Arm") + raise instruction.to_s + end @current.insert(instruction) #insert after current @current = instruction self