Exposed car, cdr, cadr, etc. in lisp

This commit is contained in:
Sami Samhuri 2009-12-20 20:28:21 -08:00
parent 2919672af3
commit 345aea8a09
2 changed files with 58 additions and 35 deletions

View file

@ -83,43 +83,22 @@ LispCons.prototype.unlist = function() {
LispCons.prototype.nth = function(n) { LispCons.prototype.nth = function(n) {
var i = 0, var i = 0,
e, cons = this,
cons = this; e = cons.car();
// print('[LispCons.nth] calling cons.isNil - cons: ' + cons + ' - _cdr: ' + cons._cdr);
while (i <= n && !cons.isNil()) { while (i <= n && !cons.isNil()) {
e = cons.car(); e = cons.car();
cons = cons.cdr(); cons = cons.cdr();
++i; ++i;
} }
return n > (i-1) ? type.NIL : e; return e;
}; };
LispCons.prototype.nthcdr = function(n) { LispCons.prototype.nthcdr = function(n) {
var e = this.cdr(), var e = this,
i = 0; i = 1;
// print('[LispCons.nthcdr] calling e.isNil - e: ' + e + ' - _cdr: ' + e._cdr); while (i <= n && !e.isNil()) {
while (i < n && !e.isNil()) {
e = e.cdr(); e = e.cdr();
++i; ++i;
} }
return n > i ? type.NIL : e; return e;
}; };
// Make NIL act like a list ... there's got to be a better way
NIL.unlist = function(){return [];};
NIL._length = 0;
NIL.length = function(){return 0;};
NIL.reduce = function(accum){return accum;};
nilMethods = ['car', 'cdr', 'cadr', 'caddr', 'cadddr',
'last', 'map', 'nthcdr', 'nth'];
var nilFn = function(){return NIL;};
for (var method in nilMethods) {
NIL[method] = nilFn;
}

View file

@ -46,18 +46,62 @@ var notFunc = function(fn) {
}; };
exports.notFunc = notFunc; exports.notFunc = notFunc;
var makePrimitiveBooleanFunc = function(fn) { var makeBooleanFunc = function(fn) {
return function(x){ return x[fn]() ? type.T : type.NIL; }; return function(x){ return x[fn]() ? type.T : type.NIL; };
}; };
exports.makePrimitiveBooleanFunc = makePrimitiveBooleanFunc; exports.makeBooleanFunc = makeBooleanFunc;
// TODO FIXME make NIL act like the empty list
var makeNilFn = function(fn) {
return function(arg){ return arg.isNil() ? arg : arg[fn](); };
};
var makeZeroFn = function(fn) {
return function(arg){ return arg.isNil() ? new type.LispNumber(0) : arg[fn](); };
};
init.hook('Define Primitive Variables and Functions', function() { init.hook('Define Primitive Variables and Functions', function() {
var type = require('elisp/types');
definePrimitive('consp', ['symbol'], makePrimitiveBooleanFunc('isCons'),
"Return T if symbol is a cons, nil otherwise.");
definePrimitive('atom', ['symbol'], makePrimitiveBooleanFunc('isAtom'), definePrimitive('consp', ['symbol'], makeBooleanFunc('isCons'),
"Return T if symbol is not a cons or is nil, nil otherwise."); "Return t if symbol is a cons, nil otherwise.");
definePrimitive('atom', ['symbol'], makeBooleanFunc('isAtom'),
"Return t if symbol is not a cons or is nil, nil otherwise.");
// list functions
definePrimitive('car', ['arg'], makeNilFn('car'),
"Return the car of list. If arg is nil, return nil. \
Error if arg is not nil and not a cons cell.");
definePrimitive('cdr', ['arg'], makeNilFn('cdr'),
"Return the cdr of list. If arg is nil, return nil. \
Error if arg is not nil and not a cons cell.");
definePrimitive('nth', ['n', 'arg'], function(n, arg){
return arg.isNil() ? arg : arg.nth(n.value());
}, "Return the nth element of list. \
n counts from zero. If list is not that long, nil is returned.");
definePrimitive('nthcdr', ['n', 'arg'], function(n, arg){
return arg.isNil() ? arg : arg.nthcdr(n.value());
}, "Take cdr n times on list, returns the result.");
definePrimitive('cadr', ['arg'], makeNilFn('cadr'),
"Return the car of the cdr of x.");
definePrimitive('caddr', ['arg'], makeNilFn('caddr'),
"Return the car of the cdr of the cdr of x.");
definePrimitive('cadddr', ['arg'], makeNilFn('cadddr'),
"Return the car of the cdr of the cdr of the cdr of x.");
//////////
///// FIXME new symbol table! this makes the current one barf, because it sucks
/////
// definePrimitive('length', ['arg'], makeZeroFn('length'),
// "Return the length of list.");
definePrimitive('symbol-name', ['symbol'], definePrimitive('symbol-name', ['symbol'],
function(symbol) { return new type.LispString(symbol.symbolName()); }, function(symbol) { return new type.LispString(symbol.symbolName()); },