Torsten Rüger
dced6b12e6
the "old" way of generating compilers is now obsolete we can use ruby code with mom macros to achieve the same Three step wip remove old builtin fix tests (including adding necessary methods) fixup and inclusion of builtin code to parfait
77 lines
2.2 KiB
Ruby
77 lines
2.2 KiB
Ruby
module Mom
|
|
|
|
# Dynamic method resolution is at the heart of a dynamic language, and here
|
|
# is the Mom level instruction to do it.
|
|
#
|
|
# When the static type can not be determined a CacheEntry is used to store
|
|
# type and method of the resolved method. The CacheEntry is shared with
|
|
# DynamicCall instruction who is responsible for calling the method in the entry.
|
|
#
|
|
# This instruction resolves the method, in case the types don't match (and
|
|
# at least on first encouter)
|
|
#
|
|
# This used to be a method, but we don't really need the method setup etc
|
|
#
|
|
class ResolveMethod < Instruction
|
|
attr :cache_entry , :name
|
|
|
|
# pass in source (VoolStatement)
|
|
# name of the method (don't knwow the actaual method)
|
|
# and the cache_entry
|
|
def initialize(source , name , cache_entry)
|
|
super(source)
|
|
@name = name
|
|
@cache_entry = cache_entry
|
|
end
|
|
|
|
def to_s
|
|
"ResolveMethod #{name}"
|
|
end
|
|
|
|
# When the method is resolved, a cache_entry is used to hold the result.
|
|
# That cache_entry (holding type and method) is checked before, and
|
|
# needs to be updated by this instruction.
|
|
#
|
|
# We use the type stored in the cache_entry to check the methods if any of it's
|
|
# names are the same as the given @name
|
|
#
|
|
# currently a fail results in sys exit
|
|
def to_risc( compiler )
|
|
name_ = @name
|
|
cache_entry_ = @cache_entry
|
|
builder = compiler.builder(self)
|
|
builder.build do
|
|
word! << name_
|
|
cache_entry! << cache_entry_
|
|
|
|
type! << cache_entry[:cached_type]
|
|
callable_method! << type[:methods]
|
|
|
|
add_code while_start_label
|
|
|
|
object! << Parfait.object_space.nil_object
|
|
object - callable_method
|
|
if_zero exit_label
|
|
|
|
name! << callable_method[:name]
|
|
name - word
|
|
|
|
if_zero ok_label
|
|
|
|
callable_method << callable_method[:next_callable]
|
|
branch while_start_label
|
|
|
|
add_code exit_label
|
|
# temporary, need to raise really.
|
|
factory! << Parfait.object_space.get_factory_for(:Integer)
|
|
integer_tmp! << factory[:reserve]
|
|
Mom::Macro.emit_syscall( builder , :died ) #uses integer_tmp
|
|
|
|
add_code ok_label
|
|
cache_entry[:cached_method] << callable_method
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|