mathexpr.hh revision 11545
12SN/A/*
21762SN/A * Copyright (c) 2016 ARM Limited
37534Ssteve.reinhardt@amd.com * All rights reserved
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Redistribution and use in source and binary forms, with or without
152SN/A * modification, are permitted provided that the following conditions are
162SN/A * met: redistributions of source code must retain the above copyright
172SN/A * notice, this list of conditions and the following disclaimer;
182SN/A * redistributions in binary form must reproduce the above copyright
192SN/A * notice, this list of conditions and the following disclaimer in the
202SN/A * documentation and/or other materials provided with the distribution;
212SN/A * neither the name of the copyright holders nor the names of its
222SN/A * contributors may be used to endorse or promote products derived from
232SN/A * this software without specific prior written permission.
242SN/A *
252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292665Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302665Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362SN/A *
372SN/A * Authors: David Guillen Fandos
382SN/A */
392SN/A
405491Sgblack@eecs.umich.edu#ifndef __SIM_MATHEXPR_HH__
415491Sgblack@eecs.umich.edu#define __SIM_MATHEXPR_HH__
422SN/A
435491Sgblack@eecs.umich.edu#include <algorithm>
442SN/A#include <array>
452SN/A#include <functional>
468737Skoansin.tan@gmail.com#include <string>
474762Snate@binkert.org
489342SAndreas.Sandberg@arm.comclass MathExpr {
499356Snilay@cs.wisc.edu  public:
5056SN/A
512SN/A    MathExpr(std::string expr);
522797Sktlim@umich.edu
532797Sktlim@umich.edu    typedef std::function<double(std::string)> EvalCallback;
5410023Smatt.horsnell@ARM.com
559196SAndreas.Sandberg@arm.com    /**
562SN/A     * Prints an ASCII representation of the expression tree
572SN/A     *
582SN/A     * @return A string containing the ASCII representation of the expression
599196SAndreas.Sandberg@arm.com     */
609196SAndreas.Sandberg@arm.com    std::string toStr() const { return toStr(root, ""); }
619196SAndreas.Sandberg@arm.com
629196SAndreas.Sandberg@arm.com    /**
639196SAndreas.Sandberg@arm.com     * Evaluates the expression
649196SAndreas.Sandberg@arm.com     *
659196SAndreas.Sandberg@arm.com     * @param fn A callback funcion to evaluate variables
669196SAndreas.Sandberg@arm.com     *
679196SAndreas.Sandberg@arm.com     * @return The value for this expression
689196SAndreas.Sandberg@arm.com     */
699196SAndreas.Sandberg@arm.com    double eval(EvalCallback fn) const { return eval(root, fn); }
709196SAndreas.Sandberg@arm.com
719196SAndreas.Sandberg@arm.com  private:
729196SAndreas.Sandberg@arm.com    enum Operator {
739196SAndreas.Sandberg@arm.com        bAdd, bSub, bMul, bDiv, bPow, uNeg, sValue, sVariable, nInvalid
749196SAndreas.Sandberg@arm.com    };
759196SAndreas.Sandberg@arm.com
769342SAndreas.Sandberg@arm.com    // Match operators
779196SAndreas.Sandberg@arm.com    const int MAX_PRIO = 4;
789196SAndreas.Sandberg@arm.com    typedef double (*binOp)(double, double);
799196SAndreas.Sandberg@arm.com    struct OpSearch {
809196SAndreas.Sandberg@arm.com        bool binary;
819196SAndreas.Sandberg@arm.com        Operator op;
829196SAndreas.Sandberg@arm.com        int priority;
839196SAndreas.Sandberg@arm.com        char c;
842SN/A        binOp fn;
859342SAndreas.Sandberg@arm.com    };
862SN/A
872SN/A    /** Operator list */
882SN/A    std::array<OpSearch, uNeg + 1> ops;
892SN/A
909196SAndreas.Sandberg@arm.com    class Node {
912SN/A      public:
922SN/A        Node() : op(nInvalid), l(0), r(0), value(0) {}
9310023Smatt.horsnell@ARM.com        std::string toStr() const {
9410023Smatt.horsnell@ARM.com            const char opStr[] = {'+', '-', '*', '/', '^', '-'};
9510023Smatt.horsnell@ARM.com            switch (op) {
964762Snate@binkert.org              case nInvalid:
979196SAndreas.Sandberg@arm.com                return "INVALID";
984762Snate@binkert.org              case sVariable:
994762Snate@binkert.org                return variable;
1002SN/A              case sValue:
1014762Snate@binkert.org                return std::to_string(value);
1024762Snate@binkert.org              default:
1034762Snate@binkert.org                return std::string(1, opStr[op]);
10410422Sandreas.hansson@arm.com            };
1052SN/A        }
1065034Smilesck@eecs.umich.edu
1075034Smilesck@eecs.umich.edu        Operator op;
1081553SN/A        Node *l, *r;
109265SN/A        double value;
1107532Ssteve.reinhardt@amd.com        std::string variable;
1117532Ssteve.reinhardt@amd.com    };
1127532Ssteve.reinhardt@amd.com
1137532Ssteve.reinhardt@amd.com    /** Root node */
1147532Ssteve.reinhardt@amd.com    Node * root;
1157532Ssteve.reinhardt@amd.com
116465SN/A    /** Parse and create nodes from string */
117465SN/A    Node *parse(std::string expr);
1187532Ssteve.reinhardt@amd.com
1197532Ssteve.reinhardt@amd.com    /** Print tree as string */
1207532Ssteve.reinhardt@amd.com    std::string toStr(Node *n, std::string prefix) const;
1217532Ssteve.reinhardt@amd.com
1227532Ssteve.reinhardt@amd.com    /** Eval a node */
1237532Ssteve.reinhardt@amd.com    double eval(const Node *n, EvalCallback fn) const;
1247532Ssteve.reinhardt@amd.com};
1257532Ssteve.reinhardt@amd.com
1269196SAndreas.Sandberg@arm.com#endif
1279196SAndreas.Sandberg@arm.com
1287532Ssteve.reinhardt@amd.com
1297532Ssteve.reinhardt@amd.com