mathexpr.hh revision 11531
110448Snilay@cs.wisc.edu/* 210448Snilay@cs.wisc.edu * Copyright (c) 2016 ARM Limited 310448Snilay@cs.wisc.edu * All rights reserved 410448Snilay@cs.wisc.edu * 510448Snilay@cs.wisc.edu * The license below extends only to copyright in the software and shall 610448Snilay@cs.wisc.edu * not be construed as granting a license to any other intellectual 710448Snilay@cs.wisc.edu * property including but not limited to intellectual property relating 810448Snilay@cs.wisc.edu * to a hardware implementation of the functionality of the software 910448Snilay@cs.wisc.edu * licensed hereunder. You may use the software subject to the license 1010448Snilay@cs.wisc.edu * terms below provided that you ensure that this notice is replicated 1110448Snilay@cs.wisc.edu * unmodified and in its entirety in all distributions of the software, 1210448Snilay@cs.wisc.edu * modified or unmodified, in source code or in binary form. 1310448Snilay@cs.wisc.edu * 1410448Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without 1510448Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are 1610448Snilay@cs.wisc.edu * met: redistributions of source code must retain the above copyright 1710448Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer; 1810448Snilay@cs.wisc.edu * redistributions in binary form must reproduce the above copyright 1910448Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the 2010448Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution; 2110448Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its 2210447Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 2310447Snilay@cs.wisc.edu * this software without specific prior written permission. 2410447Snilay@cs.wisc.edu * 2510447Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610447Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710447Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810447Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910447Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010447Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110447Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210447Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310447Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410447Snilay@cs.wisc.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510447Snilay@cs.wisc.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610447Snilay@cs.wisc.edu * 3710447Snilay@cs.wisc.edu * Authors: David Guillen Fandos 3810447Snilay@cs.wisc.edu */ 3910447Snilay@cs.wisc.edu 4010447Snilay@cs.wisc.edu#ifndef __SIM_MATHEXPR_HH__ 4110447Snilay@cs.wisc.edu#define __SIM_MATHEXPR_HH__ 4210447Snilay@cs.wisc.edu 4310447Snilay@cs.wisc.edu#include <algorithm> 4410447Snilay@cs.wisc.edu#include <functional> 4510447Snilay@cs.wisc.edu#include <string> 4610447Snilay@cs.wisc.edu 4710447Snilay@cs.wisc.educlass MathExpr { 4810447Snilay@cs.wisc.edu public: 4910447Snilay@cs.wisc.edu 5010447Snilay@cs.wisc.edu MathExpr(std::string expr); 5110447Snilay@cs.wisc.edu 5210447Snilay@cs.wisc.edu typedef std::function<double(std::string)> EvalCallback; 5310447Snilay@cs.wisc.edu 5410447Snilay@cs.wisc.edu /** 5510447Snilay@cs.wisc.edu * Prints an ASCII representation of the expression tree 5610447Snilay@cs.wisc.edu * 5710447Snilay@cs.wisc.edu * @return A string containing the ASCII representation of the expression 5810447Snilay@cs.wisc.edu */ 5910447Snilay@cs.wisc.edu std::string toStr() const { return toStr(root, ""); } 6010447Snilay@cs.wisc.edu 6110447Snilay@cs.wisc.edu /** 6210447Snilay@cs.wisc.edu * Evaluates the expression 6310447Snilay@cs.wisc.edu * 6410447Snilay@cs.wisc.edu * @param fn A callback funcion to evaluate variables 6510447Snilay@cs.wisc.edu * 6610447Snilay@cs.wisc.edu * @return The value for this expression 6710447Snilay@cs.wisc.edu */ 6810447Snilay@cs.wisc.edu double eval(EvalCallback fn) const { return eval(root, fn); } 6910447Snilay@cs.wisc.edu 7010447Snilay@cs.wisc.edu private: 7110447Snilay@cs.wisc.edu enum Operator { 7210447Snilay@cs.wisc.edu bAdd, bSub, bMul, bDiv, bPow, uNeg, sValue, sVariable, nInvalid 7310447Snilay@cs.wisc.edu }; 7410447Snilay@cs.wisc.edu 7510447Snilay@cs.wisc.edu // Match operators 7610447Snilay@cs.wisc.edu const int MAX_PRIO = 4; 7710447Snilay@cs.wisc.edu typedef double (*binOp)(double, double); 7810447Snilay@cs.wisc.edu struct OpSearch { 7910447Snilay@cs.wisc.edu bool binary; 8010447Snilay@cs.wisc.edu Operator op; 8110447Snilay@cs.wisc.edu int priority; 8210447Snilay@cs.wisc.edu char c; 8310447Snilay@cs.wisc.edu binOp fn; 8410447Snilay@cs.wisc.edu }; 8510447Snilay@cs.wisc.edu 8610447Snilay@cs.wisc.edu /** Operator list */ 8710447Snilay@cs.wisc.edu std::array<OpSearch, uNeg + 1> ops; 8810447Snilay@cs.wisc.edu 8910447Snilay@cs.wisc.edu class Node { 9010447Snilay@cs.wisc.edu public: 9110447Snilay@cs.wisc.edu Node() : op(nInvalid), l(0), r(0), value(0) {} 9210447Snilay@cs.wisc.edu std::string toStr() const { 9310447Snilay@cs.wisc.edu const char opStr[] = {'+', '-', '*', '/', '^', '-'}; 9410447Snilay@cs.wisc.edu switch (op) { 9510447Snilay@cs.wisc.edu case nInvalid: 9610447Snilay@cs.wisc.edu return "INVALID"; 9710447Snilay@cs.wisc.edu case sVariable: 9810447Snilay@cs.wisc.edu return variable; 9910447Snilay@cs.wisc.edu case sValue: 10010447Snilay@cs.wisc.edu return std::to_string(value); 10110447Snilay@cs.wisc.edu default: 10210447Snilay@cs.wisc.edu return std::string(1, opStr[op]); 10310447Snilay@cs.wisc.edu }; 10410447Snilay@cs.wisc.edu } 10510447Snilay@cs.wisc.edu 10610447Snilay@cs.wisc.edu Operator op; 10710447Snilay@cs.wisc.edu Node *l, *r; 10810447Snilay@cs.wisc.edu double value; 10910447Snilay@cs.wisc.edu std::string variable; 11010447Snilay@cs.wisc.edu }; 11110447Snilay@cs.wisc.edu 11210447Snilay@cs.wisc.edu /** Root node */ 11310447Snilay@cs.wisc.edu Node * root; 11410447Snilay@cs.wisc.edu 11510447Snilay@cs.wisc.edu /** Parse and create nodes from string */ 11610447Snilay@cs.wisc.edu Node *parse(std::string expr); 11710447Snilay@cs.wisc.edu 11810447Snilay@cs.wisc.edu /** Print tree as string */ 11910447Snilay@cs.wisc.edu std::string toStr(Node *n, std::string prefix) const; 12010447Snilay@cs.wisc.edu 12110447Snilay@cs.wisc.edu /** Eval a node */ 12210447Snilay@cs.wisc.edu double eval(const Node *n, EvalCallback fn) const; 12310447Snilay@cs.wisc.edu}; 12410447Snilay@cs.wisc.edu 12510447Snilay@cs.wisc.edu#endif 12610447Snilay@cs.wisc.edu 12710447Snilay@cs.wisc.edu 12810447Snilay@cs.wisc.edu