/*
 * Copyright (c) 2016 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: David Guillen Fandos
 */

#ifndef __SIM_MATHEXPR_HH__
#define __SIM_MATHEXPR_HH__

#include <algorithm>
#include <array>
#include <functional>
#include <string>

class MathExpr {
  public:

    MathExpr(std::string expr);

    typedef std::function<double(std::string)> EvalCallback;

    /**
     * Prints an ASCII representation of the expression tree
     *
     * @return A string containing the ASCII representation of the expression
     */
    std::string toStr() const { return toStr(root, ""); }

    /**
     * Evaluates the expression
     *
     * @param fn A callback funcion to evaluate variables
     *
     * @return The value for this expression
     */
    double eval(EvalCallback fn) const { return eval(root, fn); }

  private:
    enum Operator {
        bAdd, bSub, bMul, bDiv, bPow, uNeg, sValue, sVariable, nInvalid
    };

    // Match operators
    const int MAX_PRIO = 4;
    typedef double (*binOp)(double, double);
    struct OpSearch {
        bool binary;
        Operator op;
        int priority;
        char c;
        binOp fn;
    };

    /** Operator list */
    std::array<OpSearch, uNeg + 1> ops;

    class Node {
      public:
        Node() : op(nInvalid), l(0), r(0), value(0) {}
        std::string toStr() const {
            const char opStr[] = {'+', '-', '*', '/', '^', '-'};
            switch (op) {
              case nInvalid:
                return "INVALID";
              case sVariable:
                return variable;
              case sValue:
                return std::to_string(value);
              default:
                return std::string(1, opStr[op]);
            };
        }

        Operator op;
        Node *l, *r;
        double value;
        std::string variable;
    };

    /** Root node */
    Node * root;

    /** Parse and create nodes from string */
    Node *parse(std::string expr);

    /** Print tree as string */
    std::string toStr(Node *n, std::string prefix) const;

    /** Eval a node */
    double eval(const Node *n, EvalCallback fn) const;
};

#endif


