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