1 /*
2 * Copyright Disney Enterprises, Inc.  All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License
6 * and the following modification to it: Section 6 Trademarks.
7 * deleted and replaced with:
8 *
9 * 6. Trademarks. This License does not grant permission to use the
10 * trade names, trademarks, service marks, or product names of the
11 * Licensor and its affiliates, except as required for reproducing
12 * the content of the NOTICE file.
13 *
14 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
16 */
17 
18 #include <SeExpr2/Expression.h>
19 #include <SeExpr2/ExprFunc.h>
20 #include <SeExpr2/Vec.h>
21 #include <cstdlib>
22 #include <cstdio>
23 #include <cstring>
24 
25 #define STACK_DEPTH 256
26 
27 using namespace SeExpr2;
28 
29 /**
30    @file asciiCalculator.cpp
31 */
32 //! Simple expression class to support our function calculator
33 class CalculatorExpr : public Expression {
34   public:
35     //! Constructor that takes the expression to parse
CalculatorExpr(const std::string & expr)36     CalculatorExpr(const std::string& expr) : Expression(expr), _count(0) {
37         for (int i = 0; i < STACK_DEPTH; i++) {
38             stack[i].val = Vec<double, 3, false>(0.0);
39             fail_stack[i] = false;
40         }
41     };
42 
43     //! Empty constructor
CalculatorExpr()44     CalculatorExpr() : Expression(), _count(0) {
45         for (int i = 0; i < STACK_DEPTH; i++) fail_stack[i] = false;
46     };
47 
48     //! Push current result on stack
push()49     void push() {
50         if (returnType().isString()) {
51             evalStr();
52         } else if (returnType().isFP()) {
53             const double* val = evalFP();
54             int dim = returnType().dim();
55             for (int k = 0; k < 3; k++) std::cerr << val[k] << " ";
56             std::cerr << std::endl;
57             if (dim == 1)
58                 stack[_count].val = Vec<double, 3, false>(val[0]);
59             else if (dim == 2)
60                 stack[_count].val = Vec<double, 3, false>(val[0], val[1], 0);
61             else if (dim == 3)
62                 stack[_count].val = Vec<double, 3, true>(const_cast<double*>(&val[0]));
63             else {
64                 std::cerr << "Return type FP(" << dim << ") ignoring" << std::endl;
65             }
66 
67             _count++;
68         }
69     };
70 
71     //! Failed attempt; push 0 on stack
fail_push()72     void fail_push() {
73         fail_stack[_count] = true;
74         stack[_count].val = Vec<double, 3, false>(0.0);
75         _count++;
76     };
77 
peek()78     Vec<double, 3, false> peek() { return stack[_count - 1].val; }
79 
count() const80     int count() const {
81         return _count;
82     };
83 
84   private:
85     //! Simple variable that just returns its internal value
86     struct SimpleVar : public ExprVarRef {
SimpleVarCalculatorExpr::SimpleVar87         SimpleVar() : ExprVarRef(ExprType().FP(3).Varying()), val(0.0) {}
88 
89         Vec<double, 3, false> val;  // independent variable
90 
evalCalculatorExpr::SimpleVar91         void eval(double* result) {
92             for (int k = 0; k < 3; k++) result[k] = val[k];
93         }
94 
evalCalculatorExpr::SimpleVar95         void eval(const char** result) {}
96     };
97 
98     //! previous computations
99     mutable SimpleVar stack[STACK_DEPTH];
100     mutable bool fail_stack[STACK_DEPTH];
101     mutable int _count;
102 
103     //! resolve function that only supports one external variable 'x'
resolveVar(const std::string & name) const104     ExprVarRef* resolveVar(const std::string& name) const {
105         if (name[0] == '_') {
106             int position = atoi(name.substr(1, name.size() - 1).c_str());
107             if (position >= count()) std::cerr << "Use of unused result line." << std::endl;
108             if (fail_stack[position]) std::cerr << "Use of invalid result line." << std::endl;
109             return &(stack[position]);
110         };
111         addError(ErrorCode::UndeclaredVariable, { name }, 0, 0);
112         return 0;
113     };
114 };
115 
main(int argc,char * argv[])116 int main(int argc, char* argv[]) {
117 
118     std::cout << "SeExpr Basic Calculator";
119 
120     CalculatorExpr expr;
121     while (true) {
122         std::string str;
123         std::cout << std::endl << expr.count() << "> ";
124         // std::cin >> str;
125         getline(std::cin, str);
126 
127         if (std::cin.eof()) {
128             std::cout << std::endl;
129             str = "q";
130         };
131 
132         if (str == "quit" || str == "q") break;
133         expr.setDesiredReturnType(ExprType().FP(3));
134         expr.setExpr(str);
135 
136         if (!expr.isValid()) {
137             expr.fail_push();
138             std::cerr << "Expression failed: " << expr.parseError() << std::endl;
139         } else {
140             expr.push();
141             std::cout << "   " << expr.peek();
142         }
143     }
144     ExprFunc::cleanup();
145     return 0;
146 }
147