better calcite and operator to expand the interpreter test
This commit is contained in:
parent
af6366f2d1
commit
83ef902b55
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,2 +1,3 @@
|
||||
require_relative "test_puts"
|
||||
require_relative "test_puti"
|
||||
require_relative "test_add"
|
||||
|
@ -7,6 +7,23 @@ class AddTest < MiniTest::Test
|
||||
def test_puti
|
||||
@string_input = <<HERE
|
||||
class Integer < Object
|
||||
ref digit( int rest )
|
||||
if( rest == 5 )
|
||||
return "5"
|
||||
end
|
||||
if( rest == 1 )
|
||||
return "1"
|
||||
end
|
||||
if( rest == 2 )
|
||||
return "2"
|
||||
end
|
||||
if( rest == 3 )
|
||||
return "3"
|
||||
end
|
||||
if( rest == 4 )
|
||||
return "4"
|
||||
end
|
||||
end
|
||||
ref add_string(ref str)
|
||||
int div
|
||||
div = self / 10
|
||||
@ -48,10 +65,15 @@ HERE
|
||||
"RegisterTransfer" ,"GetSlot" , "FunctionCall" ,"SaveReturn" , "GetSlot" ,
|
||||
"LoadConstant", "SetSlot", "GetSlot" , "GetSlot" , "SetSlot" ,
|
||||
"LoadConstant", "SetSlot" , "GetSlot" , "SetSlot" , "RegisterTransfer",
|
||||
"GetSlot", "FunctionCall", "SaveReturn", "GetSlot", "GetSlot",
|
||||
"SetSlot", "GetSlot", "SetSlot", "FunctionCall", "FunctionCall",
|
||||
"FunctionCall", "FunctionCall", "FunctionCall", "FunctionCall", "FunctionCall",
|
||||
"NilClass"].each_with_index do |name , index|
|
||||
"GetSlot", "FunctionCall", "SaveReturn", "GetSlot", "LoadConstant",
|
||||
"SetSlot", "GetSlot", "GetSlot", "OperatorInstruction", "GetSlot",
|
||||
"SetSlot", "GetSlot", "GetSlot", "OperatorInstruction", "GetSlot",
|
||||
"SetSlot", "LoadConstant", "SetSlot", "GetSlot", "GetSlot",
|
||||
"OperatorInstruction", "Branch", "GetSlot", "GetSlot", "SetSlot",
|
||||
"LoadConstant", "SetSlot", "GetSlot", "SetSlot", "RegisterTransfer",
|
||||
"GetSlot", "FunctionCall", "SaveReturn", "LoadConstant", "SetSlot",
|
||||
"GetSlot", "GetSlot", "OperatorInstruction", "Branch", "LoadConstant",
|
||||
"SetSlot"].each_with_index do |name , index|
|
||||
got = ticks(1)
|
||||
puts got
|
||||
assert got.class.name.index(name) , "Wrong class for #{index+1}, expect #{name} , got #{got}"
|
||||
|
Loading…
Reference in New Issue
Block a user