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

View File

@ -10,7 +10,8 @@ module Risc
class CallableCompiler
def initialize( )
def initialize( callable )
@callable = callable
@regs = []
@risc_instructions = Risc.label(source_name, source_name)
@risc_instructions << Risc.label( source_name, "unreachable")
@ -18,7 +19,7 @@ module Risc
@constants = []
@block_compilers = []
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)
# continue down the instruction chain unti depleted

View File

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

View File

@ -1,19 +1,19 @@
module Vool
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
raise "no bod" unless @body
@clazz = clazz
end
def to_mom(clazz)
@clazz = clazz || raise( "no class in #{self}")
method = @clazz.add_method_for(name , make_arg_type , make_frame , body )
raise( "no class in #{self}") unless clazz
method = clazz.add_method_for(name , make_arg_type , make_frame , body )
compiler = method.compiler_for(clazz.instance_type)
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
compiler
end