move type to phial and add type to reg_ref

This commit is contained in:
Torsten Ruger 2015-10-10 19:14:27 +03:00
parent cb306c09f0
commit dd3381e38b
15 changed files with 65 additions and 54 deletions

View File

@ -29,11 +29,11 @@ module Phisol
end end
# require a (temporary) register. code must give this back with release_reg # require a (temporary) register. code must give this back with release_reg
def use_reg def use_reg type
if @regs.empty? if @regs.empty?
reg = Register.tmp_reg reg = Register.tmp_reg type
else else
reg = @regs.last.next_reg_use reg = @regs.last.next_reg_use type
end end
@regs << reg @regs << reg
return reg return reg
@ -46,6 +46,7 @@ module Phisol
end end
end end
require_relative "type"
require_relative "ast_helper" require_relative "ast_helper"
require_relative "compiler/basic_values" require_relative "compiler/basic_values"
require_relative "compiler/call_site" require_relative "compiler/call_site"

View File

@ -13,25 +13,26 @@ module Phisol
def on_int statement def on_int statement
int = statement.first int = statement.first
to = Virtual::Return.new(Virtual::Integer , int) # reg =
to = Virtual::Return.new(Phisol::Integer , int)
@method.source.add_code Virtual::Set.new( int , to ) @method.source.add_code Virtual::Set.new( int , to )
to to
end end
def on_true statement def on_true statement
to = Virtual::Return.new(Virtual::Reference , true ) to = Virtual::Return.new(Phisol::Reference , true )
@method.source.add_code Virtual::Set.new( true , to ) @method.source.add_code Virtual::Set.new( true , to )
to to
end end
def on_false statement def on_false statement
to = Virtual::Return.new(Virtual::Reference , false) to = Virtual::Return.new(Phisol::Reference , false)
@method.source.add_code Virtual::Set.new( false , to ) @method.source.add_code Virtual::Set.new( false , to )
to to
end end
def on_nil statement def on_nil statement
to = Virtual::Return.new(Virtual::Reference , nil) to = Virtual::Return.new(Phisol::Reference , nil)
@method.source.add_code Virtual::Set.new( nil , to ) @method.source.add_code Virtual::Set.new( nil , to )
to to
end end
@ -39,7 +40,7 @@ module Phisol
def on_string statement def on_string statement
# Clearly a TODO here to implement strings rather than reusing symbols # 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(Virtual::Reference , value) to = Virtual::Return.new(Phisol::Reference , value)
@method.source.constants << value @method.source.constants << value
@method.source.add_code Virtual::Set.new( value , to ) @method.source.add_code Virtual::Set.new( value , to )
to to

View File

@ -7,7 +7,7 @@ module Phisol
# whichever way this goes the result is stored in the return slot (as all compiles) # whichever way this goes the result is stored in the return slot (as all compiles)
def on_name statement def on_name statement
name = statement.to_a.first name = statement.to_a.first
return Virtual::Self.new( Virtual::Reference.new(@clazz)) if name == :self return Virtual::Self.new( Phisol::Reference.new(@clazz)) if name == :self
# either an argument, so it's stored in message # either an argument, so it's stored in message
if( index = @method.has_arg(name)) if( index = @method.has_arg(name))
type = @method.arguments[index].type type = @method.arguments[index].type

View File

@ -8,8 +8,8 @@ module Phisol
right_slot = process(right_e) right_slot = process(right_e)
puts "left #{left_slot}" puts "left #{left_slot}"
puts "right #{right_slot}" puts "right #{right_slot}"
tmp1 = use_reg tmp1 = use_reg :int
tmp2 = use_reg tmp2 = use_reg :int
get = Register.get_slot_to(statement , left_slot , tmp1 ) get = Register.get_slot_to(statement , left_slot , tmp1 )
get2 = Register.get_slot_to(statement , right_slot , tmp2 ) get2 = Register.get_slot_to(statement , right_slot , tmp2 )
puts "GET #{get}" puts "GET #{get}"

View File

