From 83ef902b5595784b691b09ad91afa87490ba5194 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 7 Oct 2015 10:05:34 +0300 Subject: [PATCH] better calcite and operator to expand the interpreter test --- lib/bosl/compiler/callsite_expression.rb | 18 +++++++------- lib/bosl/compiler/operator_expressions.rb | 23 ++++++++++++++--- lib/interpreter/interpreter.rb | 28 +++++++++++++++------ lib/register/instructions/get_slot.rb | 21 ++++++++++++++++ test/interpreter/test_all.rb | 1 + test/interpreter/test_puti.rb | 30 ++++++++++++++++++++--- 6 files changed, 97 insertions(+), 24 deletions(-) diff --git a/lib/bosl/compiler/callsite_expression.rb b/lib/bosl/compiler/callsite_expression.rb index 82e2339d..0aefffa4 100644 --- a/lib/bosl/compiler/callsite_expression.rb +++ b/lib/bosl/compiler/callsite_expression.rb @@ -8,7 +8,11 @@ module Bosl if receiver me = process( receiver.to_a.first ) else - me = Virtual::Self.new :int + if @method.class.name == :Integer + me = Virtual::Self.new :int + else + me = Virtual::Self.new :ref + end end ## need two step process, compile and save to frame # then move from frame to new message @@ -39,17 +43,11 @@ module Bosl raise "Method not implemented #{me.class}.#{code.name}" unless method @method.source.add_code Virtual::MethodCall.new( method ) elsif( me.is_a? Fixnum ) - 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 + #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 - # note: this is the current view: call internal send, even the method name says else - # but send is "special" and accesses the internal method name and resolves. - kernel = Virtual.machine.space.get_class_by_name(:Kernel) - method = kernel.get_instance_method(:__send) - @method.source.add_code Virtual::MethodCall.new( method ) raise "unimplemented: \n#{code} \nfor #{ref.inspect}" end else @@ -60,7 +58,9 @@ module Bosl raise "Method not implemented Integer.#{name}" unless method @method.source.add_code Virtual::MethodCall.new( method ) else - raise "me #{me}" + method = @clazz.get_instance_method(name) + raise "Method not implemented Integer.#{name}" unless method + @method.source.add_code Virtual::MethodCall.new( method ) end end raise "Method not implemented #{me.value}.#{name}" unless method diff --git a/lib/bosl/compiler/operator_expressions.rb b/lib/bosl/compiler/operator_expressions.rb index ef36e060..6fd15008 100644 --- a/lib/bosl/compiler/operator_expressions.rb +++ b/lib/bosl/compiler/operator_expressions.rb @@ -1,10 +1,25 @@ module Bosl Compiler.class_eval do -# operator attr_reader :operator, :left, :right + def on_operator expression - operator , left , right = *expression - #raise "not quite there" - Virtual::Return.new(:int) + puts "operator #{expression.inspect}" + operator , left_e , right_e = *expression + left_slot = process(left_e) + right_slot = process(right_e) + puts "left #{left_slot}" + puts "right #{right_slot}" + tmp1 = Register.tmp_reg + tmp2 = tmp1.next_reg_use + get = Register.get_slot_to(expression , left_slot , tmp1 ) + get2 = Register.get_slot_to(expression , right_slot , tmp2 ) + puts "GET #{get}" + puts "GET2 #{get2}" + @method.source.add_code get + @method.source.add_code get2 + + @method.source.add_code Register::OperatorInstruction.new(expression,operator, tmp1,tmp2) + + Virtual::Return.new(:int ) end def on_assign expression diff --git a/lib/interpreter/interpreter.rb b/lib/interpreter/interpreter.rb index 9934a119..f2998131 100644 --- a/lib/interpreter/interpreter.rb +++ b/lib/interpreter/interpreter.rb @@ -101,6 +101,13 @@ module Interpreter false end + def execute_IsZeroBranch + puts @instruction.inspect + target = @instruction.block + set_block target + false + end + def execute_LoadConstant to = @instruction.register value = @instruction.constant @@ -173,18 +180,25 @@ module Interpreter end def execute_OperatorInstruction + left = get_register(@instruction.left) + rr = @instruction.right + right = get_register(rr) case @instruction.operator when :add - left = get_register(@instruction.left) - rr = @instruction.right - right = get_register(rr) result = left + right - puts "#{@instruction} == #{result}" - right = set_register(rr , result) + when "/" + result = left / right + when "-" + result = left - right + when "<" + result = left < right + when "==" + result = left == right else - raise "unimplemented operator #{@instruction}" + raise "unimplemented #{@instruction.operator} #{@instruction}" end - + puts "#{@instruction} == #{result}" + right = set_register(rr , result) true end end diff --git a/lib/register/instructions/get_slot.rb b/lib/register/instructions/get_slot.rb index 1189388f..cac6ad65 100644 --- a/lib/register/instructions/get_slot.rb +++ b/lib/register/instructions/get_slot.rb @@ -45,4 +45,25 @@ module Register GetSlot.new( source , array , index , to) end + def self.get_slot_to source , slot , to + array = nil + index = nil + case slot + when Virtual::Self + array = :message + index = :receiver + when Virtual::Return + array = :message + index = :return_value + when Virtual::FrameSlot + array = :frame + index = slot.index + when Virtual::ArgSlot + array = :message + index = slot.index + else + raise "not done #{slot}" + end + get_slot( source , array , index , to) + end end diff --git a/test/interpreter/test_all.rb b/test/interpreter/test_all.rb index 9487f212..257893fd 100644 --- a/test/interpreter/test_all.rb +++ b/test/interpreter/test_all.rb @@ -1,2 +1,3 @@ require_relative "test_puts" +require_relative "test_puti" require_relative "test_add" diff --git a/test/interpreter/test_puti.rb b/test/interpreter/test_puti.rb index 593ddebe..8127fd1f 100644 --- a/test/interpreter/test_puti.rb +++ b/test/interpreter/test_puti.rb @@ -7,6 +7,23 @@ class AddTest < MiniTest::Test def test_puti @string_input = <