use compiler base class for blocks too
can now go to mom level and add test harness still looks overly complicated, but works first block tests at mom level
This commit is contained in:
parent
a3e758357c
commit
27a142f2a3
@ -2,19 +2,18 @@ module Risc
|
|||||||
|
|
||||||
# A BlockCompiler is much like a Mehtodcompiler, exept for blocks
|
# A BlockCompiler is much like a Mehtodcompiler, exept for blocks
|
||||||
#
|
#
|
||||||
class BlockCompiler
|
class BlockCompiler < CallableCompiler
|
||||||
|
|
||||||
attr_reader :block , :risc_instructions , :constants
|
attr_reader :block , :risc_instructions , :constants
|
||||||
|
|
||||||
def initialize( block , method)
|
def initialize( block , method)
|
||||||
@method = method
|
@method = method
|
||||||
@regs = []
|
|
||||||
@block = block
|
@block = block
|
||||||
name = "#{method.self_type.name}.init"
|
super()
|
||||||
@risc_instructions = Risc.label(name, name)
|
end
|
||||||
@risc_instructions << Risc.label( name, "unreachable")
|
|
||||||
@current = @risc_instructions
|
def source_name
|
||||||
@constants = []
|
"#{@method.self_type.name}.init"
|
||||||
end
|
end
|
||||||
|
|
||||||
# determine how given name need to be accsessed.
|
# determine how given name need to be accsessed.
|
||||||
@ -35,5 +34,20 @@ module Risc
|
|||||||
slot_def << name
|
slot_def << name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# resolve a symbol to a type. Allowed symbols are :frame , :receiver and arguments
|
||||||
|
# which return the respective types, otherwise nil
|
||||||
|
def resolve_type( name )
|
||||||
|
case name
|
||||||
|
when :frame
|
||||||
|
return @block.frame_type
|
||||||
|
when :arguments
|
||||||
|
return @block.arguments_type
|
||||||
|
when :receiver
|
||||||
|
return @block.self_type
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -24,7 +24,7 @@ module Vool
|
|||||||
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)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,8 +38,16 @@ module MomCompile
|
|||||||
@method.source.to_mom( compiler )
|
@method.source.to_mom( compiler )
|
||||||
end
|
end
|
||||||
def compile_first_block( block_input )
|
def compile_first_block( block_input )
|
||||||
mom = compile_first_method( "main_local = 5 ; self.main{|val| #{block_input}}")
|
source = "main_local = 5 ; self.main{|val| #{block_input}}"
|
||||||
mom.next(4) # ignore local assign (1) and call (3)
|
vool = RubyX::RubyCompiler.compile( as_test_main(source) ).normalize
|
||||||
|
mom_c = vool.to_mom(nil)
|
||||||
|
compiler = mom_c.method_compilers.find{|c| c.get_method.name == :main and c.get_method.self_type.object_class.name == :Test}
|
||||||
|
block = nil
|
||||||
|
vool.each {|b| block = b if b.is_a?(Vool::BlockStatement)}
|
||||||
|
assert block
|
||||||
|
block_c = compiler.block_compilers.first
|
||||||
|
assert block_c
|
||||||
|
block.body.to_mom(block_c)
|
||||||
end
|
end
|
||||||
def compile_mom(input)
|
def compile_mom(input)
|
||||||
Risc.boot!
|
Risc.boot!
|
||||||
|
@ -10,8 +10,8 @@ module VoolBlocks
|
|||||||
@ins = compile_first_block( "local = 5")
|
@ins = compile_first_block( "local = 5")
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_class_compiles
|
def test_block_compiles
|
||||||
#assert_equal Mom::SlotLoad , @ins.class , @ins
|
assert_equal Mom::SlotLoad , @ins.class , @ins
|
||||||
end
|
end
|
||||||
def pest_slot_is_set
|
def pest_slot_is_set
|
||||||
assert @ins.left
|
assert @ins.left
|
||||||
|
Loading…
Reference in New Issue
Block a user