callable as base for yield and send

more yield tests
This commit is contained in:
Torsten Ruger 2018-07-21 14:34:39 +03:00
parent 84a6fb1aba
commit b6c85cd4a4
7 changed files with 95 additions and 66 deletions

View File

@ -14,7 +14,6 @@ require_relative "ruby/array_statement"
require_relative "ruby/block_statement"
require_relative "ruby/if_statement"
require_relative "ruby/normalizer"
require_relative "ruby/send_statement"
require_relative "ruby/class_statement"
require_relative "ruby/logical_statement"
require_relative "ruby/return_statement"
@ -23,6 +22,8 @@ require_relative "ruby/basic_values"
require_relative "ruby/hash_statement"
require_relative "ruby/method_statement"
require_relative "ruby/ruby_compiler"
require_relative "ruby/callable"
require_relative "ruby/send_statement"
require_relative "ruby/yield_statement"
require_relative "ruby/variables"

36
lib/ruby/callable.rb Normal file
View File

@ -0,0 +1,36 @@
module Ruby
class Callable < Statement
attr_reader :name , :receiver , :arguments
def initialize(name , receiver , arguments )
@name , @receiver , @arguments = name , receiver , arguments
@arguments ||= []
end
def to_vool
statements = Vool::Statements.new([])
arguments = []
@arguments.each_with_index do |arg , index |
normalize_arg(arg , arguments , statements)
end
if statements.empty?
return vool_brother.new(@name, @receiver.to_vool , arguments)
else
statements << vool_brother.new(@name, @receiver.to_vool , arguments)
return statements
end
end
def normalize_arg(arg , arguments , statements)
if arg.is_a?(Constant) and !arg.is_a?(SendStatement)
arguments << arg.to_vool
return
end
assign = Vool::LocalAssignment.new( "tmp_#{arg.object_id}".to_sym, arg.to_vool)
statements << assign
arguments << Vool::LocalVariable.new(assign.name)
end
end
end

View File

@ -1,37 +1,6 @@
module Ruby
class SendStatement < Statement
attr_reader :name , :receiver , :arguments
def initialize(name , receiver , arguments )
@name , @receiver , @arguments = name , receiver , arguments
@arguments ||= []
end
def to_vool
statements = Vool::Statements.new([])
arguments = []
@arguments.each_with_index do |arg , index |
normalize_arg(arg , arguments , statements)
end
if statements.empty?
return Vool::SendStatement.new(@name, @receiver.to_vool , arguments)
else
statements << Vool::SendStatement.new(@name, @receiver.to_vool , arguments)
return statements
end
end
def normalize_arg(arg , arguments , statements)
if arg.is_a?(Constant) and !arg.is_a?(SendStatement)
arguments << arg.to_vool
return
end
assign = Vool::LocalAssignment.new( "tmp_#{arg.object_id}".to_sym, arg.to_vool)
statements << assign
arguments << Vool::LocalVariable.new(assign.name)
end
class SendStatement < Callable
def to_s
"#{receiver}.#{name}(#{arguments.join(', ')})"
end

View File

@ -1,39 +1,13 @@
module Ruby
class YieldStatement < Statement
attr_reader :arguments
class YieldStatement < Callable
def initialize(arguments )
@arguments = arguments
@arguments ||= []
end
def to_vool
statements = Statements.new([])
arguments = []
@arguments.each_with_index do |arg , index |
normalize_arg(arg , arguments , statements)
end
if statements.empty?
return YieldStatement.new(@name, @receiver , @arguments)
else
statements << YieldStatement.new(@name, @receiver , arguments)
return statements
end
end
def to_vool_arg(arg , arguments , statements)
if arg.respond_to?(:slot_definition) and !arg.is_a?(YieldStatement)
arguments << arg
return
end
assign = LocalAssignment.new( "tmp_#{arg.object_id}".to_sym, arg.to_vool)
statements << assign
arguments << LocalVariable.new(assign.name)
def initialize(arguments)
super("yield_#{object_id}".to_sym , SelfExpression.new , arguments)
end
def to_s
"#{receiver}.#{name}(#{arguments.join(', ')})"
"yield(#{arguments.join(', ')})"
end
end
end

View File

@ -3,8 +3,10 @@ module Vool
class YieldStatement < Statement
attr_reader :arguments
def initialize(arguments )
def initialize(name , receiver , arguments)
@arguments = arguments
@receiver = receiver
@name = name
@arguments ||= []
end
@ -24,7 +26,7 @@ module Vool
# - a SimpleCall,
def to_mom( compiler )
@parfait_block = @block.to_mom(compiler) if @block
@receiver = SelfExpression.new(compiler.self_type) if @receiver.is_a?(SelfExpression)
@receiver = SelfExpression.new(compiler.receiver_type) if @receiver.is_a?(SelfExpression)
if(@receiver.ct_type)
simple_call(compiler)
else

View File

@ -1,11 +1,25 @@
require_relative "helper"
module Ruby
class TestYieldStatementVool < MiniTest::Test
include RubyTests
def setup()
input = "yield(0)"
@lst = compile( input ).to_vool
end
def test_block
assert_equal Vool::YieldStatement , @lst.class
end
def test_block_args
assert_equal Vool::IntegerConstant , @lst.arguments.first.class
end
end
class TestYieldStatement < MiniTest::Test
include RubyTests
def setup()
input = "yield(0) "
input = "yield(0)"
@lst = compile( input )
end
def test_block

View File

@ -0,0 +1,33 @@
require_relative "helper"
module Vool
class TestYieldArgsSendMom < MiniTest::Test
include MomCompile
include Mom
def setup
Parfait.boot!
@ins = compile_first_method( "yield(1)" )
end
def test_array
check_array [MessageSetup, ArgumentTransfer, SimpleCall, SlotLoad, MessageSetup ,
ArgumentTransfer, SimpleCall, SlotLoad] , @ins
end
def pest_one_call
assert_equal SimpleCall, @ins.next(2).class
assert_equal :+, @ins.next(2).method.name
end
def pest_two_call
assert_equal SimpleCall, @ins.next(6).class
assert_equal :main, @ins.next(6).method.name
end
def pest_args_one_l
left = @ins.next(1).arguments[0].left
assert_equal Symbol, left.known_object.class
assert_equal :message, left.known_object
assert_equal [:next_message, :arguments, 1], left.slots
end
end
end