SeExpr
asciiCalculator.cpp
Go to the documentation of this file.
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
27using namespace SeExpr2;
28
33class CalculatorExpr : public Expression {
34 public:
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
44 CalculatorExpr() : Expression(), _count(0) {
45 for (int i = 0; i < STACK_DEPTH; i++) fail_stack[i] = false;
46 };
47
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
72 void fail_push() {
73 fail_stack[_count] = true;
74 stack[_count].val = Vec<double, 3, false>(0.0);
75 _count++;
76 };
77
78 Vec<double, 3, false> peek() { return stack[_count - 1].val; }
79
80 int count() const {
81 return _count;
82 };
83
84 private:
86 struct SimpleVar : public ExprVarRef {
87 SimpleVar() : ExprVarRef(ExprType().FP(3).Varying()), val(0.0) {}
88
89 Vec<double, 3, false> val; // independent variable
90
91 void eval(double* result) {
92 for (int k = 0; k < 3; k++) result[k] = val[k];
93 }
94
95 void eval(const char** result) {}
96 };
97
99 mutable SimpleVar stack[STACK_DEPTH];
100 mutable bool fail_stack[STACK_DEPTH];
101 mutable int _count;
102
104 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("Use of undefined variable.", 0, 0);
112 return 0;
113 };
114};
115
116int 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}
virtual void eval(ArgHandle args)
int main(int argc, char *argv[])
#define STACK_DEPTH
int dim() const
Definition: ExprType.h:160
abstract class for implementing variable references
Definition: Expression.h:45
main expression class
Definition: Expression.h:76
virtual ExprVarRef * resolveVar(const std::string &name) const
Definition: Expression.h:199
Expression(EvaluationStrategy be=Expression::defaultEvaluationStrategy)
Definition: Expression.cpp:90
const char * evalStr(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:339
const ExprType & returnType() const
Definition: Expression.cpp:299
void addError(const std::string &error, const int startPos, const int endPos) const
Definition: Expression.h:205
const double * evalFP(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:304
const ExprStrNode * isString(const ExprNode *testee)
Definition: ExprPatterns.h:44
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")