anchor.diff:      "number_t"
     else if (t = typeof<double>) then
       "number_t"
  -  else 
  +  else if (t = typeof<Environment>) then 
  +    ("env_t_" + getVariableCounter.ToString() + "*")
  +    else if (t = typeof<Closure<double, double>>) then 
  +    ("closure_t*")
  +  else
       t.ToString()
   
   
   (* C code generation for an expression *)
   let rec ccodegen (e:Expr): string =
     match e with
  +  | ApplyClosure (closure) -> sprintf "%s->env->y = y" closure.Name
     | Patterns.Lambda (x, body) -> sprintf "ERROR LAMBDA NOT SUPPORTED!"
  +  | EnvRef(env, name) -> sprintf "%s->%s" (ccodegen env) name
     | Patterns.Call (None, op, elist) -> 
       match op.Name with
  -      | OperatorName opname -> sprintf "%s %s %s" (prettyprint elist.[0]) opname (ccodegen elist.[1]) 
  +      | OperatorName opname -> sprintf "%s %s %s" (ccodegen 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))
  
positive.code:   | _ -> 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 = 
      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
      | _ -> 
        ccodegen e
    sprintf "%s %s = %s;" (ccodegenType var.Type) (var.Name) (rhs)
  
  (* C code generation for a function *)
  let 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)
  
  (* Performs a simple kind of ANF conversion for specific statements. *)
  let rec anfConversion (e: Expr): Expr = 
  
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 =
  