QoreValue AbstractQoreNode::evalValue(ExceptionSink* xsink) const { if (!needs_eval_flag) return refSelf(); if (has_value_api) { const ParseNode* pn = reinterpret_cast<const ParseNode*>(this); ValueEvalRefHolder v(pn, xsink); return v.takeReferencedValue(); } return evalImpl(xsink); }
DateTimeNode* DateTimeNode::subtractBy(const DateTime& dt) const { if (!dt.hasValue()) return refSelf(); DateTimeNode* rv; if (isRelative()) { rv = new DateTimeNode(dt); rv->priv->subtractBy(*priv); } else { rv = new DateTimeNode(*this); rv->priv->subtractBy(*dt.priv); } return rv; }
// AbstractQoreNode::eval(): return value requires a dereference AbstractQoreNode* AbstractQoreNode::eval(ExceptionSink* xsink) const { if (!needs_eval_flag) return refSelf(); return evalImpl(xsink); }
int ConstantEntry::parseInit(ClassNs ptr) { //printd(5, "ConstantEntry::parseInit() this: %p '%s' pub: %d init: %d in_init: %d node: %p '%s' class context: %p '%s' ns: %p ('%s') pub: %d\n", this, name.c_str(), pub, init, in_init, node, get_type_name(node), ptr.getClass(), ptr.getClass() ? ptr.getClass()->name.c_str() : "<none>", ptr.getNs(), ptr.getNs() ? ptr.getNs()->name.c_str() : "<none>", ptr.getNs() ? ptr.getNs()->pub : 0); if (init) return 0; if (in_init) { parse_error("recursive constant reference found to constant '%s'", name.c_str()); return 0; } ConstantEntryInitHelper ceih(*this); if (!node) return 0; int lvids = 0; { // set parse location in case of errors ParseLocationHelper plh(loc); // push parse class context qore_class_private* p = ptr.getClass(); QoreParseClassHelper qpch(p ? p->cls : 0); // ensure that there is no accessible local variable state VariableBlockHelper vbh; // set parse options and warning mask for this statement ParseWarnHelper pwh(pwo); //printd(5, "ConstantEntry::parseInit() this: %p '%s' about to init node: %p '%s' class: %p '%s'\n", this, name.c_str(), node, get_type_name(node), p, p ? p->name.c_str() : "n/a"); if (typeInfo) typeInfo = 0; node = node->parseInit((LocalVar*)0, PF_CONST_EXPRESSION, lvids, typeInfo); } //printd(5, "ConstantEntry::parseInit() this: %p %s initialized to node: %p (%s) value: %d\n", this, name.c_str(), node, get_type_name(node), node->is_value()); if (node->is_value()) return 0; // do not evaluate expression if any parse exceptions have been thrown QoreProgram* pgm = getProgram(); if (pgm->parseExceptionRaised()) { discard(node, 0); node = 0; typeInfo = nothingTypeInfo; return -1; } // evaluate expression ExceptionSink xsink; { ReferenceHolder<AbstractQoreNode> v(node->eval(&xsink), &xsink); //printd(5, "ConstantEntry::parseInit() this: %p %s evaluated to node: %p (%s)\n", this, name.c_str(), *v, get_type_name(*v)); if (!xsink) { node->deref(&xsink); node = v.release(); if (!node) { node = nothing(); typeInfo = nothingTypeInfo; } else { typeInfo = getTypeInfoForValue(node); check_constant_cycle(pgm, node); // address circular refs: pgm->const->pgm } } else { node->deref(&xsink); node = 0; typeInfo = nothingTypeInfo; } } if (xsink.isEvent()) qore_program_private::addParseException(pgm, xsink, &loc); // scan for call references if (scanValue(node)) { saved_node = node; node = new RuntimeConstantRefNode(refSelf()); } return 0; }