@ -1,5 +1,5 @@
module Virtual module Phisol
# Integer and (Object) References are the main derived classes, but float will come. # Integer and (Object) References are the main derived classes, but float will come.
class Type class Type
@ -11,15 +11,23 @@ module Virtual
# map from a type sym (currently :int/:ref) to a class of subtype of Type # map from a type sym (currently :int/:ref) to a class of subtype of Type
# TODO needs to be made extensible in a defined way. # TODO needs to be made extensible in a defined way.
def self.from_sym type def self.from_sym type
return type if type.is_a? Type
case type case type
when :int when :int
Virtual::Integer self.int
when :ref when :ref
Virtual::Reference self.ref
else else
raise "No type maps to:#{type}" raise "No type maps to:#{type} (#{type.class})"
end end
end end
def self.int
return Integer.new
end
def self.ref
return Reference.new
end
end end
class Integer < Type class Integer < Type

View File

@ -5,10 +5,10 @@ module Register
module ClassMethods module ClassMethods
def plus c def plus c
plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:int] ) plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:int] )
plus_function.source.return_type = Virtual::Integer plus_function.source.return_type = Phisol::Type.int
plus_function.source.receiver = Virtual::Integer plus_function.source.receiver = Phisol::Integer
tmp = Register.tmp_reg tmp = Register.tmp_reg :int
index = Register.arg_index 1 index = Register.arg_index 1
plus_function.source.add_code Register.get_slot( plus_function , :message , index , tmp ) plus_function.source.add_code Register.get_slot( plus_function , :message , index , tmp )
add = Register::OperatorInstruction.new( plus_function, :add , Register.self_reg , tmp ) add = Register::OperatorInstruction.new( plus_function, :add , Register.self_reg , tmp )
@ -23,9 +23,9 @@ module Register
# As we write before we recurse (save a push) we write the number backwards # As we write before we recurse (save a push) we write the number backwards
# arguments: string address , integer # arguments: string address , integer
# def utoa context # def utoa context
# utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Virtual::Integer ] ) # utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Phisol::Integer ] )
# function.source.return_type = Virtual::Integer # function.source.return_type = Phisol::Type.int
# function.source.receiver = Virtual::Integer # function.source.receiver = Phisol::Integer
# return utoa_function # return utoa_function
# # str_addr = utoa_function.receiver # # str_addr = utoa_function.receiver
# # number = utoa_function.args.first # # number = utoa_function.args.first
@ -44,8 +44,8 @@ module Register
def putint context def putint context
putint_function = Virtual::MethodSource.create_method(:Integer,:int,:putint , [] ) putint_function = Virtual::MethodSource.create_method(:Integer,:int,:putint , [] )
putint_function.source.return_type = Virtual::Integer putint_function.source.return_type = Phisol::Type.int
putint_function.source.receiver = Virtual::Integer putint_function.source.receiver = Phisol::Integer
return putint_function return putint_function
# buffer = Parfait::Word.new(" ") # create a buffer # buffer = Parfait::Word.new(" ") # create a buffer
# context.object_space.add_object buffer # and save it (function local variable: a no no) # context.object_space.add_object buffer # and save it (function local variable: a no no)
@ -73,8 +73,8 @@ module Register
# not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html # not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html
def fibo context def fibo context
fibo_function = Virtual::MethodSource.create_method(:Integer,:int,:fibo , [] ) fibo_function = Virtual::MethodSource.create_method(:Integer,:int,:fibo , [] )
fibo_function.source.return_type = Virtual::Integer fibo_function.source.return_type = Phisol::Type.int
fibo_function.source.receiver = Virtual::Integer fibo_function.source.receiver = Phisol::Integer
return fibo_function return fibo_function
# result = fibo_function.return_type # result = fibo_function.return_type
# int = fibo_function.receiver # int = fibo_function.receiver

View File

