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
# 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

View File

@ -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

View File

@ -21,6 +21,25 @@ HERE
check
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
@string_input = <<HERE
class Object
@ -43,6 +62,7 @@ class Object
end
end
HERE
@length = 17
@expect = [Label, SaveReturn,GetSlot,GetSlot,Label,RegisterTransfer,GetSlot,FunctionReturn]
check
end