mirror of
https://github.com/samsonjs/elisp.js.git
synced 2026-03-25 09:15:49 +00:00
Exposed car, cdr, cadr, etc. in lisp
This commit is contained in:
parent
2919672af3
commit
345aea8a09
2 changed files with 58 additions and 35 deletions
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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()); },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue