bool Expression::operationLogical(const ExprNodePtr& node) { bool left, right; try { left = boost::get<bool>(calcTree(node->left)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for logical operator", left); } if (node->operationType == OP_AND && !left) { return false;// Do not calculate right side } else if (node->operationType == OP_OR && left) { return true;// Do not calculate right side } try { right = boost::get<bool>(calcTree(node->right)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for logical operator", right); } switch (node->operationType) { case OP_AND: return left && right; case OP_OR: return left || right; default:; // just for Resharper to be happy } assert(false); return false; }
bool Expression::operationCompare(const ExprNodePtr& node) { ExprInteger left, right; try { left = boost::get<ExprInteger>(calcTree(node->left)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for comparison operator", left); } try { right = boost::get<ExprInteger>(calcTree(node->right)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for comparison operator", right); } switch (node->operationType) { case OP_LESS: return left < right; case OP_LESSOREQUAL: return left <= right; case OP_GREATER: return left > right; case OP_GREATEROREQUAL: return left >= right; default:; // just for Resharper to be happy } assert(false); return false; }
int calcTree(TreeNode *root, int &ans) { int F = 0; if (root == NULL) return F; int left, right; left = calcTree(root->left, ans); right = calcTree(root->right, ans); ans = max(ans, left + right + root->val); ans = max(ans, left + root->val); ans = max(ans, right + root->val); F = max(0, max(left, right)) + root->val; return F; }
bool Expression::operationIsNot(const ExprNodePtr& node) { FileAttributeSet left; FileAttribute right; try { left = boost::get<FileAttributeSet>(calcTree(node->left)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid left argument for operator 'not'", left); } try { right = boost::get<FileAttribute>(calcTree(node->right)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid right argument for operator 'not'", right); } return left.find(right) == left.end(); }
int maxPathSum(TreeNode *root) { // Start typing your C/C++ solution below // DO NOT write int main() function int ans = 0; if (root) { ans = root->val; calcTree(root, ans); } return ans; }
bool Expression::operationContains(const ExprNodePtr& node) { std::string left, right; try { left = boost::get<std::string>(calcTree(node->left)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for operation 'contains'", left); } try { right = boost::get<std::string>(calcTree(node->right)); } catch (boost::bad_get&) { throw InvalidFunctionArgument("Invalid argument for operation 'contains'", right); } namespace bl = boost::locale; bl::comparator<char, bl::collator_base::secondary> cmpr; std::wstring leftW = Utils::Utf8ToWideString(left); std::wstring rightW = Utils::Utf8ToWideString(right); auto range = boost::algorithm::ifind_first(left, right); // case insensitive search return Utils::FindSubstrCaseInsensitive(leftW, rightW) != -1; }
line *executeLine(line *toexec, var *varlist){ char tmpbuffer[100]; evaltree *root = NULL; char * startpos = NULL; int counter = 0; root = genNewNode(); if (!toexec){ return NULL; } startpos = toexec->instruction; if (strncmp(toexec->instruction, "SET", 3)==0){ startpos = readVarName(toexec->instruction+4, tmpbuffer); //skip equals when parsing startpos++; //tmpbuffer[strlen(tmpbuffer)-1]= '\0'; buildTree(startpos, root, 0); calcTree(root, varlist); setVar(varlist, tmpbuffer, root->result); } if (strncmp(toexec->instruction, "PRINT", 5)==0){ startpos+=6; buildTree(startpos, root, 0); calcTree(root, varlist); printf("%d\n", root->result.value.i); } if (strncmp(toexec->instruction, "GOTO", 4)==0){ startpos+=5; buildTree(startpos, root, 0); calcTree(root, varlist); if (root->result.value.i == toexec->lineno){ printf ("Pointless infinite loop at line %d\n", toexec->lineno); return NULL; } if (root->result.value.i < toexec->lineno){ while (toexec->prev){ toexec = toexec->prev; if (toexec->lineno == root->result.value.i) return toexec; } return NULL; } if (root->result.value.i > toexec->lineno){ while (toexec->next){ toexec = toexec->next; if (toexec->lineno == root->result.value.i) return toexec; } return NULL; } return NULL; } if (strncmp(toexec->instruction, "IF", 2)==0){ startpos+=3; buildTree(startpos, root, 0); calcTree(root, varlist); if (root->result.value.i != 0){ return toexec->next; } while(toexec->next){ toexec=toexec->next; //keep track of nested if then else if (strncmp(toexec->instruction, "IF",2)==0) counter++; if ((strncmp(toexec->instruction, "ELSE", 4)==0)&&counter==0) return toexec->next; if (strncmp(toexec->instruction, "END IF", 6)==0) counter--; } return NULL; } if (strncmp(toexec->instruction, "ELSE", 4)==0){ while (toexec->next){ toexec=toexec->next; if (strncmp(toexec->instruction, "IF",2)==0) counter++; if ((strncmp(toexec->instruction,"END IF", 6)==0)&&counter==0) return toexec->next; if (strncmp(toexec->instruction, "END IF", 6)==0) counter--; } return NULL; } if (strncmp(toexec->instruction, "WHILE", 5)==0){ // printf("In While at line %d", toexec->lineno); startpos+=6; buildTree(startpos, root,0); calcTree(root,varlist); if (root->result.value.i !=0) return toexec->next; while(toexec->next){ toexec = toexec->next; if (strncmp(toexec->instruction, "WHILE", 5)==0) counter++; if (strncmp(toexec->instruction, "WEND", 4)==0&&counter==0) return toexec->next; if (strncmp(toexec->instruction, "WEND", 4)==0) counter--; } return NULL; } if (strncmp(toexec->instruction, "WEND", 4)==0){ while (toexec->prev){ toexec=toexec->prev; if (strncmp(toexec->instruction, "WEND", 4)==0) counter++; if (strncmp(toexec->instruction, "WHILE", 5)==0&&counter==0) return toexec; if (strncmp(toexec->instruction, "WHILE", 5)==0) counter--; } return NULL; } freeTree(root); return toexec->next; }
ExprValue Expression::calcTree(const ExprNodePtr& tree) { switch (tree->operationType) { case OP_VARIABLE: return getPropertyValue(boost::get<std::string>(tree->value)); case OP_VALUE: return tree->value; case OP_PLUS: try { return boost::get<ExprInteger>(calcTree(tree->left)) + boost::get<ExprInteger>(calcTree(tree->right)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for operator '+'"); } case OP_MINUS: try { return boost::get<ExprInteger>(calcTree(tree->left)) - boost::get<ExprInteger>(calcTree(tree->right)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for operator '-'"); } case OP_MULTIPLY: try { return boost::get<ExprInteger>(calcTree(tree->left)) * boost::get<ExprInteger>(calcTree(tree->right)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for operator '*'"); } case OP_DIVIDE: try { return boost::get<ExprInteger>(calcTree(tree->left)) * boost::get<ExprInteger>(calcTree(tree->right)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for operator '*'"); } case OP_CONTAINS: return operationContains(tree); case OP_LESS: case OP_LESSOREQUAL: case OP_GREATER: case OP_GREATEROREQUAL: return operationCompare(tree); case OP_EQUAL: return operationEquals(tree); case OP_NOTEQUAL: return operationNotEquals(tree); case OP_UMINUS: try { return -boost::get<ExprInteger>(calcTree(tree->left)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for unary minus operator"); } case OP_NOT: return operationIsNot(tree); /*try { return !boost::get<bool>(calcTree(tree->left)); } catch (boost::bad_get&) { throw EvaluateException("Invalid argument for 'not' operator"); }*/ case OP_OR: case OP_AND: return operationLogical(tree); case OP_IS: return operationIs(tree); case OP_FUNCTIONCALL: { ExprValue left = calcTree(tree->left); return runtimeInfo_->callFunction(tree, left); } default: throw ParserException(str(boost::format("Unknown operation %d") % static_cast<int>(tree->operationType)), 0); } }
ExprValue Expression::evaluate(PropertyMap&& properties) { properties_ = std::move(properties); result_ = calcTree(root_); return result_; }
bool Expression::operationNotEquals(const ExprNodePtr& node) { auto left = calcTree(node->left); auto right = calcTree(node->right); return boost::apply_visitor(NotEqualsVisitor(), left, right); }