KSeExpr 6.0.0.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
9namespace KSeExpr {
10
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!
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;
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;
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
55int Func0Op(int* opData, double* fp, char** c, std::vector<int>& ) {
56 fp[opData[1]] = ((ExprFuncStandard::Func0*)(c[opData[0]]))();
57 return 1;
58}
59int 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}
63int 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}
67int 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}
71int 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}
76int 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}
81int 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}
86int 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}
94int 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}
98int 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}
103int 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}
109int 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}
115int 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}
123int 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
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);
213 interpreter->addOperand(argOps[c]);
214 interpreter->addOperand(promotedArgOp);
215 interpreter->endOp();
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 }
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
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.
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(*)(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
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