From 1141ed9c9959d3715b9c8044687f3b91513cb14d Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 14 Oct 2015 16:16:03 +0300 Subject: [PATCH] type now means class name update reader (with new type definition) remove type class (now symbol) update all types to class name symbols --- Gemfile.lock | 2 +- lib/parfait/variable.rb | 2 +- lib/phisol/compiler.rb | 1 - lib/phisol/compiler/basic_values.rb | 8 ++--- lib/phisol/compiler/call_site.rb | 26 +++++---------- lib/phisol/compiler/name_expression.rb | 2 +- lib/phisol/type.rb | 44 -------------------------- lib/register/builtin/integer.rb | 28 ++++++++-------- lib/register/builtin/kernel.rb | 14 ++++---- lib/register/builtin/object.rb | 10 +++--- lib/register/builtin/word.rb | 2 +- lib/register/register_value.rb | 12 +++---- lib/virtual/method_source.rb | 5 ++- stash/constants.rb | 2 +- test/compiler/test_call.rb | 33 +++++++++++-------- test/compiler/test_function.rb | 2 +- 16 files changed, 72 insertions(+), 121 deletions(-) delete mode 100644 lib/phisol/type.rb diff --git a/Gemfile.lock b/Gemfile.lock index 10848f68..2335ab74 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/lib/parfait/variable.rb b/lib/parfait/variable.rb index 736f6d63..9903370f 100644 --- a/lib/parfait/variable.rb +++ b/lib/parfait/variable.rb @@ -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 diff --git a/lib/phisol/compiler.rb b/lib/phisol/compiler.rb index acfa1260..98d371e3 100644 --- a/lib/phisol/compiler.rb +++ b/lib/phisol/compiler.rb @@ -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" diff --git a/lib/phisol/compiler/basic_values.rb b/lib/phisol/compiler/basic_values.rb index 23f05ba3..6fe0529e 100644 --- a/lib/phisol/compiler/basic_values.rb +++ b/lib/phisol/compiler/basic_values.rb @@ -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 diff --git a/lib/phisol/compiler/call_site.rb b/lib/phisol/compiler/call_site.rb index 8c89a29c..f022215f 100644 --- a/lib/phisol/compiler/call_site.rb +++ b/lib/phisol/compiler/call_site.rb @@ -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 ) diff --git a/lib/phisol/compiler/name_expression.rb b/lib/phisol/compiler/name_expression.rb index ab869b74..5c431f43 100644 --- a/lib/phisol/compiler/name_expression.rb +++ b/lib/phisol/compiler/name_expression.rb @@ -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 diff --git a/lib/phisol/type.rb b/lib/phisol/type.rb deleted file mode 100644 index c78ae71c..00000000 --- a/lib/phisol/type.rb +++ /dev/null @@ -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 diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index 377fe050..d0505931 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -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 diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 29479f4c..457352c1 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -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 diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index 113329b7..27509de8 100644 --- a/lib/register/builtin/object.rb +++ b/lib/register/builtin/object.rb @@ -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 diff --git a/lib/register/builtin/word.rb b/lib/register/builtin/word.rb index d972c4a0..6bd77922 100644 --- a/lib/register/builtin/word.rb +++ b/lib/register/builtin/word.rb @@ -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 diff --git a/lib/register/register_value.rb b/lib/register/register_value.rb index 6ebfdd55..8ff12128 100644 --- a/lib/register/register_value.rb +++ b/lib/register/register_value.rb @@ -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 diff --git a/lib/virtual/method_source.rb b/lib/virtual/method_source.rb index 9175f66e..f5fe5718 100644 --- a/lib/virtual/method_source.rb +++ b/lib/virtual/method_source.rb @@ -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) diff --git a/stash/constants.rb b/stash/constants.rb index 71cd9392..f7f398fe 100644 --- a/stash/constants.rb +++ b/stash/constants.rb @@ -26,7 +26,7 @@ module Virtual end attr_reader :integer def type - Phisol::Integer + :Integer end def fits_u8? integer >= 0 and integer <= 255 diff --git a/test/compiler/test_call.rb b/test/compiler/test_call.rb index 41d6dd6f..3e853c94 100644 --- a/test/compiler/test_call.rb +++ b/test/compiler/test_call.rb @@ -10,39 +10,46 @@ module Virtual def test_call_main_plain @root = :call_site - @string_input = <