anchor.diff:        erlang:throw(invalid_export_decl)
     end.
   
  -parse_defuns(Sexprs) ->
  -  lists:map(fun parse_defun/1, Sexprs).
  -
  -parse_defun(Sexpr) ->
  -  case parse(Sexpr, es_env:empty(), true) of
  -    {'ES:DEFINE', _Var, {'ES:LAMBDA', _Formals, _Body}} = Defun ->
  -      Defun;
  +check_exports(Exports, ModEnv) ->
  +  lists:foreach(fun (Export) -> check_export(Export, ModEnv) end, Exports).
  +
  +check_export({F, A}, ModEnv) ->
  +  case es_env:lookup(ModEnv, F) of
  +    {value, A} -> ok;
  +    {value, B} -> erlang:throw({export_wrong_arity, F, A, B});
  +    none -> erlang:throw({export_undef, F, A})
  +  end.
  +
  +parse_pre_defuns(Sexprs) ->
  +  lists:map(fun parse_pre_defun/1, Sexprs).
  +
  +parse_pre_defun(Sexpr) ->
  +  case Sexpr of
  +    ['define', Name, ['lambda', Formals, Body]] when is_atom(Name) ->
  +      try length(Formals) of
  +        _Arity -> {Name, Formals, Body}
  +      catch error:badarg ->
  +        erlang:throw({bad_formals, Formals})
  +      end;
       _ ->
         erlang:throw({invalid_defun, Sexpr})
     end.
  +
  +build_modenv(PreDefuns) ->
  +  lists:foldl(fun build_modenv/2, es_env:empty(), PreDefuns).
  +
  +build_modenv({Name, Formals, _Body}, Env) ->
  +  Arity = length(Formals),
  +  case es_env:is_bound(Env, Name) of
  +    true -> erlang:throw({already_bound, Name, Arity});
  +    false -> es_env:enter(Env, Name, Arity)
  +  end.
  +
  +parse_defuns(PreDefuns, ModEnv) ->
  +  lists:map(fun (PreDefun) -> parse_defun(PreDefun, ModEnv) end, PreDefuns).
  +
  +parse_defun({Name, Formals, Body}, ModEnv) ->
  +  {'ES:DEFINE', Name, parse_plain_lambda(Formals, Body, ModEnv)}.
  +
  +%% Internals: Expressions ------------------------------------------------------
   
   parse(Sexpr, Env) ->
     parse(Sexpr, Env, false).
  
positive.code:   end.
  
  bind(Var, ScopeEnv) when is_atom(Var) ->
    case es_env:lookup(ScopeEnv, Var) of
      none ->
        es_env:enter(ScopeEnv, Var, []);
      _ ->
        erlang:throw({bad_var, Var})
    end.
  
  parse_let(Tl, Env) ->
  
negative.code: module(Sexprs) ->
    {Name, Sexprs1} = parse_module_decl(Sexprs),
    {Exports, Sexprs2} = parse_export_decl(Sexprs1),
    PreDefuns = parse_pre_defuns(Sexprs2),
    ModEnv = build_modenv(PreDefuns),
    Defuns = parse_defuns(PreDefuns, ModEnv),
    check_exports(Exports, ModEnv),
    {'ES:MODULE', Name, Exports, Defuns}.
  
  -spec toplevel(sexpr()) -> ast().
  toplevel(Sexpr) ->
    parse(Sexpr, es_env:empty(), true).
  
  %% Internals: Modules ----------------------------------------------------------
  
  parse_module_decl(Sexprs) ->
    case Sexprs of
  