push the callable into the callable compiler

thus generalizing for .callable access
keep block and method aliases for destinction in derived classes
This commit is contained in:
Torsten Ruger 2018-07-30 10:26:11 +03:00
parent 285a88b59f
commit 2dc03f8d1b
5 changed files with 32 additions and 29 deletions

View File

@ -5,11 +5,11 @@ module Risc
class BlockCompiler < CallableCompiler class BlockCompiler < CallableCompiler
attr_reader :block , :risc_instructions , :constants attr_reader :block , :risc_instructions , :constants
alias :block :callable
def initialize( block , method) def initialize( block , method)
@method = method @method = method
@block = block super(block)
super()
end end
def source_name def source_name
@ -34,9 +34,9 @@ module Risc
# For blocks the options are args or frame # For blocks the options are args or frame
# or then the methods arg or frame # or then the methods arg or frame
def slot_type_for(name) def slot_type_for(name)
if @block.arguments_type.variable_index(name) if @callable.arguments_type.variable_index(name)
slot_def = [:arguments] slot_def = [:arguments]
elsif @block.frame_type.variable_index(name) elsif @callable.frame_type.variable_index(name)
slot_def = [:frame] slot_def = [:frame]
elsif @method.arguments_type.variable_index(name) elsif @method.arguments_type.variable_index(name)
slot_def = [:caller , :arguments ] slot_def = [:caller , :arguments ]
@ -50,15 +50,15 @@ module Risc
# return the frame type, ie the blocks frame type # return the frame type, ie the blocks frame type
def frame_type def frame_type
@block.frame_type @callable.frame_type
end end
# return the frame type, ie the blocks arguments type # return the frame type, ie the blocks arguments type
def arg_type def arg_type
@block.arguments_type @callable.arguments_type
end end
# return the frame type, ie the blocks self_type # return the frame type, ie the blocks self_type
def receiver_type def receiver_type
@block.self_type @callable.self_type
end end
end end

View File

@ -10,7 +10,8 @@ module Risc
class CallableCompiler class CallableCompiler
def initialize( ) def initialize( callable )
@callable = callable
@regs = [] @regs = []
@risc_instructions = Risc.label(source_name, source_name) @risc_instructions = Risc.label(source_name, source_name)
@risc_instructions << Risc.label( source_name, "unreachable") @risc_instructions << Risc.label( source_name, "unreachable")
@ -18,7 +19,7 @@ module Risc
@constants = [] @constants = []
@block_compilers = [] @block_compilers = []
end end
attr_reader :risc_instructions , :constants , :block_compilers attr_reader :risc_instructions , :constants , :block_compilers , :callable
# convert the given mom instruction to_risc and then add it (see add_code) # convert the given mom instruction to_risc and then add it (see add_code)
# continue down the instruction chain unti depleted # continue down the instruction chain unti depleted

View File

@ -7,20 +7,22 @@ module Risc
class MethodCompiler < CallableCompiler class MethodCompiler < CallableCompiler
def initialize( method ) def initialize( method )
@method = method super(method)
super()
end end
def source_name def source_name
"#{@method.self_type.name}.#{@method.name}" "#{@callable.self_type.name}.#{@callable.name}"
end end
def get_method def get_method
@method @callable
end end
# sometimes the method is used as source (tb reviewed) # sometimes the method is used as source (tb reviewed)
def source def source
@method @callable
end end
# helper method for builtin mainly # helper method for builtin mainly
# the class_name is a symbol, which is resolved to the instance_type of that class # the class_name is a symbol, which is resolved to the instance_type of that class
# #
@ -33,12 +35,13 @@ module Risc
end end
def add_method_to( target ) def add_method_to( target )
target.add_method( @method ) target.add_method( @callable )
end end
def create_block(arg_type , frame_type) def create_block(arg_type , frame_type)
@method.create_block(arg_type ,frame_type) @callable.create_block(arg_type ,frame_type)
end end
# create a method for the given type ( Parfait type object) # create a method for the given type ( Parfait type object)
# method_name is a Symbol # method_name is a Symbol
# args a hash that will be converted to a type # args a hash that will be converted to a type
@ -55,7 +58,7 @@ module Risc
# determine how given name need to be accsessed. # determine how given name need to be accsessed.
# For methods the options are args or frame # For methods the options are args or frame
def slot_type_for(name) def slot_type_for(name)
if @method.arguments_type.variable_index(name) if @callable.arguments_type.variable_index(name)
type = :arguments type = :arguments
else else
type = :frame type = :frame
@ -69,23 +72,23 @@ module Risc
# return true or false if the given name is in scope (arg/local) # return true or false if the given name is in scope (arg/local)
def in_scope?(name) def in_scope?(name)
ret = true if @method.arguments_type.variable_index(name) ret = true if @callable.arguments_type.variable_index(name)
ret = @method.frame_type.variable_index(name) unless ret ret = @callable.frame_type.variable_index(name) unless ret
ret ret
end end
# return the frame type, ie the method frame type # return the frame type, ie the method frame type
def frame_type def frame_type
@method.frame_type @callable.frame_type
end end
# return the frame type, ie the method arguments type # return the frame type, ie the method arguments type
def arg_type def arg_type
@method.arguments_type @callable.arguments_type
end end
# return the frame type, ie the method self_type # return the frame type, ie the method self_type
def receiver_type def receiver_type
@method.self_type @callable.self_type
end end
# convert the given mom instruction to_risc and then add it (see add_code) # convert the given mom instruction to_risc and then add it (see add_code)

View File

@ -22,7 +22,6 @@ module Vool
def to_mom( compiler ) def to_mom( compiler )
parfait_block = self.parfait_block(compiler) parfait_block = self.parfait_block(compiler)
block_compiler = Risc::BlockCompiler.new( parfait_block , compiler.get_method ) block_compiler = Risc::BlockCompiler.new( parfait_block , compiler.get_method )
compiler.add_block_compiler(block_compiler)
head = body.to_mom( block_compiler ) head = body.to_mom( block_compiler )
block_compiler.add_mom(head) block_compiler.add_mom(head)
block_compiler block_compiler

View File

@ -1,19 +1,19 @@
module Vool module Vool
class MethodStatement < Statement class MethodStatement < Statement
attr_reader :name, :args , :body , :clazz attr_reader :name, :args , :body
def initialize( name , args , body , clazz = nil) def initialize( name , args , body )
@name , @args , @body = name , args , body @name , @args , @body = name , args , body
raise "no bod" unless @body raise "no bod" unless @body
@clazz = clazz
end end
def to_mom(clazz) def to_mom(clazz)
@clazz = clazz || raise( "no class in #{self}") raise( "no class in #{self}") unless clazz
method = @clazz.add_method_for(name , make_arg_type , make_frame , body ) method = clazz.add_method_for(name , make_arg_type , make_frame , body )
compiler = method.compiler_for(clazz.instance_type) compiler = method.compiler_for(clazz.instance_type)
each do |node| ## TODO: must account for nested blocks (someday) each do |node| ## TODO: must account for nested blocks (someday)
node.to_mom(compiler) if node.is_a?(BlockStatement) next unless node.is_a?(BlockStatement)
compiler.block_compilers << node.to_mom(compiler)
end end
compiler compiler
end end