lib/nydp/interpreted_function.rb in nydp-0.2.3 vs lib/nydp/interpreted_function.rb in nydp-0.2.5
- old
+ new
@@ -15,39 +15,31 @@
attr_accessor :arg_names, :body, :context_builder
def invoke_1 vm, parent_context
vm.instructions.push self.body
- vm.contexts.push LexicalContext.new(parent_context)
+ vm.contexts.push set_args_0 parent_context
end
def invoke_2 vm, parent_context, arg
- lc = LexicalContext.new parent_context
- set_args_1 lc, arg
vm.instructions.push self.body
- vm.contexts.push lc
+ vm.contexts.push set_args_1(parent_context, arg)
end
def invoke_3 vm, parent_context, arg_0, arg_1
- lc = LexicalContext.new parent_context
- set_args_2 lc, arg_0, arg_1
vm.instructions.push self.body
- vm.contexts.push lc
+ vm.contexts.push set_args_2(parent_context, arg_0, arg_1)
end
def invoke_4 vm, parent_context, arg_0, arg_1, arg_2
- lc = LexicalContext.new parent_context
- set_args_3 lc, arg_0, arg_1, arg_2
vm.instructions.push self.body
- vm.contexts.push lc
+ vm.contexts.push set_args_3(parent_context, arg_0, arg_1, arg_2)
end
def invoke vm, parent_context, arg_values
- lc = LexicalContext.new parent_context
- set_args lc, arg_values
vm.instructions.push self.body
- vm.contexts.push lc
+ vm.contexts.push set_args(parent_context, arg_values)
end
def setup_context context, names, values
if pair? names
context.set names.car, values.car
@@ -61,11 +53,10 @@
my_params = { }
index_parameters arg_list, my_params
ifn = Nydp::InterpretedFunction.new
ifn.arg_names = arg_list
ifn.extend Nydp::LexicalContextBuilder.select arg_list
- ifn.initialize_names arg_list
ifn.body = compile_body body, cons(my_params, bindings), []
ifn
end
def self.compile_body body_forms, bindings, instructions
@@ -88,9 +79,14 @@
hsh[arg_list] = hsh.size
end
end
def execute vm
+ # TODO do not create a new Closure if this function does not refer to it
+ # - including top-level function definitions
+ # - and any other function that does not refer to any lexically-bound outer variable
+ # - for example (fn (x) (* x x)) in (map λx(* x x) things) does not need a closure, because
+ # the function does not refer to any lexical variable outside itself.
vm.push_arg Closure.new(self, vm.current_context)
end
def nydp_type ; "fn" ; end
def inspect ; to_s ; end