void ObjectImpl::encodeProperties(qpid::framing::Buffer& buffer) const { int propCount = objectClass->getPropertyCount(); uint8_t bit = 0; uint8_t mask = 0; ValuePtr value; for (int idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); if (prop->isOptional()) { value = properties[prop->getName()]; if (bit == 0) bit = 1; if (!value->isNull()) mask |= bit; if (bit == 0x80) { buffer.putOctet(mask); bit = 0; mask = 0; } else bit = bit << 1; } } if (bit != 0) { buffer.putOctet(mask); } for (int idx = 0; idx < propCount; idx++) { const SchemaProperty* prop = objectClass->getProperty(idx); value = properties[prop->getName()]; if (!prop->isOptional() || !value->isNull()) { value->impl->encode(buffer); } } }
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 apply(EnvPtr env, ValuePtr procedure, ValuePtr args) { if(procedure->type() == Value::NATIVE_PROCEDURE) { NativeProcedureValue* proc = static_cast<NativeProcedureValue*>(procedure.mValue); return (*proc->mProc)(env, args); } else if(procedure->type() == Value::PROCEDURE) { EnvPtr callEnvironment = new Environment; ProcedureValue* proc = static_cast<ProcedureValue*>(procedure.mValue); callEnvironment->parent = proc->environment; int iParam = 0; while(args->isNull() == false) { if(iParam == static_cast<int>(proc->paramList.size())) { CHECK_FAIL("Too many arguments to procedure"); } callEnvironment->values[proc->paramList[iParam]] = args->car(); iParam++; args = args->cdr(); } if(iParam != static_cast<int>(proc->paramList.size())) { CHECK_FAIL("Too few arguments to procedure"); } return evalSequence(callEnvironment, proc->body); } else { sWrite(env, new PairValue(procedure, new PairValue())); CHECK_FAIL("Wrong type of argument to apply: not procedure"); return NULL; } }
bool sPureInteger(ValuePtr args) { while(args->isNull() == false) { if(!(args->car()->isNumber() && args->car()->isExact())) return false; args = args->cdr(); } return true; }
ValuePtr evalStatement(EnvPtr env, ValuePtr data) { ValuePtr current = data; ValuePtr call = new PairValue(); ValuePtr callCurrent = call; while(current->isPair() && !current->isNull()) { callCurrent->car() = eval(env, current->car()); ValuePtr newParam = new PairValue(); callCurrent->cdr() = newParam; callCurrent = newParam; current = current->cdr(); } if(current->isNull() == false) { CHECK_FAIL("Malformed statement"); return NULL; } return apply(env, call); }
int main(int argc, char *argv[]) { try { Reader reader(cin); ValuePtr data = reader.parse(); if (!data.isNull()) cout << *data; return 0; } CBANG_CATCH_ERROR; return 0; }
ValuePtr sAdd(EnvPtr env, ValuePtr args) { ValuePtr result = new NumberValue(0); while(args->isNull() == false) { if(args->car()->isNumber() && args->car()->isExact()) result->vInt() += args->car()->vInt(); args = args->cdr(); } return result; }
ValuePtr sStringAppend(EnvPtr env, ValuePtr args) { ostringstream ossStream; while(args->isNull() == false) { if(args->car()->isString()) ossStream << args->car()->vString(); args = args->cdr(); } return new StringValue(ossStream.str()); }
ValuePtr evalOr(EnvPtr env, ValuePtr statement) { ValuePtr args = statement->cdr(); while(args->isNull() == false) { ValuePtr test = eval(env, args->car()); if(!sEqP(test, rsFalse())) return rsTrue(); args = args->cdr(); } return rsFalse(); }
int sLength(ValuePtr data) { int length = 0; ValuePtr ptr = data; while(ptr->isNull() == false) { if(ptr->isPair() == false) CHECK_FAIL("Malformed list to length"); length++; ptr = ptr->cdr(); } return length; }
ValuePtr sReverse(EnvPtr, ValuePtr args) { CHECK("Single argument to reverse", sLength(args) == 1 && sListP(args->car())); ValuePtr current = new PairValue(); ValuePtr rList = args->car(); while(rList->isNull() == false) { ValuePtr next = new PairValue(rList->car(), current); current = next; rList = rList->cdr(); } return current; }
ValuePtr sList(EnvPtr env, ValuePtr args) { ValuePtr result = new PairValue(); ValuePtr current = result; while(args->isNull() == false) { current->car() = args->car(); ValuePtr next = new PairValue(); current->cdr() = next; current = next; args = args->cdr(); } return result; }
ValuePtr evalLambda(EnvPtr env, ValuePtr paramList, ValuePtr body) { ProcedureValue* proc = new ProcedureValue(); proc->environment = env; proc->body = body; while(paramList->isNull() == false) { if(!paramList->car()->isSymbol()) CHECK_FAIL("Non symbol in parameter list"); proc->paramList.push_back(paramList->car()->vString()); paramList = paramList->cdr(); } return proc; }
ValuePtr evalSequence(EnvPtr env, ValuePtr sequence) { if(!sListP(sequence)) { CHECK_FAIL("evalSequence argument not list"); } ValuePtr result = NULL; while(sequence->isNull() == false) { result = eval(env, sequence->car()); sequence = sequence->cdr(); } if(result == NULL) { CHECK_FAIL("Trying to evaluate undefined sequence"); } return result; }
ValuePtr sAssq(EnvPtr, ValuePtr args) { if(sLength(args) != 2) CHECK_FAIL("Wrong number of arguments to assq"); ValuePtr obj = args->car(); ValuePtr alist = args->cdr()->car(); while(alist->isNull() == false) { if(alist->isPair() == false && alist->car()->isPair() == false) CHECK_FAIL("Malformed alist"); if(sEqP(obj, alist->car()->car())) { return alist->car(); } alist = alist->cdr(); } return rsFalse(); }
ValuePtr evalLet(EnvPtr env, ValuePtr statement) { EnvPtr letEnv = new Environment(); letEnv->parent = env; ValuePtr bindings = statement->cdr()->car(); CHECK("One or more expressions", sLength(statement) >= 3); CHECK("Let bindings are a list", sListP(bindings)); while(bindings->isNull() == false) { CHECK("Let assignment is a list", sListP(bindings->car())); CHECK("Let assignment is a 2 item list", sLength(bindings->car()) == 2); ValuePtr variable = bindings->car()->car(); CHECK("Assigning to a symbol", variable->isSymbol()); ValuePtr value = eval(env, bindings->car()->cdr()->car()); letEnv->values[variable->vString()] = value; bindings = bindings->cdr(); } return evalSequence(letEnv, statement->cdr()->cdr()); }
void Serializable::read(istream &stream) { Reader reader(stream); ValuePtr value = reader.parse(); if (value.isNull()) PARSE_ERROR("Failed to parse JSON from stream"); read(*value); }