KSeExpr  4.0.4.0
Interpreter.h
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 #pragma once
7 
8 #include "VarBlock.h"
9 #include <cassert>
10 #include <vector>
11 #include <stack>
12 
13 namespace KSeExpr {
14 class ExprLocalVar;
15 
17 template <int d>
18 struct Promote {
19  // TODO: this needs a name that is prefixed by Se!
20  static int f(int* opData, double* fp, char**, std::vector<int>&) {
21  int posIn = opData[0];
22  int posOut = opData[1];
23  for (int k = posOut; k < posOut + d; k++) fp[k] = fp[posIn];
24  return 1;
25  }
26 };
27 
30 class Interpreter {
31  public:
33  std::vector<double> d;
35  std::vector<char*> s;
37  std::vector<int> opData;
38 
40  using VarToLoc = std::map<const ExprLocalVar *, int>;
42 
44  using OpF = int (*)(int *, double *, char **, std::vector<int> &);
45 
46  std::vector<std::pair<OpF, int> > ops;
47  std::vector<int> callStack;
48 
49  private:
50  bool _startedOp{};
51  int _pcStart{};
52 
53  public:
55  s.push_back(nullptr); // reserved for double** of variable block
56  s.push_back(nullptr); // reserved for double** of variable block
57  }
58 
60  int nextPC() const { return static_cast<int>(ops.size()); }
61 
63  int addOp(OpF op) {
64  if (_startedOp) {
65  assert(false && "addOp called within another addOp");
66  }
67  _startedOp = true;
68  int pc = static_cast<int>(ops.size());
69  ops.emplace_back(op, static_cast<int>(opData.size()));
70  return pc;
71  }
72 
73  void endOp(bool execute = true) {
74  _startedOp = false;
75  if (execute) {
76  double* fp = &d[0];
77  char** str = &s[0];
78  int pc = static_cast<int>(ops.size()) - 1;
79  const std::pair<OpF, int>& op = ops[pc];
80  int* opCurr = &opData[0] + op.second;
81  pc += op.first(opCurr, fp, str, callStack);
82  }
83  }
84 
86  int addOperand(int param) {
87  assert(_startedOp);
88  int ret = static_cast<int>(opData.size());
89  opData.push_back(param);
90  return ret;
91  }
92 
94  int allocFP(int n) {
95  int ret = static_cast<int>(d.size());
96  for (int k = 0; k < n; k++) d.push_back(0);
97  return ret;
98  }
99 
101  int allocPtr() {
102  int ret = static_cast<int>(s.size());
103  s.push_back(0);
104  return ret;
105  }
106 
108  void eval(VarBlock* varBlock, bool debug = false);
110  void print(int pc = -1) const;
111 
112  void setPCStart(int pcStart) { _pcStart = pcStart; }
113 };
114 
116 template <template <int d> class T, class T_FUNCTYPE = Interpreter::OpF>
117 T_FUNCTYPE getTemplatizedOp(int i) {
118  switch (i) {
119  case 1:
120  return T<1>::f;
121  case 2:
122  return T<2>::f;
123  case 3:
124  return T<3>::f;
125  case 4:
126  return T<4>::f;
127  case 5:
128  return T<5>::f;
129  case 6:
130  return T<6>::f;
131  case 7:
132  return T<7>::f;
133  case 8:
134  return T<8>::f;
135  case 9:
136  return T<9>::f;
137  case 10:
138  return T<10>::f;
139  case 11:
140  return T<11>::f;
141  case 12:
142  return T<12>::f;
143  case 13:
144  return T<13>::f;
145  case 14:
146  return T<14>::f;
147  case 15:
148  return T<15>::f;
149  case 16:
150  return T<16>::f;
151  default:
152  assert(false && "Invalid dynamic parameter (not supported template)");
153  break;
154  }
155  return nullptr;
156 }
157 } // namespace KSeExpr
std::vector< std::pair< OpF, int > > ops
Definition: Interpreter.h:46
std::vector< double > d
Double data (constants and evaluated)
Definition: Interpreter.h:33
int addOp(OpF op)
! adds an operator to the program (pointing to the data at the current location)
Definition: Interpreter.h:63
void eval(VarBlock *varBlock, bool debug=false)
Evaluate program.
Definition: Interpreter.cpp:20
void endOp(bool execute=true)
Definition: Interpreter.h:73
std::vector< int > callStack
Definition: Interpreter.h:47
void setPCStart(int pcStart)
Definition: Interpreter.h:112
std::map< const ExprLocalVar *, int > VarToLoc
Not needed for eval only building.
Definition: Interpreter.h:40
std::vector< char * > s
constant and evaluated pointer data
Definition: Interpreter.h:35
int allocFP(int n)
! Allocate a floating point set of data of dimension n
Definition: Interpreter.h:94
int(*)(int *, double *, char **, std::vector< int > &) OpF
Op function pointer arguments are (int* currOpData,double* currD,char** c,std::stack<int>& callStacku...
Definition: Interpreter.h:44
int nextPC() const
Return the position that the next instruction will be placed at.
Definition: Interpreter.h:60
int allocPtr()
Allocate a pointer location (can be anything, but typically space for char*)
Definition: Interpreter.h:101
std::vector< int > opData
Ooperands to op.
Definition: Interpreter.h:37
int addOperand(int param)
! Adds an operand. Note this should be done after doing the addOp!
Definition: Interpreter.h:86
void print(int pc=-1) const
Debug by printing program.
Definition: Interpreter.cpp:58
A thread local evaluation context. Just allocate and fill in with data.
Definition: VarBlock.h:22
T_FUNCTYPE getTemplatizedOp(int i)
Return the function f encapsulated in class T for the dynamic i converted to a static d.
Definition: Interpreter.h:117
Promotes a FP[1] to FP[d].
Definition: Interpreter.h:18
static int f(int *opData, double *fp, char **, std::vector< int > &)
Definition: Interpreter.h:20