use method missing in resolve method
not just exit try to print name next
This commit is contained in:
@ -62,10 +62,7 @@ module Mom
|
||||
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
|
||||
MethodMissing.new(compiler.source_name).to_risc(compiler)
|
||||
|
||||
add_code ok_label
|
||||
cache_entry[:cached_method] << callable_method
|
||||
|
@ -1,9 +1,17 @@
|
||||
module Mom
|
||||
# Init "method" is the first thing that happens in the machine
|
||||
# There is an inital jump to it, but that's it, no setup, no nothing
|
||||
#
|
||||
# The method is in quotes, because it is not really a method, it does not return!!
|
||||
# This is common to all double underscore "methods", but __init also does not
|
||||
# rely on the message. In fact it's job is to set up the first message
|
||||
# and to call the main (possibly later _init_ , single undescrore)
|
||||
#
|
||||
class Init < Macro
|
||||
def to_risc(compiler)
|
||||
builder = compiler.builder(compiler.source)
|
||||
main = Parfait.object_space.get_method!(:Space, :main)
|
||||
|
||||
# Set up the first message, but advance one, so main has somewhere to return to
|
||||
builder.build do
|
||||
factory! << Parfait.object_space.get_factory_for(:Message)
|
||||
message << factory[:next_object]
|
||||
@ -11,14 +19,14 @@ module Mom
|
||||
factory[:next_object] << next_message
|
||||
end
|
||||
builder.reset_names
|
||||
# Set up the call to main, with space as receiver
|
||||
Mom::MessageSetup.new(main).build_with( builder )
|
||||
|
||||
builder.build do
|
||||
message << message[:next_message]
|
||||
space? << Parfait.object_space
|
||||
message[:receiver] << space
|
||||
end
|
||||
|
||||
# set up return address and jump to main
|
||||
exit_label = Risc.label(compiler.source , "#{compiler.receiver_type.object_class.name}.#{compiler.source.name}" )
|
||||
ret_tmp = compiler.use_reg(:Label).set_builder(builder)
|
||||
builder.build do
|
||||
@ -28,7 +36,7 @@ module Mom
|
||||
add_code exit_label
|
||||
end
|
||||
compiler.reset_regs
|
||||
Macro.exit_sequence(builder)
|
||||
Macro.exit_sequence(builder) # exit will use mains return_value as exit_code
|
||||
return compiler
|
||||
end
|
||||
end
|
||||
|
@ -1,9 +1,12 @@
|
||||
module Mom
|
||||
class MethodMissing < Macro
|
||||
def to_risc(compiler)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.prepare_int_return # makes integer_tmp variable as return
|
||||
Macro.emit_syscall( builder , :exit )
|
||||
builder = compiler.builder(compiler.source_name)
|
||||
builder.build do
|
||||
factory! << Parfait.object_space.get_factory_for(:Integer)
|
||||
integer_tmp! << factory[:reserve]
|
||||
Mom::Macro.emit_syscall( builder , :died ) #uses integer_tmp
|
||||
end
|
||||
return compiler
|
||||
end
|
||||
end
|
||||
|
@ -14,15 +14,18 @@ module Mom
|
||||
@method_compilers = compilers
|
||||
end
|
||||
|
||||
# lazily instantiate the compiler for init function
|
||||
# lazily instantiate the compiler for __init__ function and __method_missing__
|
||||
def init_compiler
|
||||
@init_compilers ||= MomCollection.create_init_compiler
|
||||
@init_compilers ||= [
|
||||
MomCollection.create_init_compiler ,
|
||||
MomCollection.create_mm_compiler ,
|
||||
]
|
||||
end
|
||||
|
||||
# Return all compilers, namely the MethodCompilers passed in, plus the
|
||||
# boot_function's compilers (boot_compilers)
|
||||
def compilers
|
||||
@method_compilers << init_compiler
|
||||
@method_compilers + init_compiler
|
||||
end
|
||||
|
||||
# Append another MomCompilers method_compilers to this one.
|
||||
@ -41,23 +44,25 @@ module Mom
|
||||
Risc::RiscCollection.new(riscs)
|
||||
end
|
||||
|
||||
# this is the really really first place the machine starts (apart from the jump here)
|
||||
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
||||
# so it is responsible for initial setup:
|
||||
# - load fist message, set up Space as receiver
|
||||
# - call main, ie set up message for that etc
|
||||
# - exit (exit_sequence) which passes a machine int out to c
|
||||
def self.create_init_compiler
|
||||
compiler = compiler_for(:Object,:__init__ ,{})
|
||||
compiler._reset_for_init # no return, just for init
|
||||
compiler.add_code Init.new("missing")
|
||||
return compiler
|
||||
end
|
||||
def self.compiler_for( clazz_name , method_name , arguments , locals = {})
|
||||
frame = Parfait::NamedList.type_for( locals )
|
||||
args = Parfait::NamedList.type_for( arguments )
|
||||
MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame )
|
||||
end
|
||||
# See Init instruction. We must have an init (ie we need it in code), so it is created in code
|
||||
def self.create_init_compiler
|
||||
compiler = compiler_for(:Object,:__init__ ,{})
|
||||
compiler._reset_for_init # no return, just for init
|
||||
compiler.add_code Init.new("missing")
|
||||
return compiler
|
||||
end
|
||||
|
||||
def self.create_mm_compiler
|
||||
compiler = compiler_for(:Object,:__method_missing__ ,{})
|
||||
compiler.add_code MethodMissing.new("missing")
|
||||
return compiler
|
||||
end
|
||||
|
||||
def self.compiler_for( clazz_name , method_name , arguments , locals = {})
|
||||
frame = Parfait::NamedList.type_for( locals )
|
||||
args = Parfait::NamedList.type_for( arguments )
|
||||
MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user