KSeExpr  4.0.4.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>
7 #include <KSeExpr/Expression.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 
16 using namespace KSeExpr;
17 
22 class CalculatorExpr : public Expression
23 {
24 public:
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 
82 private:
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 
126 int 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 }
void eval(ArgHandle args) override
#define STACK_DEPTH
int main(int, char *[])
static void cleanup()
cleanup all functions
Definition: ExprFunc.cpp:110
abstract class for implementing variable references
Definition: Expression.h:36
main expression class
Definition: Expression.h:67
@ UndeclaredVariable
Definition: ErrorCode.h:35
const ExprStrNode * isString(const ExprNode *testee)
Definition: ExprPatterns.h:36