寂しすぎる

ねがいよーかーぜーにのってー

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;
        }
    }
}