 
 # LAMBDA
 
-evaluateLambda = (name, exp, env, kont) ->
+evaluateLambda = (names, exp, env, kont) ->
   resume kont, new Function names, exp, env
 
 class Function extends Value

    @f(v)
    
class Primitive extends Value
  constructor: (@name, @address) ->
    




evaluate = (e, env, kont) ->
  [type, exp] = [(ntype e), (nvalu e)]
  if type == "symbol"
    return variables.evaluate exp, env, kont

  if type in ["number", "string", "boolean", "vector"]
    return exp

  if type == "list"
    head = car exp
    if (ntype head) == 'symbol'
      switch (nvalu head)
        when "quote" then resume (cdr exp), kont
        when "if" then evaluateIf (cdr exp), env, kont

          evaluate (cadr e), env, new Ifs((-> (caddr e)), (->(cadddr e)), env, kont)
        when "begin" then eprogn (cdr exp), env
        when "set!" then update (nvalu cadr exp), env, (evaluate (caddr exp), env)
        when "lambda" then make_function (astSymbolsToLispSymbols cadr exp), (cddr exp), env
        else invoke (evaluate (car exp), env), (evlis (cdr exp), env)
    else
      invoke (evaluate (car exp), env), (evlis (cdr exp), env)
  else
    throw new Error("Can't handle a #{type}")

class Ifs:
  evaluate: (cond, pass, alt, env, kont) ->
    if cond then 

  resume: (

env_init = nil
env_global = env_init

ntype = (node) -> car node
nvalu = (node) -> cadr node

definitial = (name, value = nil) ->
  env_global = (cons (cons name, value), env_global)
  name

defprimitive = (name, nativ, arity) ->
  definitial name, ((args) ->
    vmargs = listToVector(args)
    if (vmargs.length == arity)
      nativ.apply null, vmargs
    else
      throw "Incorrect arity")


definitial "#t", true
definitial "#f", the_false_value
definitial "nil", nil
for i in [
  "x", "y", "z", "a", "b", "c", "foo", "bar", "hux",
  "fib", "fact", "visit", "primes", "length"]
  definitial i


defpredicate = (name, nativ, arity) ->
  defprimitive name, ((a, b) -> if nativ.call(null, a, b) then true else the_false_value), arity