@ -7,7 +7,7 @@ module Register
# so it is responsible for initial setup # so it is responsible for initial setup
def __init__ context def __init__ context
function = Virtual::MethodSource.create_method(:Kernel,:int,:__init__ , []) function = Virtual::MethodSource.create_method(:Kernel,:int,:__init__ , [])
function.source.return_type = Virtual::Integer function.source.return_type = Phisol::Type.int
# no method enter or return (automatically added), remove # no method enter or return (automatically added), remove
function.source.blocks.first.codes.pop # no Method enter function.source.blocks.first.codes.pop # no Method enter
function.source.blocks.last.codes.pop # no Method return function.source.blocks.last.codes.pop # no Method return
@ -26,7 +26,7 @@ module Register
end end
def exit context def exit context
function = Virtual::MethodSource.create_method(:Kernel,:int,:exit , []) function = Virtual::MethodSource.create_method(:Kernel,:int,:exit , [])
function.source.return_type = Virtual::Integer function.source.return_type = Phisol::Type.int
return function return function
ret = Virtual::RegisterMachine.instance.exit(function) ret = Virtual::RegisterMachine.instance.exit(function)
function.set_return ret function.set_return ret
@ -34,7 +34,7 @@ module Register
end end
def __send context def __send context
function = Virtual::MethodSource.create_method(:Kernel,:int ,:__send , [] ) function = Virtual::MethodSource.create_method(:Kernel,:int ,:__send , [] )
function.source.return_type = Virtual::Integer function.source.return_type = Phisol::Type.int
return function return function
end end
@ -53,7 +53,7 @@ module Register
end end
def restore_message(function) def restore_message(function)
return_tmp = Register.tmp_reg return_tmp = Register.tmp_reg function.source.return_type
# get the sys return out of the way # get the sys return out of the way
function.source.add_code RegisterTransfer.new(function, Register.message_reg , return_tmp ) function.source.add_code RegisterTransfer.new(function, Register.message_reg , return_tmp )
# load the stored message into the base RegisterMachine # load the stored message into the base RegisterMachine

View File

@ -17,7 +17,7 @@ module Register
# end # end
# The at_index is just "below" the api, something we need but don't want to expose, # The at_index is just "below" the api, something we need but don't want to expose,
# so we can't code the above in ruby # so we can't code the above in ruby
def _get_instance_variable context , name = Virtual::Integer def _get_instance_variable context , name = :int
get_function = Virtual::MethodSource.create_method(:Object,:int, :_get_instance_variable , [ ] ) get_function = Virtual::MethodSource.create_method(:Object,:int, :_get_instance_variable , [ ] )
return get_function return get_function
# me = get_function.receiver # me = get_function.receiver
@ -38,7 +38,7 @@ module Register
# return get_function # return get_function
end end
def _set_instance_variable(context , name = Virtual::Integer , value = Virtual::Integer ) def _set_instance_variable(context , name = :int , value = :int )
set_function = Virtual::MethodSource.create_method(:Object,:int,:_set_instance_variable ,[] ) set_function = Virtual::MethodSource.create_method(:Object,:int,:_set_instance_variable ,[] )
return set_function return set_function
# receiver set_function # receiver set_function

View File

@ -32,9 +32,9 @@ module Register
end end
# wrap symbols into regsiter reference if needed # wrap symbols into regsiter reference if needed
def wrap_register reg def wrap_register reg , type
return reg if reg.is_a? RegisterReference return reg if reg.is_a? RegisterReference
RegisterReference.new(reg) RegisterReference.new(reg , type)
end end
end end

View File

@ -18,8 +18,8 @@ module Register
# Note: this may be reversed from some assembler notations (also arm) # Note: this may be reversed from some assembler notations (also arm)
def initialize source , from , to def initialize source , from , to
super(source) super(source)
@from = wrap_register(from) @from = wrap_register(from,:int)
@to = wrap_register(to) @to = wrap_register(to,:int)
end end
attr_reader :from, :to attr_reader :from, :to

View File

@ -7,7 +7,7 @@ module Register
block.codes.dup.each do |code| block.codes.dup.each do |code|
next unless code.is_a? Virtual::Set next unless code.is_a? Virtual::Set
# need a temporay place because of indexed load/store # need a temporay place because of indexed load/store
tmp = Register.tmp_reg tmp = Register.tmp_reg :int
# for constants we have to "move" the constants value # for constants we have to "move" the constants value
if( code.from.is_a?(Parfait::Value) or code.from.is_a?(Symbol) or code.from.is_a?(Fixnum) ) if( code.from.is_a?(Parfait::Value) or code.from.is_a?(Symbol) or code.from.is_a?(Fixnum) )
move1 = LoadConstant.new(code, code.from , tmp ) move1 = LoadConstant.new(code, code.from , tmp )

View File

