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
21namespace SeExpr2 {
22
23ExprType 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
67int Func0Op(int* opData, double* fp, char** c, std::vector<int>& callStack) {
68 fp[opData[1]] = ((ExprFuncStandard::Func0*)(c[opData[0]]))();
69 return 1;
70}
71int 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}
75int 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}
79int 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}
83int 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}
88int 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}
93int 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}
98int 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}
106int 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}
110int 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}
115int 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}
121int 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}
127int 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}
135int 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
145int 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 }
242 std::cerr << "Interpreter dump" << std::endl;
243 interpreter->print();
244 }
245 return retOp;
246}
247}
Node that calls a function.
Definition ExprNode.h:517
virtual int buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const
Build an interpreter to evaluate the expression.
Vec3d Func1vv(const Vec3d &)
double Func1v(const Vec3d &)
double Func2(double, double)
Vec3d Func2vv(const Vec3d &, const Vec3d &)
double Func5(double, double, double, double, double)
double Func6(double, double, double, double, double, double)
double Func2v(const Vec3d &, const Vec3d &)
double Func3(double, double, double)
double Func4(double, double, double, double)
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &envBuilder) const
double Funcn(int n, double *params)
double Funcnv(int n, const Vec3d *params)
Vec3d Funcnvv(int n, const Vec3d *params)
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
int numChildren() const
Number of children.
Definition ExprNode.h:114
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition ExprNode.h:117
const ExprType & type() const
The type of the node.
Definition ExprNode.h:145
bool checkIsFP(const ExprType &type, bool &error)
Checks if the type is a float[d] for any d.
Definition ExprNode.h:202
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
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
Definition ExprNode.cpp:104
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition ExprType.h:90
bool isFP() const
Direct is predicate checks.
Definition ExprType.h:164
int dim() const
Definition ExprType.h:160
ExprType & setLifetime(const ExprType &a)
Assign the lifetime from type a to be my type.
Definition ExprType.h:136
ExprType & Error()
Mutate this into an error type.
Definition ExprType.h:102
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition ExprEnv.h:148
static bool debugging
Whether to debug expressions.
Definition Expression.h:86
int allocFP(int n)
! Allocate a floating point set of data of dimension n
int addOp(OpF op)
! adds an operator to the program (pointing to the data at the current location)
Definition Interpreter.h:73
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
int addOperand(int param)
! Adds an operand. Note this should be done after doing the addOp!
Definition Interpreter.h:96
int allocPtr()
Allocate a pointer location (can be anything, but typically space for char*)
void endOp(bool execute=true)
Definition Interpreter.h:83
std::vector< char * > s
constant and evaluated pointer data
Definition Interpreter.h:45
void print(int pc=-1) const
Debug by printing program.
static Vec< double, d, false > copy(T2 *raw, INVALID_WITH_VECTOR_REFERENCE u=(TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Definition Vec.h:113
int Func1VVOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func5Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
int FuncNVOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func6Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func4Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func0Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
Vec< double, 3, false > Vec3d
Definition Vec.h:384
int Func3Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func1VOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func2Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
int FuncNVVOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int FuncNOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
Vec< double, 3, true > Vec3dRef
Definition Vec.h:392
int Func2VOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func2VVOp(int *opData, double *fp, char **c, std::vector< int > &callStack)
int Func1Op(int *opData, double *fp, char **c, std::vector< int > &callStack)
Promotes a FP[1] to FP[d].
Definition Interpreter.h:28