rubyx/lib/ruby/ruby_block_statement.rb

39 lines
1.4 KiB
Ruby
Raw Normal View History

module Ruby
# The way the ruby parser presents a call with a block is by wrapping the
# whole thing in a :block scope. It includes the send and the block definition.
#
# A block is in essence quite like a method, so the block definition is like a
# method definition, except it is not bound to the class direcly, but the enclosing
# method. The enclosing method also provides the scope.
class RubyBlockStatement < Statement
attr_reader :send , :args , :body
def initialize( send , args , body )
@send , @args , @body = send , args , body
raise "no bod" unless @body
end
# In Vool we "hoist" the block definition through a local assignment, much
# as we would other complex args (bit like in the Normalizer)
# The block is then passed as a normal variable to the send. In other words, the
# BlockStatement resolves to a list of Statements, the last of which is the send
#
def to_vool
block_name = "implicit_block_#{object_id}".to_sym
block = Vool::LambdaExpression.new( @args.dup , @body.to_vool)
assign = Vool::LocalAssignment.new( block_name , block)
sendd = @send.to_vool
if(sendd.is_a?(Vool::Statements))
ret = sendd
sendd = sendd.last
else
ret = Vool::Statements.new([sendd])
end
sendd.arguments << LocalVariable.new(block_name).to_vool
ret.prepend(assign)
ret
end
end
end