rubyx/lib/ruby/block_statement.rb
Torsten Ruger 235853ab2d first run at ruby block to_vool
leaving the parser structure in the ruby layer,
but adopting the constant approach in vool
2018-07-20 20:07:15 +03:00

39 lines
1.4 KiB
Ruby

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 BlockStatement < 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::BlockStatement.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