                         # we need to push assignments of any closed over parameters into the environment at this point
                         for param in n.params
                                 if n.ejs_env.closed.member param.name
-                                        n.body.body.splice 1, 0, {
+                                        prepends.push {
                                                 type: syntax.ExpressionStatement
                                                 expression:
                                                         type: syntax.AssignmentExpression,

                                env = env.parent
                n


#
#   This pass walks the tree and moves all function expressions to the toplevel.
#
#   at the point where this pass runs there are a couple of assumptions:
# 
#   1. there are no function declarations anywhere in the program.  They have all
#      been converted to 'var X = %makeClosure(%env_Y, function (%env) { ... })'
# 
#   2. There are no free variables in the function expressions.
#
class LambdaLift extends NodeVisitor
        constructor: (module) ->
                super
                @functions = []
                @mappings = []

        currentMapping: -> if @mappings.length > 0 then @mappings[0] else {}

        visitProgram: (program) ->
                super
                program.body = @functions.concat program.body
                program

        visitFunctionDeclaration: (n) ->
                n.body = @visit n.body
                n

        visitFunctionExpression: (n) ->
                if n.id?.name?
                        global_name = genGlobalFunctionName n.id.name
                        @currentMapping()[n.id.name] = global_name
                else
                        global_name = genAnonymousFunctionName()

                n.type = syntax.FunctionDeclaration
                n.id =
                        type: syntax.Identifier
                        name: global_name

                @functions.push n

                new_mapping = deep_copy_object @currentMapping()

                @mappings.unshift new_mapping
                n.body = @visit n.body
                @mappings = @mappings.slice(1)

                n.params.unshift create_identifier "%env_#{n.ejs_env.parent.id}"
                
                return {
                        type: syntax.Identifier,
                        name: global_name
                }

create_identifier = (x) -> type: syntax.Identifier, name: x
create_string_literal = (x) -> type: syntax.Literal, value: x, raw: "\"#{x}\""

# this should move to echo-desugar.coffee
FuncsToVars = class FuncsToVars extends NodeVisitor
        constructor: (module) ->
                super

        visitFunctionDeclaration: (n) ->
                if n.toplevel
                        super

                @mappings = []

        currentMapping: -> if @mappings.length > 0 then @mappings[0] else {}

        visitIdentifier: (n) ->
                if @currentMapping().hasOwnProperty n.name
                        return @currentMapping()[n.name]
                n

