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