bool sEqP(ValuePtr lhs, ValuePtr rhs) { if(lhs->type() != rhs->type()) return false; if(lhs->isBool() && lhs->vBool() == rhs->vBool()) return true; else if(lhs->isNumber() && lhs->isExact() && rhs->isExact() && lhs->vInt() == rhs->vInt()) return true; else if(lhs->isNumber() && !lhs->isExact() && !rhs->isExact() && lhs->vFloat() == rhs->vFloat()) return true; else if(lhs->isString() && string(lhs->vString()) == string(rhs->vString())) return true; else if(lhs->isSymbol() && string(lhs->vString()) == string(rhs->vString())) return true; else if(lhs->isPair() && (lhs == rhs || (lhs->isNull() && rhs->isNull()))) return true; else if(lhs->isProcedure() && (lhs.mValue == rhs.mValue)) return true; else if(lhs->type() == Value::UNDEFINED) return false; return false; }
ValuePtr sForEach(EnvPtr env, ValuePtr args) { CHECK("Only single parameter for-each supported", sLength(args) == 2); ValuePtr proc = args->car(); ValuePtr list1 = args->cdr()->car(); CHECK("Valid arguments to foreach", (proc->isProcedure()) && sListP(list1)); ValuePtr argList = new PairValue(NULL, new PairValue()); while(list1->isNull() == false) { argList->car() = list1->car(); apply(env, proc, argList); list1 = list1->cdr(); } return rsUndefined(); }
ValuePtr sMap(EnvPtr env, ValuePtr args) { CHECK("Only single parameter map supported", sLength(args) == 2); ValuePtr proc = args->car(); ValuePtr list1 = args->cdr()->car(); CHECK("Valid arguments to map", (proc->isProcedure()) && sListP(list1)); ValuePtr result = new PairValue(); ValuePtr current = result; ValuePtr argList = new PairValue(NULL, new PairValue()); while(list1->isNull() == false) { argList->car() = list1->car(); current->car() = apply(env, proc, argList); ValuePtr next = new PairValue(); current->cdr() = next; current = next; list1 = list1->cdr(); } return result; }