lisp.js
Version:
A tiny lisp interpreter
83 lines (77 loc) • 2.62 kB
JavaScript
var _ = require('underscore');
var Env = function(params, args, outer) {
var dict = {};
var that = this;
var outer = outer;
_.forEach(params, function(ele, index) {
dict[ele] = args[index];
});
this.find = function(name) {
if (dict[name]) return that;
return outer.find(name);
};
this.update = function(new_dict) {
_.extend(dict, new_dict);
};
this.get = function(name) {
if (dict[name]) return dict[name];
};
this.set = function(name, val) {
dict[name] = val;
};
};
var add_globals = function(env) {
env.update({
"+": function() {
var args = Array.prototype.slice(arguments);
return _.reduce(args, function(x, y) {
return x+y;
});
},
"-": function() {
var args = Array.prototype.slice(arguments);
return _.reduce(args, function(x, y) {
return x-y;
});
},
"*": function() {
var args = Array.prototype.slice(arguments);
return _.reduce(args, function(x, y) {
return x*y;
});
},
"/": function() {
var args = Array.prototype.slice(arguments);
return _.reduce(args, function(x, y) {
return x/y;
});
},
"not": function(val) { return !val; },
">": function(x, y) { return x > y; },
"<": function(x, y) { return x < y; },
">=": function(x, y) { return x >= y; },
"<=": function(x, y) { return x <= y; },
"=": function(x, y) { return x === y; },
"equal?": function(x, y) { return x === y; },
"eq?": function(x, y) { return x == y; },
"length": function(x) { return x.length },
"cons": function(x, y) { return [x, y]; },
"car": function(x) { return x[0]; },
"cdr": function(x) { return x.prototype.slice(1); },
"append": function(x, y) { x.push(y); return x; },
"list": function() { return Array.prototype.slice(arguments); },
"list?": function(x) { return isa(x, "list"); },
"null?": function(x) { return _.isEmpty(x); },
"symbol?": function(x) { return isa(x, "Symbol"); }
});
return env;
};
var global_env = add_globals(new Env());
var env = new Env();
env.update({a: 3, b: 4});
console.log(env.find("a"));
console.log(env.find("a").get("a"));
var env2 = new Env(["c"], [5], env);
console.log(env2.find("a"));
console.log(env2.find("a").get("a"));
console.log(global_env.get("+")(3, 4));