@ -8,22 +8,24 @@ module Register
class RegisterReference class RegisterReference
attr_accessor :symbol attr_accessor :symbol , :type
def initialize r def initialize r , type
raise "wrong type for register init #{r}" unless r.is_a? Symbol raise "wrong type for register init #{r}" unless r.is_a? Symbol
raise "double r #{r}" if r.to_s[0,1] == "rr" raise "double r #{r}" if r.to_s[0,1] == "rr"
raise "not reg #{r}" unless self.class.look_like_reg r raise "not reg #{r}" unless self.class.look_like_reg r
@type = Phisol::Type.from_sym type
@symbol = r @symbol = r
end end
def to_s def to_s
symbol.to_s symbol.to_s
end end
def self.convert something def self.convert something
return something unless something.is_a? Symbol return something unless something.is_a? Symbol
return something unless look_like_reg(something) return something unless look_like_reg(something)
return new(something) return new(something , :int)
end end
def self.look_like_reg is_it def self.look_like_reg is_it
@ -46,10 +48,10 @@ module Register
end end
#helper method to calculate with register symbols #helper method to calculate with register symbols
def next_reg_use by = 1 def next_reg_use type
int = @symbol[1,3].to_i int = @symbol[1,3].to_i
sym = "r#{int + by}".to_sym sym = "r#{int + 1}".to_sym
RegisterReference.new( sym ) RegisterReference.new( sym , type)
end end
def sof_reference_name def sof_reference_name
@ -63,30 +65,30 @@ module Register
# The register we use to store the current message object is :r0 # The register we use to store the current message object is :r0
def self.message_reg def self.message_reg
RegisterReference.new :r0 RegisterReference.new :r0 , :ref
end end
# A register to hold the receiver of the current message, in oo terms the self. :r1 # A register to hold the receiver of the current message, in oo terms the self. :r1
def self.self_reg def self.self_reg type = :ref
RegisterReference.new :r1 RegisterReference.new :r1 , type
end end
# The register to hold a possible frame of the currently executing method. :r2 # The register to hold a possible frame of the currently executing method. :r2
# May be nil if the method has no local variables # May be nil if the method has no local variables
def self.frame_reg def self.frame_reg
RegisterReference.new :r2 RegisterReference.new :r2 , :ref
end end
# The register we use to store the new message object is :r3 # The register we use to store the new message object is :r3
# The new message is the one being built, to be sent # The new message is the one being built, to be sent
def self.new_message_reg def self.new_message_reg
RegisterReference.new :r3 RegisterReference.new :r3 , :ref
end end
# The first scratch register. There is a next_reg_use to get a next and next. # The first scratch register. There is a next_reg_use to get a next and next.
# Current thinking is that scratch is schatch between instructions # Current thinking is that scratch is schatch between instructions
def self.tmp_reg def self.tmp_reg type
RegisterReference.new :r4 RegisterReference.new :r4 , type
end end
# The first arg is a class name (possibly lowercase) and the second an instance variable name. # The first arg is a class name (possibly lowercase) and the second an instance variable name.

View File

@ -9,7 +9,6 @@ require "phisol/compiler"
require "virtual/instruction" require "virtual/instruction"
require "virtual/method_source" require "virtual/method_source"
require "virtual/slots/slot" require "virtual/slots/slot"
require "virtual/type"
# the passes _are_ order dependant # the passes _are_ order dependant
require "virtual/passes/minimizer" require "virtual/passes/minimizer"
require "virtual/passes/collector" require "virtual/passes/collector"

View File

@ -37,7 +37,7 @@ module Virtual
raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol
clazz = Virtual.machine.space.get_class_by_name class_name clazz = Virtual.machine.space.get_class_by_name class_name
raise "No such class #{class_name}" unless clazz raise "No such class #{class_name}" unless clazz
return_type = Virtual::Type.from_sym return_type return_type = Phisol::Type.from_sym return_type
arguments = [] arguments = []
args.each_with_index do | arg , index | args.each_with_index do | arg , index |
unless arg.is_a? Parfait::Variable unless arg.is_a? Parfait::Variable

View File

@ -13,7 +13,7 @@ module Virtual
# derived classes are Boot/Meta Class and StringConstant # derived classes are Boot/Meta Class and StringConstant
class ObjectConstant < Constant class ObjectConstant < Constant
# def type # def type
# Virtual::Reference # Phisol::Reference
# end # end
def clazz def clazz
raise "abstract #{self}" raise "abstract #{self}"
@ -26,7 +26,7 @@ module Virtual
end end
attr_reader :integer attr_reader :integer
def type def type
Virtual::Integer Phisol::Integer
end end
def fits_u8? def fits_u8?
integer >= 0 and integer <= 255 integer >= 0 and integer <= 255