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