From 638c367e002eeb0aefb37a1a46c0b336fb113a86 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 26 Oct 2015 22:23:06 +0200 Subject: [PATCH] more class methods --- lib/soml/compiler/basic_values.rb | 41 ++++++++++++++++---------- lib/soml/compiler/call_site.rb | 11 +++++-- test/compiler/statements/test_class.rb | 20 +++++++++++++ 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/lib/soml/compiler/basic_values.rb b/lib/soml/compiler/basic_values.rb index 590c24ff..a0470f77 100644 --- a/lib/soml/compiler/basic_values.rb +++ b/lib/soml/compiler/basic_values.rb @@ -3,45 +3,54 @@ module Soml Compiler.class_eval do - # Constant statements can by definition be evaluated at compile time. + # Constant expressions can by definition be evaluated at compile time. # But that does not solve their storage, ie they need to be accessible at runtime from _somewhere_ - # So we view ConstantExpressions like functions that return the value of the constant. - # In other words, their storage is the return slot as it would be for a method + # So expressions move the data into a Register. + # All expressions return registers - # The current approach moves the constant into a variable before using it # But in the future (in the one that holds great things) we optimize those unneccesay moves away - def on_int statement - int = statement.first + def on_int expression + int = expression.first reg = use_reg :Integer , int - add_code Register::LoadConstant.new( statement, int , reg ) + add_code Register::LoadConstant.new( expression, int , reg ) return reg end - def on_true statement + def on_true expression reg = use_reg :Boolean - add_code Register::LoadConstant.new( statement, true , reg ) + add_code Register::LoadConstant.new( expression, true , reg ) return reg end - def on_false statement + def on_false expression reg = use_reg :Boolean - add_code Register::LoadConstant.new( statement, false , reg ) + add_code Register::LoadConstant.new( expression, false , reg ) return reg end - def on_nil statement + def on_nil expression reg = use_reg :NilClass - add_code Register::LoadConstant.new( statement, nil , reg ) + add_code Register::LoadConstant.new( expression, nil , reg ) return reg end - def on_string statement - value = statement.first.to_sym + def on_string expression + value = expression.first.to_sym reg = use_reg :Word @method.source.constants << value - add_code Register::LoadConstant.new( statement, value , reg ) + add_code Register::LoadConstant.new( expression, value , reg ) return reg end + + def on_class_name expression + name = expression.first + clazz = Parfait::Space.object_space.get_class_by_name! name + raise "No such class #{name}" unless clazz + reg = use_reg :Class , clazz + add_code Register::LoadConstant.new( expression, clazz , reg ) + return reg + end + end end diff --git a/lib/soml/compiler/call_site.rb b/lib/soml/compiler/call_site.rb index fee216b5..644be01b 100644 --- a/lib/soml/compiler/call_site.rb +++ b/lib/soml/compiler/call_site.rb @@ -11,11 +11,17 @@ module Soml new_message = Register.resolve_to_register(:new_message) add_code Register.get_slot(@method, :message , :next_message , new_message ) if receiver - me = process( receiver.to_a.first ) + me = process( receiver.first ) else me = use_reg @method.for_class.name add_code Register.get_slot(@method, :message , :receiver , me ) end + if(me.type == :Class) + clazz = me.value.meta + else + # now we have to resolve the method name (+ receiver) into a callable method + clazz = Register.machine.space.get_class_by_name(me.type) + end # move our receiver there add_code Register.set_slot( statement , me , :new_message , :receiver) # load method name and set to new message (for exceptions/debug) @@ -33,8 +39,7 @@ module Soml add_code set end - # now we have to resolve the method name (+ receiver) into a callable method - clazz = Register.machine.space.get_class_by_name(me.type) + #puts "clazz #{clazz.name}" raise "No such class #{me.type}" unless clazz method = clazz.get_instance_method(name) #puts Register.machine.space.get_class_by_name(:Integer).method_names.to_a diff --git a/test/compiler/statements/test_class.rb b/test/compiler/statements/test_class.rb index 2352a3d1..d977b359 100644 --- a/test/compiler/statements/test_class.rb +++ b/test/compiler/statements/test_class.rb @@ -21,6 +21,25 @@ HERE check end + def test_class_call + @string_input = <