anchor.diff:    | _ -> sprintf "ERROR[%A]" e
   
   (* C code generation for a statement in the form of `let var = e` *)
  -let ccodegenStatement (var: Var, e: Expr): string = 
  -  let rhs = 
  +let rec ccodegenStatement (var: Var, e: Expr): string * string List = 
  +  let (rhs, funs) = 
       match e with 
       | Patterns.NewArray(tp, elems) -> 
  -      sprintf "malloc(sizeof(%s) * %d);\n\t%s" (ccodegenType tp) (List.length elems) 
  -        (String.concat "\n\t" (List.mapi (fun index elem -> sprintf "%s[%d] = %s;" var.Name index (ccodegen elem)) elems))
  -    | MakeClosure(lam, env) ->
  -      sprintf "MAKE CLOSURE { %A, %A }" lam env
  +      let args = (String.concat "\n\t" (List.mapi (fun index elem -> sprintf "%s[%d] = %s;" var.Name index (ccodegen elem)) elems))
  +      let rhs = sprintf "malloc(sizeof(%s) * %d);\n\t%s" (ccodegenType tp) (List.length elems) args
  +      (rhs, [])
  +    | MakeClosure(envVar, lamBody, env) ->
  +      let lambdaName = newVar "lambda"
  +      let id = getVariableCounter
  +      let envName = sprintf "env_t_%d" id
  +      let fields = ["number_t", "y"]  (* TODO generalize *)
  +      let fieldsDeclList = List.map (fun (tp, v) -> tp + " " + v) fields
  +      let fieldsStructDecl = (String.concat "\n\t" (List.map (fun x -> x + ";") fieldsDeclList))
  +      let envStruct = sprintf "typedef struct %s {\n\t%s\n} %s;" envName fieldsStructDecl envName
  +      let fieldsDecl = String.concat "," fieldsDeclList
  +      let fieldsInit = String.concat "\n\t" (List.map (fun (_, v) -> sprintf "env->%s = %s;" v v) fields)
  +      let makeEnvDef = sprintf "%s* make_%s(%s) {\n\t%s* env = malloc(sizeof(%s));\n\t%s\n\treturn env;\n}" envName envName fieldsDecl envName envName fieldsInit
  +      let makeEnvInvoke = sprintf "make_%s(%s)" envName (String.concat "," (List.map (fun (_, v) -> v) fields))
  +      (sprintf "make_closure(%s, %s);" lambdaName makeEnvInvoke, [envStruct; makeEnvDef; ccodegenFunction (Expr.Lambda(envVar, lamBody)) lambdaName])
       | _ -> 
  -      ccodegen e
  -  sprintf "%s %s = %s;" (ccodegenType var.Type) (var.Name) (rhs)
  +      (ccodegen e, [])
  +  (sprintf "%s %s = %s;" (ccodegenType var.Type) (var.Name) (rhs), funs)
   
   (* C code generation for a function *)
  -let ccodegenFunction (e: Expr) (name: string): string =
  +and ccodegenFunction (e: Expr) (name: string): string =
     let rec extractHeader exp curInputs statements = match exp with 
       | LambdaN (inputs, body) -> extractHeader body (List.append curInputs inputs) statements
       | Patterns.Let(x, e1, e2) -> extractHeader e2 curInputs (List.append statements [(x, e1)])
       | _ -> (exp, curInputs, statements)
     let (result, inputs, statements) = extractHeader e [] []
  -  let statementsCode = (String.concat "\n\t" (List.map ccodegenStatement statements))
  -  sprintf "%s %s(%s) {\n\t%s\n\treturn %s;\n}" (ccodegenType(result.Type)) name (String.concat ", " (List.map (fun (x: Var) -> ccodegenType(x.Type) + " " + x.Name) inputs)) statementsCode (ccodegen result)
  +  let (statementsCodeList, closuresList) = List.unzip (List.map ccodegenStatement statements)
  +  let statementsCode = (String.concat "\n\t" statementsCodeList)
  +  let closuresCode = (String.concat "\n" (List.concat closuresList))
  +  sprintf "%s\n%s %s(%s) {\n\t%s\n\treturn %s;\n}" (closuresCode) (ccodegenType(result.Type)) name (String.concat ", " (List.map (fun (x: Var) -> ccodegenType(x.Type) + " " + x.Name) inputs)) statementsCode (ccodegen result)
   
   (* Performs a simple kind of ANF conversion for specific statements. *)
   let rec anfConversion (e: Expr): Expr = 
  
positive.code:     "number_t"
    else if (t = typeof<double>) then
      "number_t"
    else 
      t.ToString()
  
  
  (* C code generation for an expression *)
  let rec ccodegen (e:Expr): string =
    match e with
    | Patterns.Lambda (x, body) -> sprintf "ERROR LAMBDA NOT SUPPORTED!"
    | Patterns.Call (None, op, elist) -> 
      match op.Name with
        | OperatorName opname -> sprintf "%s %s %s" (prettyprint elist.[0]) opname (ccodegen elist.[1]) 
        | "GetArray" -> sprintf "%s[%s]" (ccodegen elist.[0]) (ccodegen elist.[1])
        | "Map" when op.DeclaringType.Name = "ArrayModule" -> sprintf "array_map(%s)" (String.concat ", " (List.map ccodegen elist))
        | _ -> sprintf "ERROR CALL %s(%s)" op.Name (String.concat ", " (List.map ccodegen elist))
  
negative.code:   | LambdaN(inputs, body) -> (inputs, body) 
    | _ -> ([], e)
  
  let (|MakeClosure|_|) (e: Expr): (Var * Expr * Expr) Option = 
    match e with 
    | Patterns.Call (None, op, [Patterns.Lambda(envVar, body); makeEnv]) when op.Name = "makeClosure" -> Some (envVar, body, makeEnv)
    | _ -> None
  
  let (|ApplyClosure|_|) (e: Expr): Var Option = 
    match e with 
    | Patterns.Lambda(arg, Patterns.Call (None, op, [Patterns.Var(closure); Patterns.Var(arg2)])) when (op.Name = "applyClosure") && (arg = arg2) ->
       Some (closure)
    | _ -> None
  
  let (|EnvRef|_|) (e: Expr): (Expr * string) Option = 
    match e with 
    | Patterns.Call (None, op, [env; Patterns.Value(s, _)]) when op.Name = "envRef" -> Some (env, s.ToString())
    | _ -> None
  
  let LambdaN (inputs: Var List, body: Expr): Expr =
  