SeExpr
ExprNode.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 #ifndef MAKEDEPEND
19 #include <math.h>
20 #include <sstream>
21 #endif
22 #include "Vec.h"
23 #include "ExprType.h"
24 #include "Expression.h"
25 #include "ExprEnv.h"
26 #include "ExprNode.h"
27 #include "ExprFunc.h"
28 #include "VarBlock.h"
29 
30 // TODO: add and other binary op demote to scalar if wantScalar
31 // TODO: logical operations like foo<bar should they do vector returns... right now no... implicit demote
32 // TODO: local function evaluation
33 // TODO: buildInterpreter for higher level nodes so the return location can be routed back
34 // TODO: ExprFuncNode interpreter stuff
35 // TODO: check each node for possibility of strings
36 
37 namespace SeExpr2 {
38 
39 ExprNode::ExprNode(const Expression* expr) : _expr(expr), _parent(0), _isVec(0) {}
40 
41 ExprNode::ExprNode(const Expression* expr, const ExprType& type) : _expr(expr), _parent(0), _isVec(0), _type(type) {}
42 
43 ExprNode::ExprNode(const Expression* expr, ExprNode* a) : _expr(expr), _parent(0), _isVec(0) {
44  _children.reserve(1);
45  addChild(a);
46 }
47 
49  : _expr(expr), _parent(0), _isVec(0), _type(type) {
50  _children.reserve(1);
51  addChild(a);
52 }
53 
54 ExprNode::ExprNode(const Expression* expr, ExprNode* a, ExprNode* b) : _expr(expr), _parent(0), _isVec(0) {
55  _children.reserve(2);
56  addChild(a);
57  addChild(b);
58 }
59 
61  : _expr(expr), _parent(0), _isVec(0), _type(type) {
62  _children.reserve(2);
63  addChild(a);
64  addChild(b);
65 }
66 
67 ExprNode::ExprNode(const Expression* expr, ExprNode* a, ExprNode* b, ExprNode* c) : _expr(expr), _parent(0), _isVec(0) {
68  _children.reserve(3);
69  addChild(a);
70  addChild(b);
71  addChild(c);
72 }
73 
75  : _expr(expr), _parent(0), _isVec(0), _type(type) {
76  _children.reserve(3);
77  addChild(a);
78  addChild(b);
79  addChild(c);
80 }
81 
83  // delete children
84  std::vector<ExprNode*>::iterator iter;
85  for (iter = _children.begin(); iter != _children.end(); iter++) delete *iter;
86 }
87 
89  _children.push_back(child);
90  child->_parent = this;
91 }
92 
93 void ExprNode::addChildren(ExprNode* surrogate) {
94  std::vector<ExprNode*>::iterator iter;
95  for (iter = surrogate->_children.begin(); iter != surrogate->_children.end(); iter++) {
96  addChild(*iter);
97  }
98  surrogate->_children.clear();
99  delete surrogate;
100 }
101 
102 ExprType ExprNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
108  bool error = false;
109 
110  _maxChildDim = 0;
111  for (int c = 0; c < numChildren(); c++) {
112  error |= !child(c)->prep(false, envBuilder).isValid();
113  int childDim = child(c)->type().isFP() ? child(c)->type().dim() : 0;
114  if (childDim > _maxChildDim) _maxChildDim = childDim;
115  }
116 
117  if (error)
118  setType(ExprType().Error());
119  else
120  setTypeWithChildLife(ExprType().None());
121 
122  return _type;
123 }
124 
125 ExprType ExprModuleNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
126  bool error = false;
127 
128  for (int c = 0; c < numChildren(); c++) error |= !child(c)->prep(false, envBuilder).isValid();
129  if (error)
130  setType(ExprType().Error());
131  else
132  setType(child(numChildren() - 1)->type());
133 
134  return _type;
135 }
136 
137 ExprType ExprPrototypeNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
138  // TODO: implement prototype
139  bool error=false;
140  checkCondition(false, "Prototypes are currently not supported",error);
141  return ExprType().Error();
142  #if 0
143  bool error = false;
144 
145  if (_retTypeSet) checkCondition(returnType().isValid(), "Function has bad return type", error);
146 
147  _argTypes.clear();
148  for (int c = 0; c < numChildren(); c++) {
149  ExprType type = child(c)->type();
150  checkCondition(type.isValid(), "Function has a parameter with a bad type", error);
151  _argTypes.push_back(type);
152  ExprLocalVar* localVar = new ExprLocalVar(type);
153  envBuilder.current()->add(((ExprVarNode*)child(c))->name(), localVar);
154  std::cerr << "after create localvar phi " << localVar->getPhi() << std::endl;
155  child(c)->prep(wantScalar, envBuilder);
156  }
157 
158  if (error)
159  setType(ExprType().Error());
160  else
161  setType(ExprType().None().Varying());
162 
163  return _type;
164  #endif
165 
166 }
167 
169  ExprNode::addChildren(surrogate);
170 
171  ExprType type;
172  for (int i = 0; i < numChildren(); i++) _argTypes.push_back(child(i)->type());
173 }
174 
176  ExprNode::addChildren(surrogate);
177 #if 0
178  ExprNode * child;
179  ExprType type;
180  for(int i = 0; i < numChildren(); i++) {
181  child = this->child(i);
182  type = child->type();
183 
184  _argTypes.push_back(type);
185  _env.add(((ExprVarNode*)child)->name(), new ExprLocalVar(type));
186  }
187 #endif
188 }
189 
191  #if 0 // TODO: no local functions for now
192  bool error = false;
193 
194  // prep prototype and check for errors
196  ExprVarEnv functionEnv;
197  functionEnv.resetAndSetParent(&env);
198  if (!prototype->prep(false, functionEnv).isValid()) error = true;
199 
200  // decide what return type we want
201  bool returnWantsScalar = false;
202  if (!error && prototype->isReturnTypeSet()) returnWantsScalar = prototype->returnType().isFP(1);
203 
204  // prep block and check for errors
205  ExprNode* block = child(1);
206  ExprType blockType = block->prep(returnWantsScalar, functionEnv);
207 
208  if (!error && blockType.isValid()) {
209  if (prototype->isReturnTypeSet()) {
210  if (blockType != prototype->returnType()) {
211  checkCondition(false,
212  "In function result of block '" + blockType.toString() +
213  "' does not match given return type " + prototype->returnType().toString(),
214  error);
215  }
216 
217  } else
218  prototype->setReturnType(blockType);
219  // register the function in the symbol table
220 
221  env.addFunction(prototype->name(), this);
222  } else {
223  checkCondition(false, "Invalid type for blockType is " + blockType.toString(), error);
224  error = true;
225  }
226  return _type = error ? ExprType().Error() : ExprType().None().Varying();
227  #else
228  bool error=false;
229  checkCondition(false,"Local functions are currently not supported.",error);
230  return ExprType().Error();
231  #endif
232 }
233 
234 // TODO: write buildInterpreter for local function node
235 ExprType ExprLocalFunctionNode::prep(ExprFuncNode* callerNode, bool scalarWanted, ExprVarEnvBuilder& envBuilder) const {
236 #if 0
237  bool error = false;
238  callerNode->checkCondition(callerNode->numChildren() == prototype()->numChildren(),
239  "Incorrect number of arguments to function call",
240  error);
241  for (int i = 0; i < callerNode->numChildren(); i++) {
242  // TODO: is this right?
243  // bool compatible=ExprType::valuesCompatible(callerNode->child(i)->prep(false,env), prototype()->argType(i));
244  if (!callerNode->checkArg(i, prototype()->argType(i), envBuilder)) error = true;
245  // callerNode->child(i)->checkCondition(compatible,"Incorrect type for argument",error);
246  }
247  return error ? ExprType().Error() : prototype()->returnType();
248 #else
249  bool error=false;
250  callerNode->checkCondition(false,"Local functions are currently not supported.",error);
251  return ExprType().Error();
252 #endif
253 }
254 
255 ExprType ExprBlockNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
256  ExprType assignType = child(0)->prep(false, envBuilder);
257  ExprType resultType = child(1)->prep(wantScalar, envBuilder);
258 
259  if (!assignType.isValid())
260  setType(ExprType().Error());
261  else
262  setType(resultType);
263 
264  return _type;
265 }
266 
267 ExprType ExprIfThenElseNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
268  ExprType condType, thenType, elseType;
269 
270  bool error = false;
271 
272  condType = child(0)->prep(true, envBuilder);
273  checkIsFP(condType, error);
274 
275  ExprVarEnv* parentEnv=envBuilder.current();
276  ExprVarEnv* thenEnv=envBuilder.createDescendant(parentEnv);
277  ExprVarEnv* elseEnv=envBuilder.createDescendant(parentEnv);
278  envBuilder.setCurrent(thenEnv);
279  thenType = child(1)->prep(false, envBuilder);
280  thenEnv=envBuilder.current();
281  envBuilder.setCurrent(elseEnv);
282  elseType = child(2)->prep(false, envBuilder);
283  elseEnv=envBuilder.current();
284 
285  if (!error && thenType.isValid() && elseType.isValid()) {
286  ExprVarEnv* newEnv=envBuilder.createDescendant(parentEnv);
287  _varEnvMergeIndex=newEnv->mergeBranches(condType, *thenEnv, *elseEnv);
288  envBuilder.setCurrent(newEnv);
289  // TODO: aselle insert the phi nodes!
290  } else{
291  envBuilder.setCurrent(parentEnv); // since the conditionals broke don't include them in new environment
292  error = true;
293  }
294  _varEnv=envBuilder.current();
295 
296 
297  if (error)
298  setType(ExprType().Error());
299  else
300  setType(ExprType().None().setLifetime(condType, thenType, elseType));
301 
302  return _type;
303 }
304 
305 ExprType ExprAssignNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
306  _assignedType = child(0)->prep(false, envBuilder);
307 
308  std::unique_ptr<ExprLocalVar> localVar(new ExprLocalVar(child(0)->type()));
309  _localVar = localVar.get();
310  envBuilder.current()->add(_name, std::move(localVar));
311  bool error = false;
313  _assignedType.isValid(), std::string("Assignment operation has bad type: ") + _type.toString(), error);
314 
315  if (error)
316  setType(ExprType().Error());
317  else
318  setTypeWithChildLife(ExprType().None());
319  return _type;
320 }
321 
322 ExprType ExprVecNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
323  bool error = false;
324 
325  int max_child_d = 0;
326  for (int c = 0; c < numChildren(); c++) {
327  ExprType childType = child(c)->prep(true, envBuilder);
328  // TODO: add way to tell what element of vector has the type mismatch
329  checkIsFP(childType, error);
330  max_child_d = std::max(max_child_d, childType.dim());
331  }
332 
333  if (error)
334  setType(ExprType().Error());
335  else
337  return _type;
338 }
339 
341  if (const ExprNumNode* f = dynamic_cast<const ExprNumNode*>(child(0))) {
342  double first = f->value();
343  if (const ExprNumNode* s = dynamic_cast<const ExprNumNode*>(child(1))) {
344  double second = s->value();
345  if (const ExprNumNode* t = dynamic_cast<const ExprNumNode*>(child(2))) {
346  double third = t->value();
347  return Vec3d(first, second, third);
348  };
349  };
350  };
351 
352  return Vec3d(0.0);
353 };
354 
355 ExprType ExprUnaryOpNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
356  bool error = false;
357 
358  // TODO: aselle may want to implicitly demote to FP[1] if wantScalar is true!
359  ExprType childType = child(0)->prep(wantScalar, envBuilder);
360  checkIsFP(childType, error);
361  if (error)
362  setType(ExprType().Error());
363  else
364  setType(childType);
365  return _type;
366 }
367 
368 ExprType ExprCondNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
369  // TODO: determine if extra environments are necessary, currently not included
370  ExprType condType, thenType, elseType;
371 
372  bool error = false;
373 
374  condType = child(0)->prep(true, envBuilder);
375 
376  checkIsFP(condType, error);
377 
378  thenType = child(1)->prep(wantScalar, envBuilder);
379  elseType = child(2)->prep(wantScalar, envBuilder);
380 
381  checkIsValue(thenType, error);
382  checkIsValue(elseType, error);
383  checkCondition(ExprType::valuesCompatible(thenType, elseType), "Types of conditional are not compatible", error);
384 
385  if (error)
386  setType(ExprType().Error());
387  else {
388  if (thenType.isString())
389  setType(thenType);
390  else
391  setType(thenType.isFP(1) ? elseType : thenType);
392  _type.setLifetime(condType, thenType, elseType);
393  }
394 
395  return _type;
396 }
397 
398 ExprType ExprSubscriptNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
399  // TODO: double-check order of evaluation - order MAY effect environment evaluation (probably not, though)
400  ExprType vecType, scriptType;
401 
402  bool error = false;
403 
404  vecType = child(0)->prep(false, envBuilder); // want scalar is false because we aren't just doing foo[0]
405  checkIsFP(vecType, error);
406 
407  scriptType = child(1)->prep(true, envBuilder);
408  checkIsFP(scriptType, error);
409 
410  if (error)
411  setType(ExprType().Error());
412  else
413  setType(ExprType().FP(1).setLifetime(vecType, scriptType));
414 
415  return _type;
416 }
417 
418 ExprType ExprCompareEqNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
419  // TODO: double-check order of evaluation - order MAY effect environment evaluation (probably not, though)
420  ExprType firstType, secondType;
421 
422  bool error = false;
423 
424  firstType = child(0)->prep(false, envBuilder);
425  checkIsValue(firstType, error);
426  secondType = child(1)->prep(false, envBuilder);
427  checkIsValue(secondType, error);
428 
429  if (firstType.isValid() && secondType.isValid()) checkTypesCompatible(firstType, secondType, error);
430 
431  if (error)
432  setType(ExprType().Error());
433  else
434  setType(ExprType().FP(1).setLifetime(firstType, secondType));
435 
436  return _type;
437 }
438 
439 ExprType ExprCompareNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
440  // TODO: assume we want scalar
441  // TODO: double-check order of evaluation - order MAY effect environment evaluation (probably not, though)
442  ExprType firstType, secondType;
443 
444  bool error = false;
445 
446  firstType = child(0)->prep(true, envBuilder);
447  checkIsFP(firstType, error);
448  secondType = child(1)->prep(true, envBuilder);
449  checkIsFP(secondType, error);
450 
451  if (firstType.isValid() && secondType.isValid()) checkTypesCompatible(firstType, secondType, error);
452 
453  if (error)
454  setType(ExprType().Error());
455  else
456  setType(ExprType().FP(1).setLifetime(firstType, secondType));
457 
458  return _type;
459 }
460 
461 ExprType ExprBinaryOpNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
462  // TODO: aselle this probably should set the type to be FP1 if wantScalar is true!
463  // TODO: double-check order of evaluation - order MAY effect environment evaluation (probably not, though)
464  ExprType firstType, secondType;
465 
466  bool error = false;
467 
468  firstType = child(0)->prep(false, envBuilder);
469  checkIsFP(firstType, error);
470  secondType = child(1)->prep(false, envBuilder);
471  checkIsFP(secondType, error);
472  checkTypesCompatible(firstType, secondType, error);
473 
474  if (error)
475  setType(ExprType().Error());
476  else
477  setType((firstType.isFP(1) ? secondType : firstType).setLifetime(firstType, secondType));
478 
479  return _type;
480 }
481 
482 ExprType ExprVarNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
483  // ask expression to resolve var
484  bool error = false;
485  if ((_localVar = envBuilder.current()->find(name()))) {
486  if(_localVar->type().isError()){
488  if(ExprLocalVarPhi* phi=dynamic_cast<ExprLocalVarPhi*>(_localVar)){
489  if(!phi->_thenVar->type().isError() && !phi->_elseVar->type().isError()){
490  addError(std::string("Variable ")+name()+" defined in conditionals inconsistently.");
491  }
492  }
493  }
494  setType(_localVar->type());
495  return _type;
496  } else {
497  // user defined external variable
498  _var = _expr->resolveVar(name());
499  if (!_var) {
500  if (const VarBlockCreator* creator = _expr->varBlockCreator()) {
501  // data block defined external var
502  _var = creator->resolveVar(name());
503  }
504  }
505  if (_var) {
506  _expr->addVar(name()); // register used variable so _expr->usedVar() works
507  setType(_var->type());
508  return _type;
509  }
510  }
511  // If we get here we do not have a variable!
512  checkCondition(_var || _localVar, std::string("No variable named ''") + name() + "'", error);
513  setType(ExprType().Error());
514  return _type;
515 }
516 
517 ExprType ExprNumNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
518  _type = ExprType().FP(1).Constant();
519  return _type;
520 }
521 
522 ExprType ExprStrNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
523  _type = ExprType().String().Constant();
524  return _type;
525 }
526 
527 ExprType ExprFuncNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
528  bool error = false;
529 
530  int nargs = numChildren();
531  _promote.resize(nargs, 0);
532 
533  // find function using per-expression callback and then global table
534  // TODO: put lookup of local functions here
535  _func = 0;
536  if (ExprLocalFunctionNode* localFunction = envBuilder.current()->findFunction(_name)) {
537  _localFunc = localFunction;
538  setTypeWithChildLife(localFunction->prep(this, wantScalar, envBuilder));
539  // TODO: we need to type check arguments here
540  } else {
541  if (!_func) _func = _expr->resolveFunc(_name);
543 
544  // check that function exists and that the function has the right number of arguments
545  if (checkCondition(_func, "Function " + _name + " has no definition", error) &&
546  checkCondition(nargs >= _func->minArgs(), "Too few args for function" + _name, error) &&
548  nargs <= _func->maxArgs() || _func->maxArgs() < 0, "Too many args for function " + _name, error)) {
549 
550  const ExprFuncX* funcx = _func->funcx();
551  ExprType type = funcx->prep(this, wantScalar, envBuilder);
552  setTypeWithChildLife(type);
553  } else { // didn't match num args or function not found
554  ExprNode::prep(false, envBuilder); // prep arguments anyways to catch as many errors as possible!
555  setTypeWithChildLife(ExprType().Error());
556  }
557  }
558 
559  return _type;
560 }
561 
563  if (_localFunc)
564  return _localFunc->buildInterpreterForCall(this, interpreter);
565  else if (_func)
566  return _func->funcx()->buildInterpreter(this, interpreter);
567 
568  assert(false);
569  return 0;
570 }
571 
572 bool ExprFuncNode::checkArg(int arg, ExprType type, ExprVarEnvBuilder& envBuilder) {
573  ExprType childType = child(arg)->prep(type.isFP(1), envBuilder);
574  _promote[arg] = 0;
575  if (ExprType::valuesCompatible(type, childType) && type.isLifeCompatible(childType)) {
576  if (type.isFP() && type.dim() > childType.dim()) {
577  _promote[arg] = type.dim();
578  }
579  return true;
580  }
581  child(arg)->addError("Expected " + type.toString() + " for argument, got " + childType.toString());
582  return false;
583 }
584 }
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Preps the definition of this site.
Definition: ExprNode.cpp:190
const ExprType & type() const
The type of the node.
Definition: ExprNode.h:145
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:267
Vec3d value() const
Definition: ExprNode.cpp:340
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:527
void addError(const std::string &error) const
Register error. This will allow users and sophisticated editors to highlight where in code problem wa...
Definition: ExprNode.h:168
int dim() const
Definition: ExprType.h:160
ExprType & Varying()
Mutate this into a varying lifetime.
Definition: ExprType.h:122
const char * name() const
Definition: ExprNode.h:472
virtual ExprVarRef * resolveVar(const std::string &name) const
Definition: Expression.h:199
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:137
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:255
virtual int buildInterpreter(const ExprFuncNode *node, Interpreter *interpreter) const =0
Build an interpreter to evaluate the expression.
void setReturnType(const ExprType &type)
Definition: ExprNode.h:268
</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
const ExprFuncX * funcx() const
return pointer to the funcx
Definition: ExprFunc.h:125
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:368
std::string _name
Definition: ExprNode.h:588
void addChildren(ExprNode *surrogate)
Transfer children from surrogate parent (for parser use only)
Definition: ExprNode.cpp:93
void addArgs(ExprNode *surrogate)
Definition: ExprNode.cpp:175
int maxArgs() const
return the maximum number of acceptable arguments
Definition: ExprFunc.h:123
ExprVarRef * _var
Definition: ExprNode.h:479
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:418
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:164
Node that references a variable.
Definition: ExprNode.h:462
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:517
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:125
ExprType type() const
returns type of the variable
Definition: ExprEnv.h:51
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:439
bool isString() const
Definition: ExprType.h:169
ExprType & String()
Mutate this into a string type.
Definition: ExprType.h:96
Node that contains local function.
Definition: ExprNode.h:307
const ExprLocalVar * localVar() const
Definition: ExprNode.h:370
std::string toString() const
Stringify the type into a printable string.
Definition: ExprType.h:191
std::vector< ExprType > _argTypes
Definition: ExprNode.h:300
bool checkIsValue(const ExprType &type, bool &error)
Checks if the type is a value (i.e. string or float[d])
Definition: ExprNode.h:198
void add(const std::string &name, std::unique_ptr< ExprLocalVar > var)
Add a variable refernece.
Definition: ExprEnv.cpp:73
std::vector< int > _promote
Definition: ExprNode.h:594
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
ExprVarEnv * createDescendant(ExprVarEnv *parent)
Create a descendant scope from the provided parent, does not clobber current.
Definition: ExprEnv.h:169
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:102
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)
Definition: varblocks.txt:35
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:322
size_t mergeBranches(const ExprType &type, ExprVarEnv &env1, ExprVarEnv &env2)
Add all variables into scope by name, but modify their lifetimes to the given type&#39;s lifetime...
Definition: ExprEnv.cpp:83
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:482
const Expression * _expr
Owning expression (node can&#39;t modify)
Definition: ExprNode.h:225
virtual ~ExprNode()
Definition: ExprNode.cpp:82
ExprType & setLifetime(const ExprType &a)
Assign the lifetime from type a to be my type.
Definition: ExprType.h:136
double max(double x, double y)
Definition: ExprBuiltins.h:42
ExprLocalVar reference, all local variables in seexpr are subclasses of this or this itself...
Definition: ExprEnv.h:38
Node that calls a function.
Definition: ExprNode.h:514
Variable scope for tracking variable lookup.
Definition: ExprEnv.h:97
const ExprLocalVar * getPhi() const
get the primary representative phi node (i.e. the global parent of a dependent phi node) ...
Definition: ExprEnv.h:49
static const ExprFunc * lookup(const std::string &name)
Lookup a builtin function by name.
Definition: ExprFunc.cpp:121
A class that lets you register for the variables used by one or more expressions. ...
Definition: VarBlock.h:71
void addArgTypes(ExprNode *surrogate)
Definition: ExprNode.cpp:168
Vec< double, 3, false > Vec3d
Definition: Vec.h:368
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
Definition: ExprNode.cpp:562
bool checkArg(int argIndex, ExprType type, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:572
Between a and b
Definition: userdoc.txt:180
void addVar(const char *n) const
add local variable (this is for internal use)
Definition: Expression.h:318
main expression class
Definition: Expression.h:76
const ExprLocalFunctionNode * _localFunc
Definition: ExprNode.h:590
void setType(const ExprType &t)
Set type of parameter.
Definition: ExprNode.h:172
const std::string & name() const
Definition: ExprNode.h:288
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:355
ExprType & Constant()
Mutate this into a constant lifetime.
Definition: ExprType.h:112
static bool valuesCompatible(const ExprType &a, const ExprType &b)
Checks if value types are compatible.
Definition: ExprType.h:173
virtual ExprType prep(ExprFuncNode *node, bool scalarWanted, ExprVarEnvBuilder &env) const =0
void setTypeWithChildLife(const ExprType &t)
Set&#39;s the type to the argument but uses the children to determine lifetime.
Definition: ExprNode.h:176
ExprNode * _parent
Parent node (null if this the the root)
Definition: ExprNode.h:228
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:522
int numChildren() const
Number of children.
Definition: ExprNode.h:114
ExprLocalVar * _localVar
Definition: ExprNode.h:374
ExprLocalVar * find(const std::string &name)
Find a variable name by name (recursive to parents)
Definition: ExprEnv.cpp:31
void addChild(ExprNode *child)
Add a child to the child list (for parser use only)
Definition: ExprNode.cpp:88
ExprNode(const Expression *expr)
Definition: ExprNode.cpp:39
bool isValid() const
Definition: ExprType.h:167
const VarBlockCreator * varBlockCreator() const
Definition: Expression.h:231
Node that stores a numeric constant.
Definition: ExprNode.h:483
ExprLocalVar * _localVar
Definition: ExprNode.h:478
bool checkIsFP(const ExprType &type, bool &error)
Checks if the type is a float[d] for any d.
Definition: ExprNode.h:202
ExprLocalFunctionNode * findFunction(const std::string &name)
Find a function by name (recursive to parents)
Definition: ExprEnv.cpp:41
int buildInterpreterForCall(const ExprFuncNode *callerNode, Interpreter *interpreter) const
Build interpreter if we are called.
ExprVarEnv * current()
Return the current variable scope.
Definition: ExprEnv.h:165
bool checkTypesCompatible(const ExprType &first, const ExprType &second, bool &error)
types match (true if they do)
Definition: ExprNode.h:215
bool isReturnTypeSet() const
Definition: ExprNode.h:273
bool isError() const
Definition: ExprType.h:168
void resetAndSetParent(ExprVarEnv *parent)
Resets the scope (deletes all variables) and sets parent.
Definition: ExprEnv.cpp:27
ExprLocalVar join (merge) references. Remembers which variables are possible assigners to this...
Definition: ExprEnv.h:68
Node that contains prototype of function.
Definition: ExprNode.h:255
ExprType returnType() const
Definition: ExprNode.h:277
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:117
virtual ExprFunc * resolveFunc(const std::string &name) const
Definition: Expression.h:202
virtual ExprType type() const
returns (current) type
Definition: Expression.h:59
bool isLifeCompatible(const ExprType &o) const
Definition: ExprType.h:188
const ExprFunc * _func
Definition: ExprNode.h:589
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:461
Extension function spec, used for complicated argument custom functions.
Definition: ExprFuncX.h:35
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition: ExprType.h:90
int minArgs() const
return the minimum number of acceptable arguments
Definition: ExprFunc.h:121
ExprType _type
Definition: ExprNode.h:237
ExprType & None()
Mutate this into a none type.
Definition: ExprType.h:84
Defined as a *alpha b *alpha< br ></div >< br > float< b > float a
Definition: userdoc.txt:174
void setCurrent(ExprVarEnv *env)
Set a new current variable scope.
Definition: ExprEnv.h:167
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:102
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:398
std::vector< ExprNode * > _children
List of children.
Definition: ExprNode.h:231
const ExprPrototypeNode * prototype() const
TODO: Accessor for prototype (probably not needed when we use prep right)
Definition: ExprNode.h:317
virtual ExprType prep(bool wantScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:305
</pre > there might be errors in the expression you must check with isValid() before you can evaluate.Then you can print a parse error as well< pre > if(!expr.isValid())
Definition: tutorial.txt:177
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:152