/* Scheme implementation in JavaScript
*/

function cons(e1, e2) {
return function(msg) {
if (msg == 0)
 return e1;
else
 return e2;
}
}

function car(aPair) {
return aPair(0);
}

function cdr(aPair) {
return aPair(1);
}

function list() {
var theList = cons(arguments[arguments.length - 1], null);
var c = 2; 
while (c <= arguments.length) {
theList = cons(arguments[arguments.length - c], theList);
++c;
}
return theList;
}

function length(lst) {
var c = 0;
while (lst != null) {
lst = cdr(lst);
++c;
}
return c;
}

function item(pos, lst) {
var c = pos;
while (c != 0) {
lst = cdr(lst);
--c;
}
return car(lst);
}

function append(lst1, lst2) {
var c = length(lst1) - 1;
while (c >= 0) {
lst2 = cons(item(c, lst1), lst2);
--c;
}
return lst2;
}

function map(func, lst) {
var c = length(lst) - 1;
theList = cons(func(item(c, lst)), null);
--c;
while (c >= 0) {
theList = cons(func(item(c, lst)), theList);
--c;
}
return theList;
}

function filter(pred, lst) {
var c = length(lst) - 1;
theList = null;
while (c >= 0) {
if (pred(item(c, lst)) != false)
theList = cons(item(c, lst), theList);
--c;
}
return theList;
}

function accumulate(func, initial, lst) {
if (lst == null)
return initial;
else
return func(car(lst), accumulate(func, initial, cdr(lst)));
}

function position(e, lst) {
if (e == car(lst))
return 0;
else
return 1 + position(e, cdr(lst));
}

function isAtom(x) {
return typeof x == "string" || typeof x == "number" || typeof x == "boolean";
}

function not(x) {
if (x == false)
return true;
else
return false;
}

function isPair(x) {
return not(isAtom(x));
}

function flatten(lst) {
if (lst == null)
return null;
else {
if (isPair(car(lst)))
return append(flatten(car(lst)), flatten(cdr(lst)));
else 
return cons(car(lst), flatten(cdr(lst)));
}
}

	
