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
|
if receiver
|
||||||
me = process( receiver.to_a.first )
|
me = process( receiver.to_a.first )
|
||||||
else
|
else
|
||||||
me = Virtual::Self.new :int
|
if @method.class.name == :Integer
|
||||||
|
me = Virtual::Self.new :int
|
||||||
|
else
|
||||||
|
me = Virtual::Self.new :ref
|
||||||
|
end
|
||||||
end
|
end
|
||||||
## need two step process, compile and save to frame
|
## need two step process, compile and save to frame
|
||||||
# then move from frame to new message
|
# then move from frame to new message
|
||||||
@ -39,17 +43,11 @@ module Bosl
|
|||||||
raise "Method not implemented #{me.class}.#{code.name}" unless method
|
raise "Method not implemented #{me.class}.#{code.name}" unless method
|
||||||
@method.source.add_code Virtual::MethodCall.new( method )
|
@method.source.add_code Virtual::MethodCall.new( method )
|
||||||
elsif( me.is_a? Fixnum )
|
elsif( me.is_a? Fixnum )
|
||||||
name = :plus if name == :+
|
|
||||||
method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(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
|
raise "Method not implemented Integer.#{name}" unless method
|
||||||
@method.source.add_code Virtual::MethodCall.new( method )
|
@method.source.add_code Virtual::MethodCall.new( method )
|
||||||
else
|
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}"
|
raise "unimplemented: \n#{code} \nfor #{ref.inspect}"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -60,7 +58,9 @@ module Bosl
|
|||||||
raise "Method not implemented Integer.#{name}" unless method
|
raise "Method not implemented Integer.#{name}" unless method
|
||||||
@method.source.add_code Virtual::MethodCall.new( method )
|
@method.source.add_code Virtual::MethodCall.new( method )
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
raise "Method not implemented #{me.value}.#{name}" unless method
|
raise "Method not implemented #{me.value}.#{name}" unless method
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
module Bosl
|
module Bosl
|
||||||
Compiler.class_eval do
|
Compiler.class_eval do
|
||||||
# operator attr_reader :operator, :left, :right
|
|
||||||
def on_operator expression
|
def on_operator expression
|
||||||
operator , left , right = *expression
|
puts "operator #{expression.inspect}"
|
||||||
#raise "not quite there"
|
operator , left_e , right_e = *expression
|
||||||
Virtual::Return.new(:int)
|
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
|
end
|
||||||
|
|
||||||
def on_assign expression
|
def on_assign expression
|
||||||
|
@ -101,6 +101,13 @@ module Interpreter
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def execute_IsZeroBranch
|
||||||
|
puts @instruction.inspect
|
||||||
|
target = @instruction.block
|
||||||
|
set_block target
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def execute_LoadConstant
|
def execute_LoadConstant
|
||||||
to = @instruction.register
|
to = @instruction.register
|
||||||
value = @instruction.constant
|
value = @instruction.constant
|
||||||
@ -173,18 +180,25 @@ module Interpreter
|
|||||||
end
|
end
|
||||||
|
|
||||||
def execute_OperatorInstruction
|
def execute_OperatorInstruction
|
||||||
|
left = get_register(@instruction.left)
|
||||||
|
rr = @instruction.right
|
||||||
|
right = get_register(rr)
|
||||||
case @instruction.operator
|
case @instruction.operator
|
||||||
when :add
|
when :add
|
||||||
left = get_register(@instruction.left)
|
|
||||||
rr = @instruction.right
|
|
||||||
right = get_register(rr)
|
|
||||||
result = left + right
|
result = left + right
|
||||||
puts "#{@instruction} == #{result}"
|
when "/"
|
||||||
right = set_register(rr , result)
|
result = left / right
|
||||||
|
when "-"
|
||||||
|
result = left - right
|
||||||
|
when "<"
|
||||||
|
result = left < right
|
||||||
|
when "=="
|
||||||
|
result = left == right
|
||||||
else
|
else
|
||||||
raise "unimplemented operator #{@instruction}"
|
raise "unimplemented #{@instruction.operator} #{@instruction}"
|
||||||
end
|
end
|
||||||
|
puts "#{@instruction} == #{result}"
|
||||||
|
right = set_register(rr , result)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -45,4 +45,25 @@ module Register
|
|||||||
GetSlot.new( source , array , index , to)
|
GetSlot.new( source , array , index , to)
|
||||||
end
|
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
|
end
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
require_relative "test_puts"
|
require_relative "test_puts"
|
||||||
|
require_relative "test_puti"
|
||||||
require_relative "test_add"
|
require_relative "test_add"
|
||||||
|
@ -7,6 +7,23 @@ class AddTest < MiniTest::Test
|
|||||||
def test_puti
|
def test_puti
|
||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
class Integer < Object
|
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)
|
ref add_string(ref str)
|
||||||
int div
|
int div
|
||||||
div = self / 10
|
div = self / 10
|
||||||
@ -48,10 +65,15 @@ HERE
|
|||||||
"RegisterTransfer" ,"GetSlot" , "FunctionCall" ,"SaveReturn" , "GetSlot" ,
|
"RegisterTransfer" ,"GetSlot" , "FunctionCall" ,"SaveReturn" , "GetSlot" ,
|
||||||
"LoadConstant", "SetSlot", "GetSlot" , "GetSlot" , "SetSlot" ,
|
"LoadConstant", "SetSlot", "GetSlot" , "GetSlot" , "SetSlot" ,
|
||||||
"LoadConstant", "SetSlot" , "GetSlot" , "SetSlot" , "RegisterTransfer",
|
"LoadConstant", "SetSlot" , "GetSlot" , "SetSlot" , "RegisterTransfer",
|
||||||
"GetSlot", "FunctionCall", "SaveReturn", "GetSlot", "GetSlot",
|
"GetSlot", "FunctionCall", "SaveReturn", "GetSlot", "LoadConstant",
|
||||||
"SetSlot", "GetSlot", "SetSlot", "FunctionCall", "FunctionCall",
|
"SetSlot", "GetSlot", "GetSlot", "OperatorInstruction", "GetSlot",
|
||||||
"FunctionCall", "FunctionCall", "FunctionCall", "FunctionCall", "FunctionCall",
|
"SetSlot", "GetSlot", "GetSlot", "OperatorInstruction", "GetSlot",
|
||||||
"NilClass"].each_with_index do |name , index|
|
"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)
|
got = ticks(1)
|
||||||
puts got
|
puts got
|
||||||
assert got.class.name.index(name) , "Wrong class for #{index+1}, expect #{name} , got #{got}"
|
assert got.class.name.index(name) , "Wrong class for #{index+1}, expect #{name} , got #{got}"
|
||||||
|
Loading…
Reference in New Issue
Block a user