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
50 ExprNode::ExprNode(const Expression* expr, ExprNode* a, const ExprType& type)
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
62 ExprNode::ExprNode(const Expression* expr, ExprNode* a, ExprNode* b, const ExprType& type)
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
76 ExprNode::ExprNode(const Expression* expr, ExprNode* a, ExprNode* b, ExprNode* c, const ExprType& type)
77 : _expr(expr), _parent(0), _isVec(0), _type(type) {
78 _children.reserve(3);
79 addChild(a);
80 addChild(b);
81 addChild(c);
82 }
83
84 ExprNode::~ExprNode() {
85 // delete children
86 std::vector<ExprNode*>::iterator iter;
87 for (iter = _children.begin(); iter != _children.end(); iter++) delete *iter;
88 }
89
90 void ExprNode::addChild(ExprNode* child) {
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
166 void ExprPrototypeNode::addArgTypes(ExprNode* surrogate) {
167 ExprNode::addChildren(surrogate);
168
169 ExprType type;
170 for (int i = 0; i < numChildren(); i++) _argTypes.push_back(child(i)->type());
171 }
172
173 void ExprPrototypeNode::addArgs(ExprNode* surrogate) {
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
188 ExprType ExprLocalFunctionNode::prep(bool wantScalar, ExprVarEnvBuilder& envBuilder) {
189 bool error = false;
190
191 #if 0 // TODO: no local functions for now
192
193 // prep prototype and check for errors
194 ExprPrototypeNode* prototype = (ExprPrototypeNode*)child(0);
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;
314 checkCondition(
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
338 setTypeWithChildLife(ExprType().FP(numChildren()));
339 return _type;
340 }
341
342 Vec3d ExprVecNode::value() const {
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);
548 if (!_func) _func = ExprFunc::lookup(_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) &&
553 checkCondition(
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);
558 setTypeWithChildLife(type);
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
568 int ExprFuncNode::buildInterpreter(Interpreter* interpreter) const {
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