33 double* fp =
d.data();
34 char** str =
s.data();
39 if (
block->threadSafe ==
true) {
43 memcpy(fp,
d.data(),
d.size() *
sizeof(
double));
47 str =
block->s.data();
48 memcpy(str,
s.data(),
s.size() *
sizeof(
char*));
52 str[0] =
reinterpret_cast<char*
>(
block->data());
53 str[1] =
reinterpret_cast<char*
>(
static_cast<size_t>(
block->indirectIndex));
57 int end =
static_cast<int>(
ops.size());
60 std::cerr <<
"Running op at " <<
pc << std::endl;
63 const std::pair<OpF, int>&
op =
ops[
pc];
70 std::cerr <<
"---- ops ----------------------" << std::endl;
71 for (
size_t i = 0;
i <
ops.size();
i++) {
72 const char* name =
"";
84 std::cerr <<
"---- opdata ----------------------" << std::endl;
85 for (
size_t k = 0;
k <
opData.size();
k++) {
86 std::cerr <<
"opData[" <<
k <<
"]= " <<
opData[
k] << std::endl;
89 std::cerr <<
"----- fp --------------------------" << std::endl;
90 for (
size_t k = 0;
k <
d.size();
k++) {
91 std::cerr <<
"fp[" <<
k <<
"]= " <<
d[
k] << std::endl;
94 std::cerr <<
"---- str ----------------------" << std::endl;
95 std::cerr <<
"s[0] reserved for datablock = " <<
reinterpret_cast<size_t>(
s[0]) << std::endl;
96 std::cerr <<
"s[1] is indirectIndex = " <<
reinterpret_cast<size_t>(
s[1]) << std::endl;
97 for (
size_t k = 2;
k <
s.size();
k++) {
98 std::cerr <<
"s[" <<
k <<
"]= 0x" <<
s[
k];
99 if (
s[
k]) std::cerr <<
" '" <<
s[
k][0] <<
s[
k][1] <<
s[
k][2] <<
s[
k][3] <<
"...'";
100 std::cerr << std::endl;
110template <
char c,
template <
char c1,
int d>
class T>
146 assert(
false &&
"Invalid dynamic parameter (not supported template)");
155struct BinaryStringOp {
156 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
158 char*& out = *(
char**)c[opData[0]];
159 char* in1 = c[opData[1]];
160 char* in2 = c[opData[2]];
165 int len1 =
static_cast<int>(strlen(in1));
166 int len2 =
static_cast<int>(strlen(in2));
167 if (out == 0 || len1 + len2 + 1 > strlen(out))
170 out =
new char [len1 + len2 + 1];
174 memset(out, 0, len1 + len2 + 1);
178 strcat(out + len1, in2);
179 out[len1 + len2] =
'\0';
189template <
char op,
int d>
191 static double niceMod(
double a,
double b) {
192 if (b == 0)
return 0;
193 return a - floor(a / b) *
b;
196 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
197 double* in1 = fp + opData[0];
198 double* in2 = fp + opData[1];
199 double* out = fp + opData[2];
201 for (
int k = 0; k < d; k++) {
204 *out = (*in1) + (*in2);
207 *out = (*in1) - (*in2);
210 *out = (*in1) * (*in2);
213 *out = (*in1) / (*in2);
216 *out = niceMod(*in1, *in2);
219 *out =
pow(*in1, *in2);
223 *out = (*in1) < (*in2);
226 *out = (*in1) > (*in2);
229 *out = (*in1) <= (*in2);
232 *out = (*in1) >= (*in2);
235 *out = (*in1) && (*in2);
238 *out = (*in1) || (*in2);
252template <
char op,
int d>
254 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
255 double* in = fp + opData[0];
256 double* out = fp + opData[1];
257 for (
int k = 0; k < d; k++) {
281 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
282 int tuple = opData[0];
283 int subscript = int(fp[opData[1]]);
285 if (subscript >= d || subscript < 0)
288 fp[out] = fp[tuple + subscript];
296 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
298 for (
int k = 0; k < d; k++) {
299 fp[out + k] = fp[opData[k]];
308 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
311 for (
int k = 0; k < d; k++) {
312 fp[out + k] = fp[in + k];
320 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
329struct CondJmpRelativeIfFalse {
330 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
331 bool cond = (bool)fp[opData[0]];
340struct CondJmpRelativeIfTrue {
341 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
342 bool cond = (bool)fp[opData[0]];
352 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
return opData[0]; }
357 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
358 ExprVarRef* ref =
reinterpret_cast<ExprVarRef*
>(c[opData[0]]);
359 if (ref->type().isFP()) {
360 ref->eval(fp + opData[1]);
362 ref->eval(
const_cast<const char**
>(c + opData[1]));
371 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
373 double* basePointer =
reinterpret_cast<double*
>(c[0]) + opData[0];
374 double* destPointer = fp + opData[1];
375 for (
int i = 0; i < dim; i++) destPointer[i] = basePointer[i];
382template <
char uniform,
int dim>
383struct EvalVarBlockIndirect {
384 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
386 int stride = opData[2];
387 int outputVarBlockOffset = opData[0];
388 int destIndex = opData[1];
389 size_t indirectIndex =
reinterpret_cast<size_t>(c[1]);
390 double* basePointer =
391 reinterpret_cast<double**
>(c[0])[outputVarBlockOffset] + (uniform ? 0 : (stride * indirectIndex));
392 double* destPointer = fp + destIndex;
393 for (
int i = 0; i < dim; i++) destPointer[i] = basePointer[i];
403template <
char op,
int d>
405 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
407 double* in0 = fp + opData[0];
408 double* in1 = fp + opData[1];
409 double* out = fp + opData[2];
410 for (
int k = 0; k < d; k++) {
413 result &= (*in0) == (*in1);
416 result &= (*in0) != (*in1);
430struct CompareEqOp<op, 3> {
431 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
432 bool eq = fp[opData[0]] == fp[opData[1]] && fp[opData[0] + 1] == fp[opData[1] + 1] &&
433 fp[opData[0] + 2] == fp[opData[1] + 2];
434 if (op ==
'=') fp[opData[2]] = eq;
435 if (op ==
'!') fp[opData[2]] = !eq;
440template <
char op,
int d>
441struct StrCompareEqOp {
443 static int f(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
446 fp[opData[2]] = strcmp(c[opData[0]], c[opData[1]]) == 0;
449 fp[opData[2]] = strcmp(c[opData[0]], c[opData[1]]) != 0;
458int ProcedureReturn(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
459 int newPC = callStack.back();
460 callStack.pop_back();
461 return newPC - opData[0];
466int ProcedureCall(
int* opData,
double* fp,
char** c, std::vector<int>& callStack) {
467 callStack.push_back(opData[0]);
489 for (
int c = 0; c <
callerNode->numChildren(); c++) {
493 if (
child->type().isFP()) {
556 std::vector<int>
locs;
706 throw std::runtime_error(
"Unallocated variable encountered.");
711 int dim =
type.dim();
745 assert(
loc != -1 &&
"Invalid type found");
754 assert(
false &&
"Invalid desired assign type");
775 }
else if (
varDest->type().isString()) {
781 assert(
false &&
"failed to promote invalid type");
839 if (
_op ==
'&' ||
_op ==
'|') {
848 interpreter->addOp(
_op ==
'&' ? CondJmpRelativeIfFalse::f : CondJmpRelativeIfTrue::f);
936 if (
child0->type().isFP()) {
962 assert(
false &&
"Invalid operation");
963 }
else if (
child0->type().isString()) {
969 assert(
false &&
"Invalid operation");
971 assert(
false &&
"Invalid type for comparison");
1032 else if (
type().isString())
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
char _op
_op '<' less-than, 'l' less-than-eq, '>' greater-than, 'g' greater-than-eq
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
Node that calls a function.
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
const ExprPrototypeNode * prototype() const
TODO: Accessor for prototype (probably not needed when we use prep right)
int buildInterpreter(Interpreter *interpreter) const
Build the interpreter.
int buildInterpreterForCall(const ExprFuncNode *callerNode, Interpreter *interpreter) const
Build interpreter if we are called.
ExprLocalVar join (merge) references. Remembers which variables are possible assigners to this.
ExprLocalVar reference, all local variables in seexpr are subclasses of this or this itself.
int buildInterpreter(Interpreter *interpreter) const
Allocates variable for interpreter.
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
int numChildren() const
Number of children.
const ExprNode * child(size_t i) const
Get 0 indexed child.
const ExprType & type() const
The type of the node.
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
int buildInterpreter(Interpreter *interpreter) const
Build the interpreter.
std::vector< int > _interpreterOps
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
bool isFP() const
Direct is predicate checks.
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
std::vector< std::pair< std::string, ExprLocalVarPhi * > > & merge(size_t index)
Node that references a variable.
const ExprVarRef * var() const
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
abstract class for implementing variable references
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
int(* OpF)(int *, double *, char **, std::vector< int > &)
Op function pointer arguments are (int* currOpData,double* currD,char** c,std::stack<int>& callStacku...
std::vector< std::pair< OpF, int > > ops
void eval(VarBlock *varBlock, bool debug=false)
Evaluate program.
std::vector< int > opData
Ooperands to op.
std::vector< double > d
Double data (constants and evaluated)
std::vector< char * > s
constant and evaluated pointer data
void print(int pc=-1) const
Debug by printing program.
std::vector< int > callStack
Internally implemented var ref used by SeExpr.
A thread local evaluation context. Just allocate and fill in with data.
you may not use this file except in compliance with the License and the following modification to it
const ExprStrNode * isString(const ExprNode *testee)
void copyVarToPromotedPosition(Interpreter *interpreter, ExprLocalVar *varSource, ExprLocalVar *varDest)
static Interpreter::OpF getTemplatizedOp2(int i)
Return the function f encapsulated in class T for the dynamic i converted to a static d....
< br > pow($a, 0.5)+ $b< br >< br ></div > External variables can also be overridden by local assignment.  
Defined as a *alpha b *alpha< br ></div >< br > float< b > float a
with numParticles numAttributes A variable block contains variable names and types but doesn t care what the values are< pre > void f(const std::string &s, MyParticleData *p, int outputDim=3)