diff --git a/lib/arm/logic_instruction.rb b/lib/arm/logic_instruction.rb index b8cef6ec..3fe897b2 100644 --- a/lib/arm/logic_instruction.rb +++ b/lib/arm/logic_instruction.rb @@ -43,7 +43,7 @@ module Arm elsif (op_with_rot = calculate_u8_with_rr(right)) operand = op_with_rot immediate = 1 - raise "hmm" +# raise "hmm" else raise "cannot fit numeric literal argument in operand #{right.inspect}" end diff --git a/lib/arm/move_instruction.rb b/lib/arm/move_instruction.rb index 336d8f76..6a57c0ee 100644 --- a/lib/arm/move_instruction.rb +++ b/lib/arm/move_instruction.rb @@ -12,10 +12,10 @@ module Arm @immediate = 0 @rn = :r0 # register zero = zero bit pattern - raise inspect if to.is_a?(Vm::Value) and - from.is_a?(Vm::Value) and - !@attributes[:shift_lsr] and - to.register == from.register +# raise inspect if to.is_a?(Vm::Value) and +# from.is_a?(Vm::Value) and +# !@attributes[:shift_lsr] and +# to.register == from.register end # arm intrucions are pretty sensible, and always 4 bytes (thumb not supported) diff --git a/lib/ast/call_site_expression.rb b/lib/ast/call_site_expression.rb index f25a001b..b49d9085 100644 --- a/lib/ast/call_site_expression.rb +++ b/lib/ast/call_site_expression.rb @@ -15,14 +15,18 @@ module Ast raise "uups #{clazz}.#{c_name}" unless clazz #class qualifier, means call from metaclass clazz = clazz.meta_class + value = clazz + puts "CLAZZ #{value}" function = clazz.get_or_create_function(name) elsif receiver.is_a? VariableExpression raise "not implemented instance var:#{receiver}" else - raise "not implemented case (dare i say system error):#{receiver}" + # should be case switch for basic tyes and dynamic dispatch for objects reference + value = context.locals[receiver.name] + function = context.current_class.get_or_create_function(name) end raise "No such method error #{clazz.to_s}:#{name}" if function == nil - call = Vm::CallSite.new( name , params , function) + call = Vm::CallSite.new( name , value , params , function) current_function = context.function current_function.save_locals(context , into) if current_function call.load_args into diff --git a/lib/boot/object.rb b/lib/boot/object.rb index e5704f22..9fead4ce 100644 --- a/lib/boot/object.rb +++ b/lib/boot/object.rb @@ -32,17 +32,17 @@ module Boot return get_function end - def _set_instance_variable(name , value) + def _set_instance_variable(context , name , value) raise name end - def _get_singleton_method(name ) + def _get_singleton_method(context , name ) raise name end - def _add_singleton_method(method) + def _add_singleton_method(context, method) raise "4" end - def initialize() + def initialize(context) raise "4" end end diff --git a/lib/boot/string.rb b/lib/boot/string.rb new file mode 100644 index 00000000..ecd43393 --- /dev/null +++ b/lib/boot/string.rb @@ -0,0 +1,15 @@ +module Boot + class String + module ClassMethods + def get context , index = Vm::Integer + get_function = Vm::Function.new(:get , [Vm::Integer, Vm::Integer] , Vm::Integer ) + return get_function + end + def set context , index = Vm::Integer , char = Vm::Integer + set_function = Vm::Function.new(:set , [Vm::Integer, Vm::Integer, Vm::Integer] , Vm::Integer ) + return set_function + end + end + extend ClassMethods + end +end diff --git a/lib/core/string.rb b/lib/core/string.rb deleted file mode 100644 index 94d7bfbb..00000000 --- a/lib/core/string.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Core - class String - module ClassMethods - end - extend ClassMethods - end -end diff --git a/lib/vm/boot_class.rb b/lib/vm/boot_class.rb index 1b6033fe..33a8ab03 100644 --- a/lib/vm/boot_class.rb +++ b/lib/vm/boot_class.rb @@ -38,7 +38,6 @@ module Vm end unless fun fun = Core::Kernel.send(name , @context) - return nil if fun == nil @functions << fun end fun @@ -47,6 +46,9 @@ module Vm def inspect "BootClass #{@name} , super #{@super_class} #{@functions.length} functions" end + def to_s + inspect + end # Code interface follows. Note position is inheitted as is from Code # length of the class is the length of it's functions diff --git a/lib/vm/boot_space.rb b/lib/vm/boot_space.rb index 3a9523c6..3418ab41 100644 --- a/lib/vm/boot_space.rb +++ b/lib/vm/boot_space.rb @@ -4,6 +4,7 @@ require_relative "call_site" require "arm/arm_machine" require "core/kernel" require "boot/object" +require "boot/string" module Vm # The BootSpace is contains all objects for a program. In functional terms it is a program, but on oo @@ -48,6 +49,11 @@ module Vm puts "adding #{f}" obj.add_function Boot::Object.send(f , @context) end + obj = get_or_create_class :String + [:get , :set].each do |f| + puts "adding #{f}" + obj.add_function Boot::String.send(f , @context) + end end def add_object o return if @objects.include? o diff --git a/lib/vm/call_site.rb b/lib/vm/call_site.rb index 121819a1..d6111b68 100644 --- a/lib/vm/call_site.rb +++ b/lib/vm/call_site.rb @@ -4,13 +4,14 @@ module Vm class CallSite < Value - def initialize(name , args , function ) + def initialize(name , value , args , function ) @name = name + @value = value @args = args @function = function end - attr_reader :function , :args , :name - + attr_reader :function , :args , :name , :value + def load_args into args.each_with_index do |arg , index| if arg.is_a?(IntegerConstant) or arg.is_a?(StringConstant) diff --git a/lib/vm/constants.rb b/lib/vm/constants.rb index f34c4f67..12e10907 100644 --- a/lib/vm/constants.rb +++ b/lib/vm/constants.rb @@ -15,6 +15,9 @@ module Vm @integer = int end attr_reader :integer + def value + @integer + end end # The name really says it all. diff --git a/lib/vm/function.rb b/lib/vm/function.rb index c4346144..5f09d7b5 100644 --- a/lib/vm/function.rb +++ b/lib/vm/function.rb @@ -65,7 +65,8 @@ module Vm def new_local type = Vm::Integer register = args.length + @locals.length l = type.new(register + 1) # one for the type register 0, TODO add type as arg0 implicitly - raise "the red flag #{inspect}" if l.register > 6 + puts "new local #{l.register}" +# raise "Register overflow in function #{name}" if l.register > 6 @locals << l l end diff --git a/lib/vm/meta_class.rb b/lib/vm/meta_class.rb index 5a65cab2..12514d3f 100644 --- a/lib/vm/meta_class.rb +++ b/lib/vm/meta_class.rb @@ -30,8 +30,22 @@ module Vm puts "no function for #{name} in Meta #{@me_self.inspect}" unless f f end + # way of creating new functions that have not been parsed. + def get_or_create_function name + fun = get_function name + unless fun or name == :Object + supr = @context.object_space.get_or_create_class(@super_class) + fun = supr.get_function name + puts "#{supr.functions.collect(&:name)} for #{name} GOT #{fun.class}" if name == :index_of + end + fun + end + def inspect - "#{@me_self}, #{@functions.length} functions" + "MetaClass on #{@me_self}, #{@functions.length} functions" + end + def to_s + inspect end end end diff --git a/test/fragments/test_class.rb b/test/fragments/test_class.rb index 8527952a..495b3345 100644 --- a/test/fragments/test_class.rb +++ b/test/fragments/test_class.rb @@ -7,13 +7,15 @@ class TestClass < MiniTest::Test @string_input = <