Class: Rewrite::CallByThunk

Inherits:
SexpProcessor
  • Object
show all
Defined in:
lib/rewrite/evaluation_strategies.rb

Overview

Initialize with a list of names, e.g.

CallByThunk.new(:foo, :bar)

It then converts expressions of the form:

foo(expr1, expr2, ..., exprn)

into:

foo.call( lambda { expr1 }, lambda { expr2 }, ..., lambda { exprn })

This is handy when combined with RewriteVariablesAsThunkCalls in the following manner: if you rewrite function invocations with CallByThunk and also rewrite the function’s body to convert variable references into thunk calls, you now have a function with call-by-name semantics

Instance Method Summary collapse

Constructor Details

#initialize(*functions_to_thunkify) ⇒ CallByThunk

Returns a new instance of CallByThunk.



68
69
70
71
# File 'lib/rewrite/evaluation_strategies.rb', line 68

def initialize(*functions_to_thunkify)
  @functions_to_thunkify = functions_to_thunkify
  super()
end

Instance Method Details

#process_fcall(exp) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rewrite/evaluation_strategies.rb', line 73

def process_fcall(exp)
  qua = exp.dup
  exp.shift
  name = exp.shift
  if @functions_to_thunkify.include? name
    thunked = s(:call, s(:dvar, name), :call)
    unless exp.empty?
      arguments = exp.shift
      raise "Do not understand arguments #{arguments}" unless arguments[0] == :array
      arguments.shift
      thunked_arguments = s(:array)
      until arguments.empty?
        thunked_arguments <<  s(:iter, s(:fcall, :lambda), nil, process(arguments.shift))
      end
      thunked << thunked_arguments
    end
  else
    thunked = s(:fcall, name) # :fcall, name_of_the_function
    thunked << process(exp.shift) unless exp.empty?
  end
  thunked
end