From 72d4adc7af2d09f1e862fd36dc929264802a6fd6 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 3 Jun 2014 22:16:57 +0300 Subject: [PATCH] another step closer to a working oo system --- lib/arm/memory_instruction.rb | 5 ++++- lib/ast/basic_expressions.rb | 4 ++-- lib/ast/call_site_expression.rb | 22 ++++++++++++++-------- lib/boot/object.rb | 8 ++++---- lib/core/array.rb | 20 -------------------- lib/vm/boot_class.rb | 15 ++++++++++----- lib/vm/boot_space.rb | 1 + lib/vm/constants.rb | 1 + lib/vm/meta_class.rb | 8 ++++++-- test/fragments/test_while_fibo.rb | 2 +- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/lib/arm/memory_instruction.rb b/lib/arm/memory_instruction.rb index 266554ad..2f75fdb9 100644 --- a/lib/arm/memory_instruction.rb +++ b/lib/arm/memory_instruction.rb @@ -11,7 +11,7 @@ module Arm @attributes[:update_status] = 0 if @attributes[:update_status] == nil @attributes[:condition_code] = :al if @attributes[:condition_code] == nil @operand = 0 - + raise "alert" if right.is_a? Vm::Block @pre_post_index = 0 #P flag @add_offset = 0 #U flag @is_load = opcode.to_s[0] == "l" ? 1 : 0 #L (load) flag @@ -31,7 +31,10 @@ module Arm @rn = arg if @right @operand = @right + #TODO better test, this operand integer (register) does not work. but sleep first + @operand = @operand.register if @operand.is_a? Vm::Integer unless( @operand.is_a? Symbol) + puts "operand #{@operand.inspect}" if (@operand < 0) @add_offset = 0 #TODO test/check/understand diff --git a/lib/ast/basic_expressions.rb b/lib/ast/basic_expressions.rb index 67e79f50..c6bed8ff 100644 --- a/lib/ast/basic_expressions.rb +++ b/lib/ast/basic_expressions.rb @@ -35,7 +35,7 @@ module Ast "#{self.class.name}.new(#{name})" end def to_s - name + name.to_s end def attributes [:name] @@ -54,7 +54,7 @@ module Ast self.class.name + '.new("' + string + '")' end def to_s - '"' + string + '"' + '"' + string.to_s + '"' end def compile context , into value = Vm::StringConstant.new(string) diff --git a/lib/ast/call_site_expression.rb b/lib/ast/call_site_expression.rb index b537c020..45fd65e6 100644 --- a/lib/ast/call_site_expression.rb +++ b/lib/ast/call_site_expression.rb @@ -13,15 +13,21 @@ module Ast def compile context , into params = args.collect{ |a| a.compile(context, into) } - r = context.current_class.name - if !receiver.nil? and receiver.name != :self - r = receiver.name - raise "uups #{receiver.class}.#{receiver.name.class}" unless r.is_a? Symbol + if receiver.name == :self + function = context.current_class.get_or_create_function(name) + elsif receiver.is_a? ModuleName + c_name = receiver.name + clazz = context.object_space.get_or_create_class c_name + raise "uups #{clazz}.#{c_name}" unless clazz + #class qualifier, means call from metaclass + clazz = clazz.meta_class + 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}" end - clazz = context.object_space.get_or_create_class r - - function = context.current_class.get_function(name) - raise "Forward declaration not implemented for #{clazz.name}:#{name} #{inspect}" if function == nil + raise "No such method error #{clazz.to_s}:#{name}" if function == nil call = Vm::CallSite.new( name , params , function) current_function = context.function current_function.save_locals(context , into) if current_function diff --git a/lib/boot/object.rb b/lib/boot/object.rb index 822c660c..e5704f22 100644 --- a/lib/boot/object.rb +++ b/lib/boot/object.rb @@ -24,10 +24,10 @@ module Boot return_to = get_function.return_type index_function = context.object_space.get_or_create_class(:Object).get_or_create_function(:index_of) b = get_function.body - b.push( me ) - index = b.call( index_function ) - b.pop(me) - return_to.at_index( get_function.body , me , index ) + b.push( [me] ) + b.call( index_function ) + b.pop([me]) + return_to.at_index( get_function.body , me , return_to ) get_function.set_return return_to return get_function end diff --git a/lib/core/array.rb b/lib/core/array.rb index ab588db7..31687853 100644 --- a/lib/core/array.rb +++ b/lib/core/array.rb @@ -1,26 +1,6 @@ # this is not a "normal" ruby file, ie it is not required by crystal # instead it is parsed by crystal to define part of the crystal that runs -class BaseObject - - def _set_instance_variable(name , value) - - end - - def _get_instance_variable( name ) - - end - - def _get_singleton_method(name ) - - end - def _add_singleton_method(method) - - end - def initialize - end -end - class Array < BaseObject def initialize size diff --git a/lib/vm/boot_class.rb b/lib/vm/boot_class.rb index d2bcc58c..1b6033fe 100644 --- a/lib/vm/boot_class.rb +++ b/lib/vm/boot_class.rb @@ -21,9 +21,11 @@ module Vm @functions << function end - def get_function name - name = name.to_sym - @functions.detect{ |f| f.name == name } + def get_function fname + fname = fname.to_sym + f = @functions.detect{ |f| f.name == fname } + names = @functions.collect{|f| f.name } + f end # way of creating new functions that have not been parsed. @@ -36,12 +38,15 @@ module Vm end unless fun fun = Core::Kernel.send(name , @context) - raise "no such function #{name}, #{name.class}" if fun == nil + return nil if fun == nil @functions << fun end fun end - + + def inspect + "BootClass #{@name} , super #{@super_class} #{@functions.length} functions" + 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 7dc32814..3a9523c6 100644 --- a/lib/vm/boot_space.rb +++ b/lib/vm/boot_space.rb @@ -45,6 +45,7 @@ module Vm # dummies, just for the other to compile obj = get_or_create_class :Object [:index_of , :_get_instance_variable].each do |f| + puts "adding #{f}" obj.add_function Boot::Object.send(f , @context) end end diff --git a/lib/vm/constants.rb b/lib/vm/constants.rb index cefa550e..f34c4f67 100644 --- a/lib/vm/constants.rb +++ b/lib/vm/constants.rb @@ -26,6 +26,7 @@ module Vm attr_reader :string # currently aligned to 4 (ie padded with 0) and off course 0 at the end def initialize str + str = str.to_s if str.is_a? Symbol length = str.length # rounding up to the next 4 (always adding one for zero pad) pad = ((length / 4 ) + 1 ) * 4 - length diff --git a/lib/vm/meta_class.rb b/lib/vm/meta_class.rb index 1442de37..5a65cab2 100644 --- a/lib/vm/meta_class.rb +++ b/lib/vm/meta_class.rb @@ -26,8 +26,12 @@ module Vm def get_function name name = name.to_sym - @functions.detect{ |f| f.name == name } + f = @functions.detect{ |f| f.name == name } + puts "no function for #{name} in Meta #{@me_self.inspect}" unless f + f + end + def inspect + "#{@me_self}, #{@functions.length} functions" end - end end diff --git a/test/fragments/test_while_fibo.rb b/test/fragments/test_while_fibo.rb index 3c4f7c35..8a2881d7 100644 --- a/test/fragments/test_while_fibo.rb +++ b/test/fragments/test_while_fibo.rb @@ -3,7 +3,7 @@ require_relative 'helper' class TestWhileFragment < MiniTest::Test include Fragments - def test_while + def test_while_fibo @string_input = <