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

View File

@ -13,25 +13,26 @@ module Phisol
def on_int statement
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 )
to
end
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 )
to
end
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 )
to
end
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 )
to
end
@ -39,7 +40,7 @@ module Phisol
def on_string statement
# Clearly a TODO here to implement strings rather than reusing symbols
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.add_code Virtual::Set.new( value , 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)
def on_name statement
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
if( index = @method.has_arg(name))
type = @method.arguments[index].type

View File

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

View File

@ -1,7 +1,7 @@
module Virtual
module Phisol
# Integer and (Object) References are the main derived classes, but float will come.
class Type
def == other
return false unless other.class == self.class
@ -11,15 +11,23 @@ module Virtual
# 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.
def self.from_sym type
return type if type.is_a? Type
case type
when :int
Virtual::Integer
self.int
when :ref
Virtual::Reference
self.ref
else
raise "No type maps to:#{type}"
raise "No type maps to:#{type} (#{type.class})"
end
end
def self.int
return Integer.new
end
def self.ref
return Reference.new
end
end
class Integer < Type

View File

@ -5,10 +5,10 @@ module Register
module ClassMethods
def plus c
plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:int] )
plus_function.source.return_type = Virtual::Integer
plus_function.source.receiver = Virtual::Integer
plus_function.source.return_type = Phisol::Type.int
plus_function.source.receiver = Phisol::Integer
tmp = Register.tmp_reg
tmp = Register.tmp_reg :int
index = Register.arg_index 1
plus_function.source.add_code Register.get_slot( plus_function , :message , index , 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
# arguments: string address , integer
# def utoa context
# utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Virtual::Integer ] )
# function.source.return_type = Virtual::Integer
# function.source.receiver = Virtual::Integer
# utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Phisol::Integer ] )
# function.source.return_type = Phisol::Type.int
# function.source.receiver = Phisol::Integer
# return utoa_function
# # str_addr = utoa_function.receiver
# # number = utoa_function.args.first
@ -44,8 +44,8 @@ module Register
def putint context
putint_function = Virtual::MethodSource.create_method(:Integer,:int,:putint , [] )
putint_function.source.return_type = Virtual::Integer
putint_function.source.receiver = Virtual::Integer
putint_function.source.return_type = Phisol::Type.int
putint_function.source.receiver = Phisol::Integer
return putint_function
# buffer = Parfait::Word.new(" ") # create a buffer
# 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
def fibo context
fibo_function = Virtual::MethodSource.create_method(:Integer,:int,:fibo , [] )
fibo_function.source.return_type = Virtual::Integer
fibo_function.source.receiver = Virtual::Integer
fibo_function.source.return_type = Phisol::Type.int
fibo_function.source.receiver = Phisol::Integer
return fibo_function
# result = fibo_function.return_type
# int = fibo_function.receiver

View File

@ -7,7 +7,7 @@ module Register
# so it is responsible for initial setup
def __init__ context
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
function.source.blocks.first.codes.pop # no Method enter
function.source.blocks.last.codes.pop # no Method return
@ -26,7 +26,7 @@ module Register
end
def exit context
function = Virtual::MethodSource.create_method(:Kernel,:int,:exit , [])
function.source.return_type = Virtual::Integer
function.source.return_type = Phisol::Type.int
return function
ret = Virtual::RegisterMachine.instance.exit(function)
function.set_return ret
@ -34,7 +34,7 @@ module Register
end
def __send context
function = Virtual::MethodSource.create_method(:Kernel,:int ,:__send , [] )
function.source.return_type = Virtual::Integer
function.source.return_type = Phisol::Type.int
return function
end
@ -53,7 +53,7 @@ module Register
end
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
function.source.add_code RegisterTransfer.new(function, Register.message_reg , return_tmp )
# load the stored message into the base RegisterMachine

View File

@ -17,7 +17,7 @@ module Register
# end
# 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
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 , [ ] )
return get_function
# me = get_function.receiver
@ -38,7 +38,7 @@ module Register
# return get_function
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 ,[] )
return set_function
# receiver set_function

View File

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

View File

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

View File

@ -7,7 +7,7 @@ module Register
block.codes.dup.each do |code|
next unless code.is_a? Virtual::Set
# 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
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 )

View File

@ -8,22 +8,24 @@ module Register
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 "double r #{r}" if r.to_s[0,1] == "rr"
raise "not reg #{r}" unless self.class.look_like_reg r
@type = Phisol::Type.from_sym type
@symbol = r
end
def to_s
symbol.to_s
end
def self.convert something
return something unless something.is_a? Symbol
return something unless look_like_reg(something)
return new(something)
return new(something , :int)
end
def self.look_like_reg is_it
@ -46,10 +48,10 @@ module Register
end
#helper method to calculate with register symbols
def next_reg_use by = 1
def next_reg_use type
int = @symbol[1,3].to_i
sym = "r#{int + by}".to_sym
RegisterReference.new( sym )
sym = "r#{int + 1}".to_sym
RegisterReference.new( sym , type)
end
def sof_reference_name
@ -63,30 +65,30 @@ module Register
# The register we use to store the current message object is :r0
def self.message_reg
RegisterReference.new :r0
RegisterReference.new :r0 , :ref
end
# A register to hold the receiver of the current message, in oo terms the self. :r1
def self.self_reg
RegisterReference.new :r1
def self.self_reg type = :ref
RegisterReference.new :r1 , type
end
# The register to hold a possible frame of the currently executing method. :r2
# May be nil if the method has no local variables
def self.frame_reg
RegisterReference.new :r2
RegisterReference.new :r2 , :ref
end
# The register we use to store the new message object is :r3
# The new message is the one being built, to be sent
def self.new_message_reg
RegisterReference.new :r3
RegisterReference.new :r3 , :ref
end
# 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
def self.tmp_reg
RegisterReference.new :r4
def self.tmp_reg type
RegisterReference.new :r4 , type
end
# 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/method_source"
require "virtual/slots/slot"
require "virtual/type"
# the passes _are_ order dependant
require "virtual/passes/minimizer"
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
clazz = Virtual.machine.space.get_class_by_name class_name
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 = []
args.each_with_index do | arg , index |
unless arg.is_a? Parfait::Variable

View File

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