KSeExpr  4.0.4.0
ExprFuncStandard.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 "ExprNode.h"
7 #include "ExprFuncStandard.h"
8 
9 namespace KSeExpr {
10 
11 ExprType ExprFuncStandard::prep(ExprFuncNode* node, bool scalarWanted, ExprVarEnvBuilder& envBuilder) const {
12  if (_funcType < VEC) {
13  // scalar argumented functions returning scalars
14  // use promote protocol...
15 
16  bool error = false;
17  int nonOneDim = 1; // defaults to 1, if another is seen record!
18  bool multiInvoke = !scalarWanted;
19  ExprType retType;
20  for (int c = 0; c < node->numChildren(); c++) {
21  ExprType childType = node->child(c)->prep(scalarWanted, envBuilder);
22  int childDim = childType.dim();
23  node->child(c)->checkIsFP(childType, error);
24  retType.setLifetime(childType);
25  if (childDim != 1) {
26  if (nonOneDim != 1 && childDim != nonOneDim) multiInvoke = false;
27  nonOneDim = childDim;
28  }
29  }
30  if (error)
31  return retType.Error();
32  else if (multiInvoke && nonOneDim != 1)
33  return retType.FP(nonOneDim);
34  return retType.FP(1);
35  } else {
36  // vector argumented functions
37  bool error = false;
38  ExprType retType;
39  for (int c = 0; c < node->numChildren(); c++) {
40  ExprType childType = node->child(c)->prep(scalarWanted, envBuilder);
41  int childDim = childType.dim();
42  node->child(c)->checkIsFP(childType, error);
43  node->child(c)->checkCondition(childDim == 1 || childDim == 3, ErrorCode::ExpectedFloatOrFloat3, {}, error);
44  retType.setLifetime(childType);
45  }
46  if (error)
47  return retType.Error();
48  else if (scalarWanted || _funcType < VECVEC)
49  return retType.FP(1);
50  else
51  return retType.FP(3);
52  }
53 }
54 
55 int Func0Op(int* opData, double* fp, char** c, std::vector<int>& ) {
56  fp[opData[1]] = ((ExprFuncStandard::Func0*)(c[opData[0]]))();
57  return 1;
58 }
59 int Func1Op(int* opData, double* fp, char** c, std::vector<int>&) {
60  fp[opData[2]] = ((ExprFuncStandard::Func1*)(c[opData[0]]))(fp[opData[1]]);
61  return 1;
62 }
63 int Func2Op(int* opData, double* fp, char** c, std::vector<int>&) {
64  fp[opData[3]] = ((ExprFuncStandard::Func2*)(c[opData[0]]))(fp[opData[1]], fp[opData[2]]);
65  return 1;
66 }
67 int Func3Op(int* opData, double* fp, char** c, std::vector<int>&) {
68  fp[opData[4]] = ((ExprFuncStandard::Func3*)(c[opData[0]]))(fp[opData[1]], fp[opData[2]], fp[opData[3]]);
69  return 1;
70 }
71 int Func4Op(int* opData, double* fp, char** c, std::vector<int>&) {
72  fp[opData[5]] =
73  ((ExprFuncStandard::Func4*)(c[opData[0]]))(fp[opData[1]], fp[opData[2]], fp[opData[3]], fp[opData[4]]);
74  return 1;
75 }
76 int Func5Op(int* opData, double* fp, char** c, std::vector<int>&) {
77  fp[opData[6]] = ((ExprFuncStandard::Func5*)(c[opData[0]]))(
78  fp[opData[1]], fp[opData[2]], fp[opData[3]], fp[opData[4]], fp[opData[5]]);
79  return 1;
80 }
81 int Func6Op(int* opData, double* fp, char** c, std::vector<int>&) {
82  fp[opData[7]] = ((ExprFuncStandard::Func6*)(c[opData[0]]))(
83  fp[opData[1]], fp[opData[2]], fp[opData[3]], fp[opData[4]], fp[opData[5]], fp[opData[6]]);
84  return 1;
85 }
86 int FuncNOp(int* opData, double* fp, char** c, std::vector<int>&) {
87  int n = opData[1];
88  double* vals = static_cast<double*>(alloca(n * sizeof(double)));
89  for (int k = 0; k < n; k++) vals[k] = fp[opData[k + 2]];
90  double* out = &fp[opData[n + 2]];
91  *out = ((ExprFuncStandard::Funcn*)(c[opData[0]]))(n, vals);
92  return 1;
93 }
94 int Func1VOp(int* opData, double* fp, char** c, std::vector<int>&) {
95  fp[opData[2]] = ((ExprFuncStandard::Func1v*)(c[opData[0]]))(Vec3d::copy(&fp[opData[1]]));
96  return 1;
97 }
98 int Func2VOp(int* opData, double* fp, char** c, std::vector<int>&) {
99  fp[opData[3]] =
100  ((ExprFuncStandard::Func2v*)(c[opData[0]]))(Vec3d::copy(&fp[opData[1]]), Vec3d::copy(&fp[opData[2]]));
101  return 1;
102 }
103 int Func1VVOp(int* opData, double* fp, char** c, std::vector<int>&) {
104  Vec3d v = ((ExprFuncStandard::Func1vv*)(c[opData[0]]))(Vec3d::copy(&fp[opData[1]]));
105  double* out = &fp[opData[2]];
106  for (int k = 0; k < 3; k++) out[k] = v[k];
107  return 1;
108 }
109 int Func2VVOp(int* opData, double* fp, char** c, std::vector<int>&) {
110  Vec3d v = ((ExprFuncStandard::Func2vv*)(c[opData[0]]))(Vec3d::copy(&fp[opData[1]]), Vec3d::copy(&fp[opData[2]]));
111  double* out = &fp[opData[3]];
112  for (int k = 0; k < 3; k++) out[k] = v[k];
113  return 1;
114 }
115 int FuncNVOp(int* opData, double* fp, char** c, std::vector<int>&) {
116  int n = opData[1];
117  Vec3d* vals = static_cast<Vec3d*>(alloca(n * sizeof(Vec3d)));
118  for (int k = 0; k < n; k++) new (vals + k) Vec3d(Vec3dRef(&fp[opData[k + 2]])); // placement new!
119  double* out = &fp[opData[n + 2]];
120  *out = ((ExprFuncStandard::Funcnv*)(c[opData[0]]))(n, vals);
121  return 1;
122 }
123 int FuncNVVOp(int* opData, double* fp, char** c, std::vector<int>&) {
124  int n = opData[1];
125  Vec3d* vals = static_cast<Vec3d*>(alloca(n * sizeof(Vec3d)));
126  for (int k = 0; k < n; k++) new (vals + k) Vec3d(Vec3dRef(&fp[opData[k + 2]])); // placement new!
127  double* out = &fp[opData[n + 2]];
128  Vec3d val = ((ExprFuncStandard::Funcnvv*)(c[opData[0]]))(n, vals);
129  for (int k = 0; k < 3; k++) out[k] = val[k];
130  return 1;
131 }
132 
133 int ExprFuncStandard::buildInterpreter(const ExprFuncNode* node, Interpreter* interpreter) const {
134  std::vector<int> argOps;
135  for (int c = 0; c < node->numChildren(); c++) {
136  int op = node->child(c)->buildInterpreter(interpreter);
137  argOps.push_back(op);
138  }
139  int retOp = -1;
140 
141  int funcPtrLoc = interpreter->allocPtr();
142  interpreter->s[funcPtrLoc] = (char*)_func;
143 
144  Interpreter::OpF op = nullptr;
145  switch (_funcType) {
146  case FUNC0:
147  op = Func0Op;
148  break;
149  case FUNC1:
150  op = Func1Op;
151  break;
152  case FUNC2:
153  op = Func2Op;
154  break;
155  case FUNC3:
156  op = Func3Op;
157  break;
158  case FUNC4:
159  op = Func4Op;
160  break;
161  case FUNC5:
162  op = Func5Op;
163  break;
164  case FUNC6:
165  op = Func6Op;
166  break;
167  case FUNCN:
168  op = FuncNOp;
169  break;
170  case FUNC1V:
171  op = Func1VOp;
172  break;
173  case FUNC2V:
174  op = Func2VOp;
175  break;
176  case FUNCNV:
177  op = FuncNVOp;
178  break;
179  case FUNC1VV:
180  op = Func1VVOp;
181  break;
182  case FUNC2VV:
183  op = Func2VVOp;
184  break;
185  case FUNCNVV:
186  op = FuncNVVOp;
187  break;
188  default:
189  assert(false);
190  }
191 
192  if (_funcType < VEC) {
193  retOp = interpreter->allocFP(node->type().dim());
194  for (int k = 0; k < node->type().dim(); k++) {
195  interpreter->addOp(op);
196  interpreter->addOperand(funcPtrLoc);
197  if (_funcType == FUNCN) interpreter->addOperand(static_cast<int>(argOps.size()));
198  for (size_t c = 0; c < argOps.size(); c++) {
199  if (node->child(c)->type().isFP(1))
200  interpreter->addOperand(argOps[c]);
201  else
202  interpreter->addOperand(argOps[c] + k);
203  }
204  interpreter->addOperand(retOp + k);
205  interpreter->endOp();
206  }
207  } else {
208  // do any promotions that are necessary
209  for (size_t c = 0; c < argOps.size(); c++) {
210  if (node->child(c)->type().dim() == 1) {
211  int promotedArgOp = interpreter->allocFP(3);
212  interpreter->addOp(Promote<3>::f);
213  interpreter->addOperand(argOps[c]);
214  interpreter->addOperand(promotedArgOp);
215  interpreter->endOp();
216  argOps[c] = promotedArgOp;
217  }
218  }
219  retOp = interpreter->allocFP(_funcType >= VECVEC ? 3 : 1);
220 
221  interpreter->addOp(op);
222  interpreter->addOperand(funcPtrLoc);
223  if (_funcType == FUNCNV || _funcType == FUNCNVV) interpreter->addOperand(static_cast<int>(argOps.size()));
224  for (int argOp : argOps) {
225  interpreter->addOperand(argOp);
226  }
227  interpreter->addOperand(retOp);
228  interpreter->endOp();
229  }
230  if (Expression::debugging) {
231  std::cerr << "Interpreter dump" << std::endl;
232  interpreter->print();
233  }
234  return retOp;
235 }
236 } // namespace KSeExpr
Node that calls a function.
Definition: ExprNode.h:654
double(double, double, double, double) Func4
Vec3d(int, const Vec3d *) Funcnvv
double(int, double *) Funcn
ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const override
int buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const override
Build an interpreter to evaluate the expression.
double(const Vec3d &) Func1v
double(const Vec3d &, const Vec3d &) Func2v
double(double, double, double, double, double, double) Func6
double(double, double, double) Func3
Vec3d(const Vec3d &) Func1vv
double(int, const Vec3d *) Funcnv
double(double, double, double, double, double) Func5
Vec3d(const Vec3d &, const Vec3d &) Func2vv
double(double, double) Func2
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:121
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
bool checkIsFP(const ExprType &type, bool &error) const
Checks if the type is a float[d] for any d.
Definition: ExprNode.h:224
int numChildren() const
Number of children.
Definition: ExprNode.h:108
bool checkCondition(bool check, const ErrorCode message, const std::vector< std::string > &ids, bool &error) const
Checks the boolean value and records an error string with node if it is false.
Definition: ExprNode.h:210
const ExprType & type() const
The type of the node.
Definition: ExprNode.h:150
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:114
int dim() const
Definition: ExprType.h:180
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition: ExprType.h:97
ExprType & setLifetime(const ExprType &a)
Assign the lifetime from type a to be my type.
Definition: ExprType.h:150
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:190
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:111
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:181
static bool debugging
Whether to debug expressions.
Definition: Expression.h:77
int addOp(OpF op)
! adds an operator to the program (pointing to the data at the current location)
Definition: Interpreter.h:63
void endOp(bool execute=true)
Definition: Interpreter.h:73
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 allocPtr()
Allocate a pointer location (can be anything, but typically space for char*)
Definition: Interpreter.h:101
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
static Vec< double, d, false > copy(T2 *raw)
Initialize vector value using raw memory.
Definition: Vec.h:40
int FuncNOp(int *opData, double *fp, char **c, std::vector< int > &)
int Func3Op(int *opData, double *fp, char **c, std::vector< int > &)
int Func1VOp(int *opData, double *fp, char **c, std::vector< int > &)
int Func1VVOp(int *opData, double *fp, char **c, std::vector< int > &)
int FuncNVVOp(int *opData, double *fp, char **c, std::vector< int > &)
int Func1Op(int *opData, double *fp, char **c, std::vector< int > &)
int Func2Op(int *opData, double *fp, char **c, std::vector< int > &)
@ ExpectedFloatOrFloat3
"Expected float or FP[3]"
Definition: ErrorCode.h:20
int Func5Op(int *opData, double *fp, char **c, std::vector< int > &)
int Func2VOp(int *opData, double *fp, char **c, std::vector< int > &)
int Func4Op(int *opData, double *fp, char **c, std::vector< int > &)
int Func0Op(int *opData, double *fp, char **c, std::vector< int > &)
int Func6Op(int *opData, double *fp, char **c, std::vector< int > &)
Vec< double, 3, false > Vec3d
Definition: Vec.h:352
int Func2VVOp(int *opData, double *fp, char **c, std::vector< int > &)
int FuncNVOp(int *opData, double *fp, char **c, std::vector< int > &)
Vec< double, 3, true > Vec3dRef
Definition: Vec.h:360
Promotes a FP[1] to FP[d].
Definition: Interpreter.h:18