diff --git a/lib/bosl/compiler/callsite_expression.rb b/lib/bosl/compiler/callsite_expression.rb index 4a2859a9..a5537d4b 100644 --- a/lib/bosl/compiler/callsite_expression.rb +++ b/lib/bosl/compiler/callsite_expression.rb @@ -27,7 +27,36 @@ module Bosl method.source.add_code Virtual::Set.new( val , to ) compiled_args << to end - method.source.add_code Virtual::MessageSend.new(name , me , compiled_args) #and pass control + #method.source.add_code Virtual::MessageSend.new(name , me , compiled_args) #and pass control + method = nil + if(me.value) + me = me.value + if( me.is_a? Parfait::Class ) + raise "unimplemented #{code} me is #{me}" + elsif( me.is_a? Symbol ) + # get the function from my class. easy peasy + method = Virtual.machine.space.get_class_by_name(:Word).get_instance_method(name) + raise "Method not implemented #{me.class}.#{code.name}" unless method + @method.source.add_code Virtual::MethodCall.new( method ) + elsif( me.is_a? Fixnum ) + name = :plus if name == :+ + method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(name) + #puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a + raise "Method not implemented Integer.#{name}" unless method + @method.source.add_code Virtual::MethodCall.new( method ) + else + # note: this is the current view: call internal send, even the method name says else + # but send is "special" and accesses the internal method name and resolves. + kernel = Virtual.machine.space.get_class_by_name(:Kernel) + method = kernel.get_instance_method(:__send) + @method.source.add_code Virtual::MethodCall.new( method ) + raise "unimplemented: \n#{code} \nfor #{ref.inspect}" + end + else + method = @method + @method.source.add_code Virtual::MethodCall.new( @method ) + end + raise "Method not implemented #{me.value}.#{name}" unless method # the effect of the method is that the NewMessage Return slot will be filled, return it # (this is what is moved _inside_ above loop for such expressions that are calls (or constants)) Virtual::Return.new( method.source.return_type ) diff --git a/lib/virtual.rb b/lib/virtual.rb index 59e68477..6b5ebe3f 100644 --- a/lib/virtual.rb +++ b/lib/virtual.rb @@ -13,7 +13,6 @@ require "virtual/type" # the passes _are_ order dependant require "virtual/passes/minimizer" require "virtual/passes/collector" -require "virtual/passes/send_implementation" require "virtual/passes/get_implementation" require "virtual/passes/enter_implementation" require "virtual/passes/set_optimisation" diff --git a/lib/virtual/passes/send_implementation.rb b/lib/virtual/passes/send_implementation.rb deleted file mode 100644 index 8ba4505a..00000000 --- a/lib/virtual/passes/send_implementation.rb +++ /dev/null @@ -1,70 +0,0 @@ -module Virtual - # This implements the send logic - # Send is so complicated that we actually code it in ruby and stick it in - # That off course opens up an endless loop possibility that we stop by - # implementing Class and Module methods - - # Note: I find it slightly unsymmetrical that the NewMessage object needs to be created - # before this instruction. - # This is because all expressions create a (return) value and that return value is - # overwritten by the next expression unless saved. - # And since the message is the place to save it it needs to exist. qed - class SendImplementation - def run block - block.codes.dup.each do |code| - next unless code.is_a? MessageSend - new_codes = [ ] - ref = code.me - # value known at compile time, got do something with it - if(ref.value) - me = ref.value - if( me.is_a? Parfait::Class ) - raise "unimplemented #{code} me is #{me}" - elsif( me.is_a? Parfait::Object ) - # get the function from my class. easy peasy - puts "Me is #{me.class}" - method = me.get_class.get_instance_method(code.name) - raise "Method not implemented #{me.class}.#{code.name}" unless method - new_codes << MethodCall.new( method ) - elsif( me.is_a? Symbol ) - # get the function from my class. easy peasy - method = Virtual.machine.space.get_class_by_name(:Word).get_instance_method(code.name) - raise "Method not implemented #{me.class}.#{code.name}" unless method - new_codes << MethodCall.new( method ) - elsif( me.is_a? Fixnum ) - name = code.name - name = :plus if name == :+ - method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(name) - #puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a - raise "Method not implemented Integer.#{name}" unless method - new_codes << MethodCall.new( method ) - else - # note: this is the current view: call internal send, even the method name says else - # but send is "special" and accesses the internal method name and resolves. - kernel = Virtual.machine.space.get_class_by_name(:Kernel) - method = kernel.get_instance_method(:__send) - new_codes << MethodCall.new( method ) - raise "unimplemented: \n#{code} \nfor #{ref.inspect}" - end - else - if ref.type.is_a?(Reference) and ref.type.of_class - #find method and call - clazz = ref.type.of_class - begin - method = clazz.resolve_method code.name - rescue - raise "No method found #{code.name} for #{clazz.name} in #{clazz.method_names}" unless method - end - #puts "CALL is #{method.name}" - new_codes << MethodCall.new( method ) - else - # must defer send to run-time - # So inlining the code from message.send (in the future) - raise "not constant/ known object for send #{ref.inspect}" - end - end - block.replace(code , new_codes ) - end - end - end -end