type now means class name
update reader (with new type definition) remove type class (now symbol) update all types to class name symbols
This commit is contained in:
parent
d8a5dc147b
commit
1141ed9c99
@ -12,7 +12,7 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/salama/salama-reader.git
|
||||
revision: 6bd5e9b5ee26e4e0157283e9af4389b13d660193
|
||||
revision: ab0a94bd51c996637453331adeb28bf1731f9b65
|
||||
specs:
|
||||
salama-reader (0.4.0)
|
||||
ast (~> 2.1.0)
|
||||
|
@ -2,7 +2,7 @@ module Parfait
|
||||
class Variable < Object
|
||||
|
||||
def initialize type , name , value = nil
|
||||
raise "not type #{type}" unless type == :ref or type == :int
|
||||
raise "not type #{type}" unless Virtual.machine.space.get_class_by_name(type)
|
||||
self.type , self.name , self.value = type , name , value
|
||||
self.value = 0 if self.type == :int and value == nil
|
||||
raise "must give name for variable" unless name
|
||||
|
@ -55,7 +55,6 @@ module Phisol
|
||||
end
|
||||
end
|
||||
|
||||
require_relative "type"
|
||||
require_relative "ast_helper"
|
||||
require_relative "compiler/basic_values"
|
||||
require_relative "compiler/call_site"
|
||||
|
@ -19,26 +19,26 @@ module Phisol
|
||||
end
|
||||
|
||||
def on_true statement
|
||||
reg = use_reg :ref
|
||||
reg = use_reg :Boolean
|
||||
@method.source.add_code Register::LoadConstant.new( statement, true , reg )
|
||||
return reg
|
||||
end
|
||||
|
||||
def on_false statement
|
||||
reg = use_reg :ref
|
||||
reg = use_reg :Boolean
|
||||
@method.source.add_code Register::LoadConstant.new( statement, false , reg )
|
||||
return reg
|
||||
end
|
||||
|
||||
def on_nil statement
|
||||
reg = use_reg :ref
|
||||
reg = use_reg :NilClass
|
||||
@method.source.add_code Register::LoadConstant.new( statement, nil , reg )
|
||||
return reg
|
||||
end
|
||||
|
||||
def on_string statement
|
||||
value = statement.first.to_sym
|
||||
reg = use_reg :ref
|
||||
reg = use_reg :Word
|
||||
@method.source.constants << value
|
||||
@method.source.add_code Register::LoadConstant.new( statement, value , reg )
|
||||
return reg
|
||||
|
@ -9,12 +9,7 @@ module Phisol
|
||||
if receiver
|
||||
me = process( receiver.to_a.first )
|
||||
else
|
||||
if @method.for_class.name == :Integer
|
||||
type = :int
|
||||
else
|
||||
type = :ref
|
||||
end
|
||||
me = Register.self_reg type
|
||||
me = Register.self_reg @method.for_class.name
|
||||
end
|
||||
#move the new message (that we need to populate to make a call) to std register
|
||||
new_message = Register.resolve_to_register(:new_message)
|
||||
@ -22,7 +17,7 @@ module Phisol
|
||||
# move our receiver there
|
||||
@method.source.add_code Register.set_slot( statement , me , :new_message , :receiver)
|
||||
# load method name and set to new message (for exceptions/debug)
|
||||
name_tmp = use_reg(:ref)
|
||||
name_tmp = use_reg(:Word)
|
||||
@method.source.add_code Register::LoadConstant.new(statement, name , name_tmp)
|
||||
@method.source.add_code Register.set_slot( statement , name_tmp , :new_message , :name)
|
||||
# next arguments. reset tmp regs for each and load result into new_message
|
||||
@ -56,17 +51,12 @@ module Phisol
|
||||
raise "unimplemented: \n#{code} \nfor #{ref.inspect}"
|
||||
end
|
||||
else
|
||||
if( me.type.is_a? Phisol::Integer)
|
||||
name = :plus if name == :+
|
||||
method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(name)
|
||||
puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a
|
||||
raise "Method not implemented Integer.#{name}" unless method
|
||||
@method.source.add_code Virtual::MethodCall.new( method )
|
||||
else
|
||||
method = @clazz.get_instance_method(name)
|
||||
raise "Method not implemented #{@clazz.name}.#{name}" unless method
|
||||
@method.source.add_code Virtual::MethodCall.new( method )
|
||||
end
|
||||
clazz = Virtual.machine.space.get_class_by_name(me.type)
|
||||
raise "No such class #{me.type}" unless clazz
|
||||
method = clazz.get_instance_method(name)
|
||||
puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a
|
||||
raise "Method not implemented Integer.#{name}" unless method
|
||||
@method.source.add_code Virtual::MethodCall.new( method )
|
||||
end
|
||||
raise "Method not implemented #{me.value}.#{name}" unless method
|
||||
ret = use_reg( method.source.return_type )
|
||||
|
@ -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( Phisol::Reference.new(@clazz)) if name == :self
|
||||
return Virtual::Self.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
|
||||
|
@ -1,44 +0,0 @@
|
||||
|
||||
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
|
||||
return true
|
||||
end
|
||||
|
||||
# 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
|
||||
self.int
|
||||
when :ref
|
||||
self.ref
|
||||
else
|
||||
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
|
||||
end
|
||||
|
||||
class Reference < Type
|
||||
# possibly unknown value, but known class (as in methods)
|
||||
def initialize clazz = nil
|
||||
@of_class = clazz
|
||||
end
|
||||
attr_reader :of_class
|
||||
end
|
||||
|
||||
end
|
@ -4,14 +4,14 @@ module Register
|
||||
module Integer
|
||||
module ClassMethods
|
||||
def plus c
|
||||
plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:int] )
|
||||
plus_function.source.set_return_type Phisol::Type.int
|
||||
plus_function.source.receiver = Phisol::Integer
|
||||
plus_function = Virtual::MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] )
|
||||
plus_function.source.set_return_type :Integer
|
||||
plus_function.source.receiver = :Integer
|
||||
|
||||
tmp = Register.tmp_reg :int
|
||||
tmp = Register.tmp_reg :Integer
|
||||
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 )
|
||||
add = Register::OperatorInstruction.new( plus_function, :add , Register.self_reg(:Integer) , tmp )
|
||||
plus_function.source.add_code add
|
||||
return plus_function
|
||||
end
|
||||
@ -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 , [ Phisol::Integer ] )
|
||||
# function.source.return_type = Phisol::Type.int
|
||||
# function.source.receiver = Phisol::Integer
|
||||
# utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ :Integer ] )
|
||||
# function.source.return_type = :Integer
|
||||
# function.source.receiver = :Integer
|
||||
# return utoa_function
|
||||
# # str_addr = utoa_function.receiver
|
||||
# # number = utoa_function.args.first
|
||||
@ -43,9 +43,9 @@ module Register
|
||||
# end
|
||||
|
||||
def putint context
|
||||
putint_function = Virtual::MethodSource.create_method(:Integer,:int,:putint , [] )
|
||||
putint_function.source.set_return_type Phisol::Type.int
|
||||
putint_function.source.receiver = Phisol::Integer
|
||||
putint_function = Virtual::MethodSource.create_method(:Integer,:Integer,:putint , [] )
|
||||
putint_function.source.set_return_type :Integer
|
||||
putint_function.source.receiver = :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)
|
||||
@ -72,9 +72,9 @@ module Register
|
||||
# a hand coded version of the fibonachi numbers
|
||||
# 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.set_return_type Phisol::Type.int
|
||||
fibo_function.source.receiver = Phisol::Integer
|
||||
fibo_function = Virtual::MethodSource.create_method(:Integer,:Integer,:fibo , [] )
|
||||
fibo_function.source.set_return_type :Integer
|
||||
fibo_function.source.receiver = :Integer
|
||||
return fibo_function
|
||||
# result = fibo_function.return_type
|
||||
# int = fibo_function.receiver
|
||||
|
@ -6,14 +6,14 @@ module Register
|
||||
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
||||
# so it is responsible for initial setup
|
||||
def __init__ context
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:int,:__init__ , [])
|
||||
function.source.set_return_type Phisol::Type.int
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer,:__init__ , [])
|
||||
function.source.set_return_type :Integer
|
||||
# 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
|
||||
#Set up the Space as self upon init
|
||||
space = Parfait::Space.object_space
|
||||
function.source.add_code LoadConstant.new(function, space , Register.self_reg)
|
||||
function.source.add_code LoadConstant.new(function, space , Register.self_reg(:Space))
|
||||
message_ind = Register.resolve_index( :space , :first_message )
|
||||
# Load the message to new message register (r3)
|
||||
function.source.add_code Register.get_slot( function , :self , message_ind , :new_message)
|
||||
@ -25,16 +25,16 @@ module Register
|
||||
return function
|
||||
end
|
||||
def exit context
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:int,:exit , [])
|
||||
function.source.set_return_type Phisol::Type.int
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer,:exit , [])
|
||||
function.source.set_return_type :Integer
|
||||
return function
|
||||
ret = Virtual::RegisterMachine.instance.exit(function)
|
||||
function.set_return ret
|
||||
function
|
||||
end
|
||||
def __send context
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:int ,:__send , [] )
|
||||
function.source.set_return_type Phisol::Type.int
|
||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer ,:__send , [] )
|
||||
function.source.set_return_type :Integer
|
||||
return function
|
||||
end
|
||||
|
||||
|
@ -6,7 +6,7 @@ module Register
|
||||
# main entry point, ie __init__ calls this
|
||||
# defined here as empty, to be redefined
|
||||
def main context
|
||||
function = Virtual::MethodSource.create_method(:Object, :int , :main , [])
|
||||
function = Virtual::MethodSource.create_method(:Object, :Integer , :main , [])
|
||||
return function
|
||||
end
|
||||
|
||||
@ -17,8 +17,8 @@ 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 = :int
|
||||
get_function = Virtual::MethodSource.create_method(:Object,:int, :_get_instance_variable , [ ] )
|
||||
def _get_instance_variable context , name = :Integer
|
||||
get_function = Virtual::MethodSource.create_method(:Object,:Integer, :_get_instance_variable , [ ] )
|
||||
return get_function
|
||||
# me = get_function.receiver
|
||||
# var_name = get_function.args.first
|
||||
@ -38,8 +38,8 @@ module Register
|
||||
# return get_function
|
||||
end
|
||||
|
||||
def _set_instance_variable(context , name = :int , value = :int )
|
||||
set_function = Virtual::MethodSource.create_method(:Object,:int,:_set_instance_variable ,[] )
|
||||
def _set_instance_variable(context , name = :Integer , value = :Integer )
|
||||
set_function = Virtual::MethodSource.create_method(:Object,:Integer,:_set_instance_variable ,[] )
|
||||
return set_function
|
||||
# receiver set_function
|
||||
# me = set_function.receiver
|
||||
|
@ -3,7 +3,7 @@ module Register
|
||||
module Word
|
||||
module ClassMethods
|
||||
def putstring context
|
||||
function = Virtual::MethodSource.create_method(:Word,:int , :putstring , [] )
|
||||
function = Virtual::MethodSource.create_method(:Word,:Integer , :putstring , [] )
|
||||
Kernel.emit_syscall( function , :putstring )
|
||||
function
|
||||
end
|
||||
|
@ -10,7 +10,7 @@ module Register
|
||||
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
|
||||
@type = type
|
||||
@symbol = r
|
||||
@value = value
|
||||
end
|
||||
@ -62,24 +62,24 @@ module Register
|
||||
|
||||
# The register we use to store the current message object is :r0
|
||||
def self.message_reg
|
||||
RegisterValue.new :r0 , :ref
|
||||
RegisterValue.new :r0 , :Message
|
||||
end
|
||||
|
||||
# A register to hold the receiver of the current message, in oo terms the self. :r1
|
||||
def self.self_reg type = :ref
|
||||
def self.self_reg type
|
||||
RegisterValue.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
|
||||
RegisterValue.new :r2 , :ref
|
||||
RegisterValue.new :r2 , :Frame
|
||||
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
|
||||
RegisterValue.new :r3 , :ref
|
||||
RegisterValue.new :r3 , :Message
|
||||
end
|
||||
|
||||
# The first scratch register. There is a next_reg_use to get a next and next.
|
||||
@ -116,7 +116,7 @@ module Register
|
||||
when :new_message
|
||||
register = new_message_reg
|
||||
when :self
|
||||
register = self_reg
|
||||
register = self_reg(:Object) #TODO , prpbably have to get rid of this resolve method
|
||||
when :frame
|
||||
register = frame_reg
|
||||
else
|
||||
|
@ -37,11 +37,10 @@ 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 = Phisol::Type.from_sym return_type
|
||||
arguments = []
|
||||
args.each_with_index do | arg , index |
|
||||
unless arg.is_a? Parfait::Variable
|
||||
raise "not type #{arg}:#{arg.class}" unless arg == :int || arg == :ref
|
||||
raise "not type #{arg}:#{arg.class}" unless Virtual.machine.space.get_class_by_name arg
|
||||
arg = Parfait::Variable.new arg , "arg#{index}".to_sym
|
||||
end
|
||||
arguments << arg
|
||||
@ -69,7 +68,7 @@ module Virtual
|
||||
|
||||
def set_return_type type
|
||||
return if type.nil?
|
||||
raise "not type #{type}" unless type.is_a? Phisol::Type
|
||||
raise "not type #{type}" unless Virtual.machine.space.get_class_by_name type
|
||||
@return_type = type
|
||||
end
|
||||
# add an instruction after the current (insertion point)
|
||||
|
@ -26,7 +26,7 @@ module Virtual
|
||||
end
|
||||
attr_reader :integer
|
||||
def type
|
||||
Phisol::Integer
|
||||
:Integer
|
||||
end
|
||||
def fits_u8?
|
||||
integer >= 0 and integer <= 255
|
||||
|
@ -10,39 +10,46 @@ module Virtual
|
||||
|
||||
def test_call_main_plain
|
||||
@root = :call_site
|
||||
@string_input = <<HERE
|
||||
main()
|
||||
HERE
|
||||
@string_input = 'main()'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_main_int
|
||||
@root = :call_site
|
||||
@string_input = <<HERE
|
||||
main(1)
|
||||
HERE
|
||||
@string_input = 'main(1)'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def ttest_call_self_main
|
||||
@root = :call_site
|
||||
@string_input = 'self.main()'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_main_string
|
||||
@root = :call_site
|
||||
@string_input = <<HERE
|
||||
main("1")
|
||||
HERE
|
||||
@string_input = 'main("1")'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def ttest_call_main_op
|
||||
Virtual.machine.space.get_main.ensure_local(:bar , :int)
|
||||
Virtual.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||
@root = :call_site
|
||||
@string_input = <<HERE
|
||||
main( bar )
|
||||
HERE
|
||||
@string_input = 'main( bar )'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_string_put
|
||||
@root = :call_site
|
||||
@string_input = '"Hello Raisa, I am salama".putstring()'
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -16,7 +16,7 @@ module Virtual
|
||||
def test_puts
|
||||
@root = :function_definition
|
||||
@string_input = <<HERE
|
||||
int puts(ref str)
|
||||
int puts(Word str)
|
||||
main()
|
||||
end
|
||||
HERE
|
||||
|
Loading…
x
Reference in New Issue
Block a user