diff --git a/lib/ruby.rb b/lib/ruby.rb index 3055fec0..86fc7cfd 100644 --- a/lib/ruby.rb +++ b/lib/ruby.rb @@ -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" diff --git a/lib/ruby/callable.rb b/lib/ruby/callable.rb new file mode 100644 index 00000000..387950aa --- /dev/null +++ b/lib/ruby/callable.rb @@ -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 diff --git a/lib/ruby/send_statement.rb b/lib/ruby/send_statement.rb index 671d23c7..10698803 100644 --- a/lib/ruby/send_statement.rb +++ b/lib/ruby/send_statement.rb @@ -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 diff --git a/lib/ruby/yield_statement.rb b/lib/ruby/yield_statement.rb index 946d6bf2..b15fd11a 100644 --- a/lib/ruby/yield_statement.rb +++ b/lib/ruby/yield_statement.rb @@ -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 diff --git a/lib/vool/yield_statement.rb b/lib/vool/yield_statement.rb index b8121d26..ac13f224 100644 --- a/lib/vool/yield_statement.rb +++ b/lib/vool/yield_statement.rb @@ -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 diff --git a/test/ruby/test_yield_statement.rb b/test/ruby/test_yield_statement.rb index bbad76fe..be53a5fb 100644 --- a/test/ruby/test_yield_statement.rb +++ b/test/ruby/test_yield_statement.rb @@ -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 diff --git a/test/vool/test_yield_statement.rb b/test/vool/test_yield_statement.rb index e69de29b..51eff4e2 100644 --- a/test/vool/test_yield_statement.rb +++ b/test/vool/test_yield_statement.rb @@ -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