diff --git a/lib/bosl/compiler/callsite_expression.rb b/lib/bosl/compiler/callsite_expression.rb index 72ddcbfc..4a2859a9 100644 --- a/lib/bosl/compiler/callsite_expression.rb +++ b/lib/bosl/compiler/callsite_expression.rb @@ -8,13 +8,13 @@ module Bosl if receiver me = process( receiver.to_a.first ) else - me = Virtual::Self.new + me = Virtual::Self.new :int end ## need two step process, compile and save to frame # then move from frame to new message method.source.add_code Virtual::NewMessage.new method.source.add_code Virtual::Set.new( me , Virtual::NewSelf.new(me.type)) - method.source.add_code Virtual::Set.new( name.to_sym , Virtual::NewMessageName.new()) + method.source.add_code Virtual::Set.new( name.to_sym , Virtual::NewMessageName.new(:int)) compiled_args = [] arguments.to_a.each_with_index do |arg , i| #compile in the running method, ie before passing control diff --git a/lib/bosl/compiler/function_expression.rb b/lib/bosl/compiler/function_expression.rb index 3615b7f4..18dfc83c 100644 --- a/lib/bosl/compiler/function_expression.rb +++ b/lib/bosl/compiler/function_expression.rb @@ -24,10 +24,10 @@ module Bosl end end else - r = Virtual::Self.new() + r = Virtual::Self.new(:int) class_name = method.for_class.name end - new_method = Virtual::MethodSource.create_method(class_name, name , args ) + new_method = Virtual::MethodSource.create_method(class_name, return_type, name , args ) new_method.source.receiver = r new_method.for_class.add_instance_method new_method diff --git a/lib/bosl/compiler/name_expression.rb b/lib/bosl/compiler/name_expression.rb index f04df405..f8fae00d 100644 --- a/lib/bosl/compiler/name_expression.rb +++ b/lib/bosl/compiler/name_expression.rb @@ -9,12 +9,12 @@ module Bosl name = expression.to_a.first return Virtual::Self.new( Virtual::Reference.new(method.for_class)) if name == :self # either an argument, so it's stored in message - ret = Virtual::Return.new + ret = Virtual::Return.new :int if( index = method.has_arg(name)) - method.source.add_code Virtual::Set.new( Virtual::ArgSlot.new(index ) , ret) + method.source.add_code Virtual::Set.new( Virtual::ArgSlot.new(:int,index ) , ret) else # or a local so it is in the frame index = method.ensure_local( name ) - method.source.add_code Virtual::Set.new(Virtual::FrameSlot.new(index ) , ret ) + method.source.add_code Virtual::Set.new(Virtual::FrameSlot.new(:int,index ) , ret ) end return ret end diff --git a/lib/bosl/compiler/operator_expressions.rb b/lib/bosl/compiler/operator_expressions.rb index ebfcd75c..602e744b 100644 --- a/lib/bosl/compiler/operator_expressions.rb +++ b/lib/bosl/compiler/operator_expressions.rb @@ -3,7 +3,7 @@ module Bosl # operator attr_reader :operator, :left, :right def on_operator expression operator , left , right = *expression - Virtual::Return.new() + Virtual::Return.new(:int) end def on_assign expression @@ -11,7 +11,7 @@ module Bosl name = name.to_a.first v = process(value) index = method.ensure_local( name ) - method.source.add_code Virtual::Set.new(Virtual::FrameSlot.new(index ) , v ) + method.source.add_code Virtual::Set.new(Virtual::FrameSlot.new(:int,index ) , v ) end end diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index 1c0f60a9..2943efec 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -4,7 +4,7 @@ module Register module Integer module ClassMethods def plus c - plus_function = Virtual::MethodSource.create_method(:Integer,:plus , [:Integer] ) + plus_function = Virtual::MethodSource.create_method(:Integer,:int,:plus , [:Integer] ) plus_function.source.return_type = Virtual::Integer plus_function.source.receiver = Virtual::Integer @@ -43,7 +43,7 @@ module Register # end def putint context - putint_function = Virtual::MethodSource.create_method(:Integer,:putint , [] ) + putint_function = Virtual::MethodSource.create_method(:Integer,:int,:putint , [] ) putint_function.source.return_type = Virtual::Integer putint_function.source.receiver = Virtual::Integer return putint_function @@ -72,7 +72,7 @@ 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,:fibo , [] ) + fibo_function = Virtual::MethodSource.create_method(:Integer,:int,:fibo , [] ) fibo_function.source.return_type = Virtual::Integer fibo_function.source.receiver = Virtual::Integer return fibo_function diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index ee5eea04..c4d9e713 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -6,7 +6,7 @@ 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,:__init__ , []) + function = Virtual::MethodSource.create_method(:Kernel,:int,:__init__ , []) function.source.return_type = Virtual::Integer # no method enter or return (automatically added), remove function.source.blocks.first.codes.pop # no Method enter @@ -25,7 +25,7 @@ module Register return function end def exit context - function = Virtual::MethodSource.create_method(:Kernel,:exit , []) + function = Virtual::MethodSource.create_method(:Kernel,:int,:exit , []) function.source.return_type = Virtual::Integer return function ret = Virtual::RegisterMachine.instance.exit(function) @@ -33,7 +33,7 @@ module Register function end def __send context - function = Virtual::MethodSource.create_method(:Kernel ,:__send , [] ) + function = Virtual::MethodSource.create_method(:Kernel,:int ,:__send , [] ) function.source.return_type = Virtual::Integer return function end diff --git a/lib/register/builtin/object.rb b/lib/register/builtin/object.rb index 3b45e145..94e6bbeb 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,:main , []) + function = Virtual::MethodSource.create_method(:Object, :int , :main , []) return function end @@ -18,7 +18,7 @@ module Register # 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 - get_function = Virtual::MethodSource.create_method(:Object,:_get_instance_variable , [ ] ) + get_function = Virtual::MethodSource.create_method(:Object,:int, :_get_instance_variable , [ ] ) return get_function # me = get_function.receiver # var_name = get_function.args.first @@ -39,7 +39,7 @@ module Register end def _set_instance_variable(context , name = Virtual::Integer , value = Virtual::Integer ) - set_function = Virtual::MethodSource.create_method(:Object,:_set_instance_variable ,[] ) + set_function = Virtual::MethodSource.create_method(:Object,:int,:_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 0b121885..d972c4a0 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 , :putstring , [] ) + function = Virtual::MethodSource.create_method(:Word,:int , :putstring , [] ) Kernel.emit_syscall( function , :putstring ) function end diff --git a/lib/virtual/method_source.rb b/lib/virtual/method_source.rb index a884286c..fde7c74e 100644 --- a/lib/virtual/method_source.rb +++ b/lib/virtual/method_source.rb @@ -34,17 +34,18 @@ module Virtual # second, it creates MethodSource and attaches it to the method # # compile code then works with the method, but adds code tot the info - def self.create_method( class_name , method_name , args) + def self.create_method( class_name , return_type , method_name , args) raise "create_method #{class_name}.#{class_name.class}" unless class_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 raise "No such class #{class_name}" unless clazz + return_type = Virtual::Type.from_sym return_type method = clazz.create_instance_method( method_name , Virtual.new_list(args)) - method.source = MethodSource.new(method) + method.source = MethodSource.new(method , return_type) method end # just passing the method object in for Instructions to make decisions (later) - def initialize method , return_type = Virtual::Unknown + def initialize method , return_type # first block we have to create with .new , as new_block assumes a current enter = Block.new( "enter" , method ).add_code(MethodEnter.new( method )) @return_type = return_type diff --git a/lib/virtual/slots/frame_slot.rb b/lib/virtual/slots/frame_slot.rb index caa5eb94..25c584bd 100644 --- a/lib/virtual/slots/frame_slot.rb +++ b/lib/virtual/slots/frame_slot.rb @@ -4,7 +4,7 @@ module Virtual # Slots in the Frame are local or temporary variables in a message class FrameSlot < Slot - def initialize index , type = Unknown, value = nil + def initialize index , type , value = nil super(type, value) @index = index end diff --git a/lib/virtual/slots/message_slot.rb b/lib/virtual/slots/message_slot.rb index 5bdc052c..3b59536b 100644 --- a/lib/virtual/slots/message_slot.rb +++ b/lib/virtual/slots/message_slot.rb @@ -7,7 +7,7 @@ module Virtual # The Message has a layout as per the constant above class MessageSlot < Slot - def initialize type = Unknown , value = nil + def initialize type , value = nil super(type , value ) end def object_name @@ -19,28 +19,28 @@ module Virtual # Return is the return of MessageSlot class Return < MessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # Self is the self in MessageSlot class Self < MessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # MessageName of the current message class MessageName < MessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # NewMessageName of the next message class ArgSlot < MessageSlot - def initialize index , type = Unknown, value = nil + def initialize index , type , value = nil @index = index super( type , value ) end diff --git a/lib/virtual/slots/new_message_slot.rb b/lib/virtual/slots/new_message_slot.rb index 8d66fbc6..761203c9 100644 --- a/lib/virtual/slots/new_message_slot.rb +++ b/lib/virtual/slots/new_message_slot.rb @@ -7,7 +7,7 @@ module Virtual # The Message has a layout as per the constant above class NewMessageSlot < Slot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end def object_name @@ -19,28 +19,28 @@ module Virtual # NewReturn is the return of NewMessageSlot class NewReturn < NewMessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # NewSelf is the self of NewMessageSlot class NewSelf < NewMessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # NewMessageName of the next message class NewMessageName < NewMessageSlot - def initialize type = Unknown, value = nil + def initialize type , value = nil super( type , value ) end end # NewMessageName of the next message class NewArgSlot < NewMessageSlot - def initialize index , type = Unknown, value = nil + def initialize index , type , value = nil @index = index super( type , value ) end diff --git a/lib/virtual/slots/self_slot.rb b/lib/virtual/slots/self_slot.rb index 97d52324..2f844396 100644 --- a/lib/virtual/slots/self_slot.rb +++ b/lib/virtual/slots/self_slot.rb @@ -14,7 +14,7 @@ module Virtual # that object # class SelfSlot < Slot - def initialize type = Unknown, value = nil + def initialize type , value = nil super end def object_name diff --git a/lib/virtual/type.rb b/lib/virtual/type.rb index e4bec88c..c6eec9c4 100644 --- a/lib/virtual/type.rb +++ b/lib/virtual/type.rb @@ -7,6 +7,19 @@ module Virtual 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 + case type + when :int + Virtual::Integer + when :ref + Virtual::Reference + else + raise "No type maps to:#{type}" + end + end end class Integer < Type @@ -20,7 +33,4 @@ module Virtual attr_reader :of_class end - class Unknown < Type - end - end diff --git a/test/compiler/test_basic.rb b/test/compiler/test_basic.rb index f0c30888..a79833e5 100644 --- a/test/compiler/test_basic.rb +++ b/test/compiler/test_basic.rb @@ -36,7 +36,7 @@ class TestBasic < MiniTest::Test def test_name @string_input = 'foo ' - @output = "- Virtual::Return(:type => Virtual::Unknown)" + @output = "- Virtual::Return(:type => :int)" check end