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