fixing basic and field access to return register

as that is the new way, drop a layer, code to registers
This commit is contained in:
Torsten Ruger 2015-10-13 16:42:53 +03:00
parent 80d58ee03c
commit f506f95cbf
6 changed files with 48 additions and 45 deletions

View File

@ -13,37 +13,35 @@ module Phisol
def on_int statement def on_int statement
int = statement.first int = statement.first
# reg = reg = use_reg :int
to = Virtual::Return.new(Phisol::Integer , int) @method.source.add_code Register::LoadConstant.new( statement, int , reg )
@method.source.add_code Virtual::Set.new( int , to ) return reg
to
end end
def on_true statement def on_true statement
to = Virtual::Return.new(Phisol::Reference , true ) reg = use_reg :ref
@method.source.add_code Virtual::Set.new( true , to ) @method.source.add_code Register::LoadConstant.new( statement, true , reg )
to return reg
end end
def on_false statement def on_false statement
to = Virtual::Return.new(Phisol::Reference , false) reg = use_reg :ref
@method.source.add_code Virtual::Set.new( false , to ) @method.source.add_code Register::LoadConstant.new( statement, false , reg )
to return reg
end end
def on_nil statement def on_nil statement
to = Virtual::Return.new(Phisol::Reference , nil) reg = use_reg :ref
@method.source.add_code Virtual::Set.new( nil , to ) @method.source.add_code Register::LoadConstant.new( statement, nil , reg )
to return reg
end end
def on_string statement def on_string statement
# Clearly a TODO here to implement strings rather than reusing symbols
value = statement.first.to_sym value = statement.first.to_sym
to = Virtual::Return.new(Phisol::Reference , value) reg = use_reg :ref
@method.source.constants << value @method.source.constants << value
@method.source.add_code Virtual::Set.new( value , to ) @method.source.add_code Register::LoadConstant.new( statement, value , reg )
to return reg
end end
end end
end end

View File

@ -11,8 +11,10 @@ module Phisol
when :self when :self
index = @clazz.object_layout.variable_index(field_name) index = @clazz.object_layout.variable_index(field_name)
raise "field access, but no such field:#{field_name} for class #{@clazz.name}" unless index raise "field access, but no such field:#{field_name} for class #{@clazz.name}" unless index
value = Virtual::Return.new(:int) value = use_reg(:int) #TODO, need types in layout
@method.source.add_code Virtual::Set.new( Virtual::SelfsSlot.new(index, :int ) , value ) move = Register.get_slot(statement, :self , index , value )
@method.source.add_code move
return value
when :message when :message
#message Slot #message Slot
raise "message not yet" raise "message not yet"

View File

@ -5,11 +5,13 @@ module CompilerHelper
Phisol::Compiler.class_eval do Phisol::Compiler.class_eval do
def set_main def set_main
@clazz = Virtual.machine.space.get_class_by_name :Object
@method = Virtual.machine.space.get_main @method = Virtual.machine.space.get_main
end end
end end
def check def check
machine = Virtual.machine.boot machine = Virtual.machine
machine.boot unless machine.booted
parser = Parser::Salama.new parser = Parser::Salama.new
parser = parser.send @root parser = parser.send @root
syntax = parser.parse_with_debug(@string_input) syntax = parser.parse_with_debug(@string_input)
@ -18,13 +20,8 @@ module CompilerHelper
compiler = Phisol::Compiler.new compiler = Phisol::Compiler.new
compiler.set_main compiler.set_main
produced = compiler.process( parts ) produced = compiler.process( parts )
produced = [produced] unless produced.is_a? Array
assert @output , "No output given" assert @output , "No output given"
assert_equal produced.length, @output.length , "Block length" assert_equal produced.class, @output , "Wrong class"
produced.each_with_index do |b,i|
codes = @output[i]
assert_equal codes , b.class , "Class #{i} "
end
end end
end end

View File

@ -1,4 +1,3 @@
require_relative "test_basic" require_relative "test_basic"
require_relative "test_hello"
require_relative "test_compiler" require_relative "test_compiler"
require_relative "test_field_access" require_relative "test_field_access"

View File

@ -6,7 +6,7 @@ class TestBasic < MiniTest::Test
def setup def setup
@root = :basic_type @root = :basic_type
@output = [Virtual::Return] @output = Register::RegisterValue
end end
def test_number def test_number
@ -15,7 +15,7 @@ class TestBasic < MiniTest::Test
end end
def test_true def test_true
@string_input = 'true ' @string_input = 'true'
check check
end end
def test_false def test_false
@ -30,12 +30,13 @@ class TestBasic < MiniTest::Test
def test_var def test_var
@string_input = 'int foo ' @string_input = 'int foo '
@root = :field_def @root = :field_def
@output = AST::Node
check check
end end
def test_self def test_self
@string_input = 'self ' @string_input = 'self '
@output = [Virtual::Self] @output = Virtual::Self
check check
end end

View File

@ -1,24 +1,30 @@
require_relative "compiler_helper" require_relative "compiler_helper"
require_relative "code_checker"
module Virtual module Virtual
class TestFoo < MiniTest::Test class TestFields < MiniTest::Test
include CodeChecker include CompilerHelper
def test_foo3 def setup
@string_input = <<HERE Virtual.machine.boot
class Object
field int a
int foo(int x)
int b = self.a
return b +x
end end
end
def test_field_not_defined
@root = :field_access
@string_input = <<HERE
self.a
HERE HERE
@output = [ [Virtual::MethodEnter] , [Virtual::MethodReturn] ] assert_raises(RuntimeError) { check }
end
def test_field
Virtual.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
@root = :field_access
@string_input = <<HERE
self.bro
HERE
@output = Register::RegisterValue
check check
end end
end end
end end