bool QoreValue::isEqualHard(const QoreValue n) const { qore_type_t t = getType(); if (t != n.getType()) return false; switch (t) { case NT_INT: return getAsBigInt() == n.getAsBigInt(); case NT_BOOLEAN: return getAsBool() == n.getAsBool(); case NT_FLOAT: return getAsFloat() == n.getAsFloat(); case NT_NOTHING: case NT_NULL: return true; } return !compareHard(v.n, n.v.n, 0); }
bool CaseNode::matches(AbstractQoreNode *lhs_value, ExceptionSink *xsink) { return !compareHard(lhs_value, val, xsink); // the ! is because of compareHard() semantics }
int SwitchStatement::parseInitImpl(LocalVar *oflag, int pflag) { int lvids = 0; // turn off top-level flag for statement vars pflag &= (~PF_TOP_LEVEL); const QoreTypeInfo *argTypeInfo = 0; if (sexp) sexp = sexp->parseInit(oflag, pflag, lvids, argTypeInfo); CaseNode *w = head; ExceptionSink xsink; QoreProgram *pgm = getProgram(); while (w) { if (w->val) { argTypeInfo = 0; w->val = w->val->parseInit(oflag, pflag | PF_CONST_EXPRESSION, lvids, argTypeInfo); if (lvids) { parse_error("illegal local variable declaration in assignment expression for case block"); while (lvids--) pop_local_var(); w = w->next; continue; } // evaluate case expression if necessary and no parse expressions have been raised if (w->val && !w->val->is_value()) { if (pgm->parseExceptionRaised()) { w = w->next; continue; } ReferenceHolder<AbstractQoreNode> v(w->val->eval(&xsink), &xsink); if (!xsink) { w->val->deref(&xsink); w->val = v.release(); if (!w->val) w->val = nothing(); } else qore_program_private::addParseException(pgm, xsink); } //printd(5, "SwitchStatement::parseInit() this=%p case exp: %p %s\n", this, w->val, get_type_name(w->val)); // check for duplicate values CaseNode *cw = head; while (cw != w) { // Check only the simple case blocks (case 1: ...), // not those with relational operators. Could be changed later to provide more checking. // note that no exception can be raised here as the case node values are parse values if (w->isCaseNode() && cw->isCaseNode() && !compareHard(w->val, cw->val, &xsink)) parse_error("duplicate case values in switch"); assert(!xsink); cw = cw->next; } } if (w->code) w->code->parseInitImpl(oflag, pflag); w = w->next; } // save local variables if (lvids) lvars = new LVList(lvids); return 0; }