ねがいよーかーぜーにのってー
var ScheJS = { }; with (ScheJS) { ScheJS.eval = function(string) { var context = { }; ScheJS.buffer = string; try { while (1) var value = evalExpression.call(context, read()); } catch (e) { return value; } } ScheJS.evalExpression = function(expr) { if (expr instanceof Array) { var evalee = expr[0]; if (evalee in specialForms) var args = expr.slice(1); else var args = expr.slice(1).map(evalExpression, this); return evalExpression.call(this, evalee).apply(this, args); } else { switch (true) { case typeof expr == 'function': return expr; case expr in this: return this[expr]; case expr in specialForms: return specialForms[expr]; case expr in functions: return functions[expr]; case !isNaN(Number(expr)): return Number(expr); } } } ScheJS.specialForms = { define: function(name, expr) { this[name] = evalExpression(expr); }, lambda: function(args) { var body = Array.slice(arguments, 1); return function() { var context = { }; for (var i = 0; i < args.length; i++) context[args[i]] = arguments[i]; context.__proto__ = this; return body.map(evalExpression, context)[body.length - 1]; } } } ScheJS.functions = { cons: function(car, cdr) { return { car: car, cdr: cdr } }, car: function(val) { if (val instanceof Array) return val[0]; else return val.car; }, cdr: function(val) { if (val instanceof Array) return val.slice(1); else return val.cdr; } } ScheJS.read = function(string) { if (string) ScheJS.buffer = string; return readExpression(); } ScheJS.readExpression = function() { eat(/^\s*/); switch (true) { case eat(/^\(\s*/): var expr = []; try { while (1) expr.push(readExpression()); } catch (e) { } return expr; case eat(/^([^()\s]+)\s*/): return RegExp.$1; case eat(/^\)\s*/): default: throw 'End of S-Expression'; } } function eat(regexp) { if (buffer.match(regexp)) { buffer = RegExp.rightContext; return true; } else { return false; } } }