var _ = require('underscore');

SYMBOL_TABLE = {}

exports.define = function (sym, val) {
  SYMBOL_TABLE[sym] = val;
}

exports.eval = function eval(form, stack_frame) {
  if (typeof stack_frame == 'undefined') {
    stack_frame = SYMBOL_TABLE;
  }

  if (_.isEqual(form, null)) {
    return null;
  }

  if (form.type == 'id')
    return stack_frame[form.name];
  else if (_.isArray(form)) {
    var func = eval(form[0], stack_frame);
    var args = form.slice(1);
    args.unshift(stack_frame);
    return func.apply(undefined, args);
  }
  else {
    return form;
  }
}

exports.evalAll = function (forms, stack_frame) {
  if (typeof stack_frame == 'undefined') {
    stack_frame = SYMBOL_TABLE;
  }

  var results = [];
  for (var i = 0; i < forms.length; i++) {
    results[i] = exports.eval(forms[i], stack_frame);
  }
  return results[results.length - 1]; // return last form
}

exports.define('stack', function (_s) {
  console.log(_s);
});

exports.define('sym', function () {
  console.log(SYMBOL_TABLE);
});

@@ -109,24 +109,229 @@
 %5D = val;%0A%7D%0A%0A
+exports.apply = function (fn, args, stack_frame) %7B%0A  if (typeof fn != 'function')%0A    throw %22cannot evaluate non-function value: %22 + fn;%0A  args.unshift(stack_frame);%0A  return fn.apply(undefined, args);%0A%7D%0A%0A
 exports.eval
@@ -672,72 +672,52 @@
     
-args.unshift(stack_frame);%0A    return func.apply(undefined, args
+return exports.apply(func, args, stack_frame
 );%0A 

Refactor out applying function. Throw if invalid.