2018-07-19 15:22:44 +02:00
|
|
|
module Ruby
|
2018-07-20 19:07:15 +02:00
|
|
|
# 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.
|
2019-08-19 09:31:11 +02:00
|
|
|
class RubyBlockStatement < Statement
|
2018-07-19 15:22:44 +02:00
|
|
|
attr_reader :send , :args , :body
|
2018-07-19 13:46:51 +02:00
|
|
|
|
2018-07-19 15:22:44 +02:00
|
|
|
def initialize( send , args , body )
|
|
|
|
@send , @args , @body = send , args , body
|
2018-07-19 13:46:51 +02:00
|
|
|
raise "no bod" unless @body
|
|
|
|
end
|
|
|
|
|
2019-10-03 23:36:49 +02:00
|
|
|
# This resolves to a Sol SendStatement, in fact that is mostly what it is.
|
2019-08-19 13:23:55 +02:00
|
|
|
#
|
|
|
|
# The implicitly passed block (in ruby) gets converted to the constant it is, and
|
|
|
|
# is passed as the last argument.
|
2018-07-20 19:07:15 +02:00
|
|
|
#
|
2019-10-03 23:36:49 +02:00
|
|
|
def to_sol
|
2019-08-19 13:23:55 +02:00
|
|
|
#block_name = "implicit_block_#{object_id}".to_sym
|
2019-10-03 23:36:49 +02:00
|
|
|
lambda = Sol::LambdaExpression.new( @args.dup , @body.to_sol)
|
|
|
|
ret = @send.to_sol
|
|
|
|
sendd = ret.is_a?(Sol::Statements) ? ret.last : ret
|
2019-08-19 13:23:55 +02:00
|
|
|
sendd.arguments << lambda
|
2018-07-20 19:07:15 +02:00
|
|
|
ret
|
2018-07-19 13:46:51 +02:00
|
|
|
end
|
2019-09-06 20:00:37 +02:00
|
|
|
def to_s(depth = 0)
|
|
|
|
at_depth(depth , "{|#{@args.join(',')}| #{@body}}")
|
|
|
|
end
|
2018-07-19 13:46:51 +02:00
|
|
|
end
|
|
|
|
end
|