KSeExpr 6.0.0.0
asciiCalculator.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2// SPDX-License-Identifier: LicenseRef-Apache-2.0
3// SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6#include <KSeExpr/ExprFunc.h>
8#include <KSeExpr/Vec.h>
9#include <cassert>
10#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13
14#define STACK_DEPTH 256
15
16using namespace KSeExpr;
17
22class CalculatorExpr : public Expression
23{
24public:
26 CalculatorExpr(const std::string &expr)
27 : Expression(expr)
28 {
29 for (int i = 0; i < STACK_DEPTH; i++) {
30 stack.at(i).val = Vec<double, 3, false>(0.0);
31 fail_stack.at(i) = false;
32 }
33 };
34
36 CalculatorExpr()
37 : Expression() {};
38
40 void push()
41 {
42 if (returnType().isString()) {
43 evalStr();
44 } else if (returnType().isFP()) {
45 const double *val = evalFP();
46 int dim = returnType().dim();
47 for (int k = 0; k < 3; k++)
48 std::cerr << val[k] << " ";
49 std::cerr << std::endl;
50 if (dim == 1)
51 stack.at(_count).val = Vec<double, 3, false>(val[0]);
52 else if (dim == 2)
53 stack.at(_count).val = Vec<double, 3, false>(val[0], val[1], 0);
54 else if (dim == 3)
55 stack.at(_count).val = Vec<double, 3, true>(const_cast<double *>(&val[0]));
56 else {
57 std::cerr << "Return type FP(" << dim << ") ignoring" << std::endl;
58 }
59
60 _count++;
61 }
62 };
63
65 void fail_push()
66 {
67 fail_stack.at(_count) = true;
68 stack.at(_count).val = Vec<double, 3, false>(0.0);
69 _count++;
70 };
71
73 {
74 return stack.at(_count - 1).val;
75 }
76
77 int count() const
78 {
79 return _count;
80 };
81
82private:
84 struct SimpleVar : public ExprVarRef {
85 SimpleVar()
86 : ExprVarRef(ExprType().FP(3).Varying())
87 , val(0.0)
88 {
89 }
90
91 Vec<double, 3, false> val; // independent variable
92
93 void eval(double *result) override
94 {
95 for (int k = 0; k < 3; k++)
96 result[k] = val[k];
97 }
98
99 void eval(const char **) override
100 {
101 assert(false);
102 }
103 };
104
106 mutable std::array<SimpleVar, STACK_DEPTH> stack;
107 mutable std::array<bool, STACK_DEPTH> fail_stack {};
108 mutable int _count {0};
109
111 ExprVarRef *resolveVar(const std::string &name) const override
112 {
113 if (name[0] == '_') {
114 int position = std::stoi(name.substr(1, name.size() - 1));
115 if (position >= count())
116 std::cerr << "Use of unused result line." << std::endl;
117 if (fail_stack.at(position))
118 std::cerr << "Use of invalid result line." << std::endl;
119 return &(stack.at(position));
120 };
121 addError(ErrorCode::UndeclaredVariable, {name}, 0, 0);
122 return nullptr;
123 };
124};
125
126int main(int, char *[])
127{
128 std::cout << "KSeExpr Basic Calculator";
129
130 CalculatorExpr expr;
131 while (true) {
132 std::string str;
133 std::cout << std::endl << expr.count() << "> ";
134 // std::cin >> str;
135 getline(std::cin, str);
136
137 if (std::cin.eof()) {
138 std::cout << std::endl;
139 str = "q";
140 };
141
142 if (str == "quit" || str == "q")
143 break;
144 expr.setDesiredReturnType(ExprType().FP(3));
145 expr.setExpr(str);
146
147 if (!expr.isValid()) {
148 expr.fail_push();
149 std::cerr << "Expression failed: " << expr.parseError() << std::endl;
150 } else {
151 expr.push();
152 std::cout << " " << expr.peek();
153 }
154 }
156 return 0;
157}
#define STACK_DEPTH
int main(int, char *[])
static void cleanup()
cleanup all functions
Definition ExprFunc.cpp:110
int dim() const
Definition ExprType.h:180
abstract class for implementing variable references
Definition Expression.h:36
main expression class
Definition Expression.h:67
void addError(const ErrorCode error, const std::vector< std::string > ids, const int startPos, const int endPos) const
Definition Expression.h:207
virtual ExprVarRef * resolveVar(const std::string &) const
Definition Expression.h:201
const double * evalFP(VarBlock *varBlock=nullptr) const
const ExprType & returnType() const
const char * evalStr(VarBlock *varBlock=nullptr) const
const ExprStrNode * isString(const ExprNode *testee)