more class methods

This commit is contained in:
Torsten Ruger 2015-10-26 22:23:06 +02:00
parent 5b7c98f50b
commit 638c367e00
3 changed files with 53 additions and 19 deletions

View File

@ -3,45 +3,54 @@ module Soml
Compiler.class_eval do 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_ # 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. # So expressions move the data into a Register.
# In other words, their storage is the return slot as it would be for a method # 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 # But in the future (in the one that holds great things) we optimize those unneccesay moves away
def on_int statement def on_int expression
int = statement.first int = expression.first
reg = use_reg :Integer , int reg = use_reg :Integer , int
add_code Register::LoadConstant.new( statement, int , reg ) add_code Register::LoadConstant.new( expression, int , reg )
return reg return reg
end end
def on_true statement def on_true expression
reg = use_reg :Boolean reg = use_reg :Boolean
add_code Register::LoadConstant.new( statement, true , reg ) add_code Register::LoadConstant.new( expression, true , reg )
return reg return reg
end end
def on_false statement def on_false expression
reg = use_reg :Boolean reg = use_reg :Boolean
add_code Register::LoadConstant.new( statement, false , reg ) add_code Register::LoadConstant.new( expression, false , reg )
return reg return reg
end end
def on_nil statement def on_nil expression
reg = use_reg :NilClass reg = use_reg :NilClass
add_code Register::LoadConstant.new( statement, nil , reg ) add_code Register::LoadConstant.new( expression, nil , reg )
return reg return reg
end end
def on_string statement def on_string expression
value = statement.first.to_sym value = expression.first.to_sym
reg = use_reg :Word reg = use_reg :Word
@method.source.constants << value @method.source.constants << value
add_code Register::LoadConstant.new( statement, value , reg ) add_code Register::LoadConstant.new( expression, value , reg )
return reg return reg
end 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
end end

View File

@ -11,11 +11,17 @@ module Soml
new_message = Register.resolve_to_register(:new_message) new_message = Register.resolve_to_register(:new_message)
add_code Register.get_slot(@method, :message , :next_message , new_message ) add_code Register.get_slot(@method, :message , :next_message , new_message )
if receiver if receiver
me = process( receiver.to_a.first ) me = process( receiver.first )
else else
me = use_reg @method.for_class.name me = use_reg @method.for_class.name
add_code Register.get_slot(@method, :message , :receiver , me ) add_code Register.get_slot(@method, :message , :receiver , me )
end 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 # move our receiver there
add_code Register.set_slot( statement , me , :new_message , :receiver) add_code Register.set_slot( statement , me , :new_message , :receiver)
# load method name and set to new message (for exceptions/debug) # load method name and set to new message (for exceptions/debug)
@ -33,8 +39,7 @@ module Soml
add_code set add_code set
end end
# now we have to resolve the method name (+ receiver) into a callable method #puts "clazz #{clazz.name}"
clazz = Register.machine.space.get_class_by_name(me.type)
raise "No such class #{me.type}" unless clazz raise "No such class #{me.type}" unless clazz
method = clazz.get_instance_method(name) method = clazz.get_instance_method(name)
#puts Register.machine.space.get_class_by_name(:Integer).method_names.to_a #puts Register.machine.space.get_class_by_name(:Integer).method_names.to_a

View File

@ -21,6 +21,25 @@ HERE
check check
end end
def test_class_call
@string_input = <<HERE
class Bar
int self.buh()
return 1
end
end
class Object
int main()
return Bar.buh()
end
end
HERE
@length = 30
@expect = [Label, SaveReturn,GetSlot,LoadConstant,SetSlot,LoadConstant,SetSlot,
RegisterTransfer,FunctionCall,GetSlot,Label,RegisterTransfer,GetSlot,FunctionReturn]
check
end
def test_class_field_value def test_class_field_value
@string_input = <<HERE @string_input = <<HERE
class Object class Object
@ -43,6 +62,7 @@ class Object
end end
end end
HERE HERE
@length = 17
@expect = [Label, SaveReturn,GetSlot,GetSlot,Label,RegisterTransfer,GetSlot,FunctionReturn] @expect = [Label, SaveReturn,GetSlot,GetSlot,Label,RegisterTransfer,GetSlot,FunctionReturn]
check check
end end