Torsten Rüger
f87526f86f
Class, Method and Lambda (was block) are expressions. Just making things clearer, especially for the blocks (ahem, lambdas) is matters. wip
39 lines
1.4 KiB
Ruby
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 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
|