SeExpr

Expression.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 #ifndef MAKEDEPEND
18 #include <iostream>
19 #include <math.h>
20 #include <stack>
21 #include <algorithm>
22 #include <sstream>
23 #endif
24
25 #include "ExprConfig.h"
26 #include "ExprNode.h"
27 #include "ExprParser.h"
28 #include "ExprFunc.h"
29 #include "Expression.h"
30 #include "ExprType.h"
31 #include "ExprEnv.h"
32 #include "Platform.h"
33
34 #include "Evaluator.h"
35 #include "ExprWalker.h"
36
37 #include <cstdio>
38 #include <typeinfo>
39
40 namespace SeExpr2 {
41
42 // Get debugging flag from environment
43 bool Expression::debugging = getenv("SE_EXPR_DEBUG") != 0;
44 // Choose the defeault strategy based on what we've compiled with (SEEXPR_ENABLE_LLVM)
45 // And the environment variables SE_EXPR_DEBUG
46 static Expression::EvaluationStrategy chooseDefaultEvaluationStrategy() {
47 if (Expression::debugging) {
48 std::cerr << "SeExpr2 Debug Mode Enabled " <<
49 #if defined(WINDOWS)
50 _MSC_FULL_VER
51 #else
52 __VERSION__
53 #endif
54 << std::endl;
55 }
56 #ifdef SEEXPR_ENABLE_LLVM
57 if (char* env = getenv("SE_EXPR_EVAL")) {
58 if (Expression::debugging) std::cerr << "Overriding SeExpr Evaluation Default to be " << env << std::endl;
59 return !strcmp(env, "LLVM") ? Expression::UseLLVM : !strcmp(env, "INTERPRETER") ? Expression::UseInterpreter
60 : Expression::UseInterpreter;
61 } else
62 return Expression::UseLLVM;
63 #else
64 return Expression::UseInterpreter;
65 #endif
66 }
67 Expression::EvaluationStrategy Expression::defaultEvaluationStrategy = chooseDefaultEvaluationStrategy();
68
69 class TypePrintExaminer : public SeExpr2::Examiner<true> {
70 public:
71 virtual bool examine(const SeExpr2::ExprNode* examinee);
72 virtual void reset() {};
73 };
74
75 bool TypePrintExaminer::examine(const ExprNode* examinee) {
76 const ExprNode* curr = examinee;
77 int depth = 0;
78 char buf[1024];
79 while (curr != 0) {
80 depth++;
81 curr = curr->parent();
82 }
83 sprintf(buf, "%*s", depth * 2, " ");
84 std::cout << buf << "'" << examinee->toString() << "' " << typeid(*examinee).name()
85 << " type=" << examinee->type().toString() << std::endl;
86
87 return true;
88 };
89
90 Expression::Expression(Expression::EvaluationStrategy evaluationStrategy)
91 : _wantVec(true), _expression(""), _evaluationStrategy(evaluationStrategy), _context(&Context::global()),
92 _desiredReturnType(ExprType().FP(3).Varying()), _parseTree(0), _isValid(0), _parsed(0), _prepped(0),
93 _interpreter(0), _llvmEvaluator(new LLVMEvaluator()) {
94 ExprFunc::init();
95 }
96
97 Expression::Expression(const std::string& e,
98 const ExprType& type,
99 EvaluationStrategy evaluationStrategy,
100 const Context& context)
101 : _wantVec(true), _expression(e), _evaluationStrategy(evaluationStrategy), _context(&context),
102 _desiredReturnType(type), _parseTree(0), _isValid(0), _parsed(0), _prepped(0), _interpreter(0),
103 _llvmEvaluator(new LLVMEvaluator()) {
104 ExprFunc::init();
105 }
106
107 Expression::~Expression() {
108 reset();
109 delete _llvmEvaluator;
110 }
111
112 void Expression::debugPrintInterpreter() const {
113 if (_interpreter) {
114 _interpreter->print();
115 std::cerr << "return slot " << _returnSlot << std::endl;
116 }
117 }
118
119 void Expression::debugPrintLLVM() const { _llvmEvaluator->debugPrint(); }
120
121 void Expression::debugPrintParseTree() const {
122 if (_parseTree) {
123 // print the parse tree
124 std::cerr << "Parse tree desired type " << _desiredReturnType.toString() << " actual "
125 << _parseTree->type().toString() << std::endl;
126 TypePrintExaminer _examiner;
127 SeExpr2::ConstWalker _walker(&_examiner);
128 _walker.walk(_parseTree);
129 }
130 }
131
132 void Expression::reset() {
133 delete _llvmEvaluator;
134 _llvmEvaluator = new LLVMEvaluator();
135 delete _parseTree;
136 _parseTree = 0;
137 if (_evaluationStrategy == UseInterpreter) {
138 delete _interpreter;
139 _interpreter = 0;
140 }
141 _isValid = 0;
142 _parsed = 0;
143 _prepped = 0;
144 _parseError = "";
145 _vars.clear();
146 _funcs.clear();
147 //_localVars.clear();
148 _errors.clear();
149 _envBuilder.reset();
150 _threadUnsafeFunctionCalls.clear();
151 _comments.clear();
152 }
153
154 void Expression::setContext(const Context& context) {
155 reset();
156 _context = &context;
157 }
158
159 void Expression::setDesiredReturnType(const ExprType& type) {
160 reset();
161 _desiredReturnType = type;
162 }
163
164 void Expression::setVarBlockCreator(const VarBlockCreator* creator) {
165 reset();
166 _varBlockCreator = creator;
167 }
168
169 void Expression::setExpr(const std::string& e) {
170 if (_expression != "") reset();
171 _expression = e;
172 }
173
174 bool Expression::syntaxOK() const {
175 parseIfNeeded();
176 return _isValid;
177 }
178
179 bool Expression::isConstant() const {
180 parseIfNeeded();
181 return returnType().isLifetimeConstant();
182 }
183
184 bool Expression::usesVar(const std::string& name) const {
185 parseIfNeeded();
186 return _vars.find(name) != _vars.end();
187 }
188
189 bool Expression::usesFunc(const std::string& name) const {
190 parseIfNeeded();
191 return _funcs.find(name) != _funcs.end();
192 }
193
194 void Expression::parse() const {
195 if (_parsed) return;
196 _parsed = true;
197 int tempStartPos, tempEndPos;
198 ExprParse(_parseTree, _parseError, tempStartPos, tempEndPos, _comments, this, _expression.c_str(), _wantVec);
199 if (!_parseTree) {
200 addError(_parseError, tempStartPos, tempEndPos);
201 }
202 }
203
204 void Expression::prep() const {
205 if (_prepped) return;
206 #ifdef SEEXPR_PERFORMANCE
207 PrintTiming timer("[ PREP ] v2 prep time: ");
208 #endif
209 _prepped = true;
210 parseIfNeeded();
211
212 bool error = false;
213
214 if (!_parseTree) {
215 // parse error
216 error = true;
217 } else if (!_parseTree->prep(_desiredReturnType.isFP(1), _envBuilder).isValid()) {
218 // prep error
219 error = true;
220 } else if (!ExprType::valuesCompatible(_parseTree->type(), _desiredReturnType)) {
221 // incompatible type error
222 error = true;
223 _parseTree->addError("Expression generated type " + _parseTree->type().toString() +
224 " incompatible with desired type " + _desiredReturnType.toString());
225 } else {
226 _isValid = true;
227
228 if (_evaluationStrategy == UseInterpreter) {
229 if (debugging) {
230 debugPrintParseTree();
231 std::cerr << "Eval strategy is interpreter" << std::endl;
232 }
233 assert(!_interpreter);
234 _interpreter = new Interpreter;
235 _returnSlot = _parseTree->buildInterpreter(_interpreter);
236 if (_desiredReturnType.isFP()) {
237 int dimWanted = _desiredReturnType.dim();
238 int dimHave = _parseTree->type().dim();
239 if (dimWanted > dimHave) {
240 _interpreter->addOp(getTemplatizedOp<Promote>(dimWanted));
241 int finalOp = _interpreter->allocFP(dimWanted);
242 _interpreter->addOperand(_returnSlot);
243 _interpreter->addOperand(finalOp);
244 _returnSlot = finalOp;
245 _interpreter->endOp();
246 }
247 }
248 if (debugging) _interpreter->print();
249 } else { // useLLVM
250 if (debugging) {
251 std::cerr << "Eval strategy is llvm" << std::endl;
252 debugPrintParseTree();
253 }
254 if (!_llvmEvaluator->prepLLVM(_parseTree, _desiredReturnType)) {
255 error = true;
256 }
257 }
258
259 // TODO: need promote
260 _returnType = _parseTree->type();
261 }
262
263 if (error) {
264 _isValid = false;
265 _returnType = ExprType().Error();
266
267 // build line lookup table
268 std::vector<int> lines;
269 const char* start = _expression.c_str();
270 const char* p = _expression.c_str();
271 while (*p != 0) {
272 if (*p == '\n') lines.push_back(static_cast<int>(p - start));
273 p++;
274 }
275 lines.push_back(static_cast<int>(p - start));
276
277 std::stringstream sstream;
278 for (unsigned int i = 0; i < _errors.size(); i++) {
279 int* bound = std::lower_bound(&*lines.begin(), &*lines.end(), _errors[i].startPos);
280 int line = static_cast<int>(bound - &*lines.begin() + 1);
281 int lineStart = line == 1 ? 0 : lines[line - 1];
282 int col = _errors[i].startPos - lineStart;
283 sstream << " Line " << line << " Col " << col << " - " << _errors[i].error << std::endl;
284 }
285 _parseError = std::string(sstream.str());
286 }
287
288 if (debugging) {
289 std::cerr << "ending with isValid " << _isValid << std::endl;
290 std::cerr << "parse error \n" << parseError() << std::endl;
291 }
292 }
293
294 bool Expression::isVec() const {
295 prepIfNeeded();
296 return _isValid ? _parseTree->isVec() : _wantVec;
297 }
298
299 const ExprType& Expression::returnType() const {
300 prepIfNeeded();
301 return _returnType;
302 }
303
304 const double* Expression::evalFP(VarBlock* varBlock) const {
305 prepIfNeeded();
306 if (_isValid) {
307 if (_evaluationStrategy == UseInterpreter) {
308 _interpreter->eval(varBlock);
309 return (varBlock && varBlock->threadSafe) ? &(varBlock->d[_returnSlot]) : &_interpreter->d[_returnSlot];
310 } else { // useLLVM
311 return _llvmEvaluator->evalFP(varBlock);
312 }
313 }
314 static double noCrash[16] = {};
315 return noCrash;
316 }
317
318 void Expression::evalMultiple(VarBlock* varBlock, int outputVarBlockOffset, size_t rangeStart, size_t rangeEnd) const {
319 prepIfNeeded();
320 if (_isValid) {
321 if (_evaluationStrategy == UseInterpreter) {
322 // TODO: need strings to work
323 int dim = _desiredReturnType.dim();
324 // double* iHack=reinterpret_cast<double**>(varBlock->data())[outputVarBlockOffset];
325 double* destBase = reinterpret_cast<double**>(varBlock->data())[outputVarBlockOffset];
326 for (size_t i = rangeStart; i < rangeEnd; i++) {
327 varBlock->indirectIndex = static_cast<int>(i);
328 const double* f = evalFP(varBlock);
329 for (int k = 0; k < dim; k++) {
330 destBase[dim * i + k] = f[k];
331 }
332 }
333 } else { // useLLVM
334 _llvmEvaluator->evalMultiple(varBlock, outputVarBlockOffset, rangeStart, rangeEnd);
335 }
336 }
337 }
338
339 const char* Expression::evalStr(VarBlock* varBlock) const {
340 prepIfNeeded();
341 if (_isValid) {
342 if (_evaluationStrategy == UseInterpreter) {
343 _interpreter->eval(varBlock);
344 return (varBlock && varBlock->threadSafe) ? varBlock->s[_returnSlot] : _interpreter->s[_returnSlot];
345 } else { // useLLVM
346 return _llvmEvaluator->evalStr(varBlock);
347 }
348 }
349 return 0;
350 }
351
352 } // end namespace SeExpr2/
SeExpr2::Expression::debugPrintInterpreter
void debugPrintInterpreter() const
Definition: Expression.cpp:112
SeExpr2::Expression::usesVar
bool usesVar(const std::string &name) const
Definition: Expression.cpp:184
SeExpr2::Expression::debugging
static bool debugging
Whether to debug expressions.
Definition: Expression.h:86
SeExpr2::Expression::context
const Context & context() const
Definition: Expression.h:216
SeExpr2::Expression::_threadUnsafeFunctionCalls
std::vector< std::string > _threadUnsafeFunctionCalls
Definition: Expression.h:303
SeExpr2::Expression::isValid
bool isValid() const
Definition: Expression.h:133
SeExpr2::Expression::parseError
const std::string & parseError() const
Definition: Expression.h:140
SeExpr2::LLVMEvaluator::evalFP
const double * evalFP(VarBlock *varBlock)
Definition: Evaluator.h:395
SeExpr2::Interpreter::eval
void eval(VarBlock *varBlock, bool debug=false)
Evaluate program.
Definition: Interpreter.cpp:31
SeExpr2::Expression::_parseTree
ExprNode * _parseTree
Definition: Expression.h:271
SeExpr2::Expression::parseIfNeeded
void parseIfNeeded() const
Definition: Expression.h:242
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::Expression::setVarBlockCreator
void setVarBlockCreator(const VarBlockCreator *varBlockCreator)
Definition: Expression.cpp:164
SeExpr2::Interpreter::endOp
void endOp(bool execute=true)
Definition: Interpreter.h:83
SeExpr2::VarBlock
A thread local evaluation context. Just allocate and fill in with data.
Definition: VarBlock.h:33
SeExpr2::Expression::UseInterpreter
Definition: Expression.h:80
SeExpr2::ExprNode::type
const ExprType & type() const
The type of the node.
Definition: ExprNode.h:145
SeExpr2::Interpreter::addOp
int addOp(OpF op)
! adds an operator to the program (pointing to the data at the current location)
Definition: Interpreter.h:73
SeExpr2::Expression::evalMultiple
void evalMultiple(VarBlock *varBlock, int outputVarBlockOffset, size_t rangeStart, size_t rangeEnd) const
Evaluate multiple blocks.
Definition: Expression.cpp:318
SeExpr2::Expression::_prepped
bool _prepped
Definition: Expression.h:282
SeExpr2::Expression::reset
void reset()
Definition: Expression.cpp:132
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::LLVMEvaluator::debugPrint
void debugPrint()
Definition: Evaluator.h:406
SeExpr2::LLVMEvaluator::evalMultiple
void evalMultiple(VarBlock *varBlock, int outputVarBlockOffset, size_t rangeStart, size_t rangeEnd)
Definition: Evaluator.h:403
SeExpr2::Interpreter::d
std::vector< double > d
Double data (constants and evaluated)
Definition: Interpreter.h:43
SeExpr2::VarBlockCreator
A class that lets you register for the variables used by one or more expressions.
Definition: VarBlock.h:84
SeExpr2::Expression::_comments
std::vector< std::pair< int, int > > _comments
Definition: Expression.h:291
SeExpr2::ExprNode
Definition: ExprNode.h:72
SeExpr2::PrintTiming
Definition: Platform.h:150
SeExpr2::Expression::evalStr
const char * evalStr(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:339
SeExpr2::Expression::setExpr
void setExpr(const std::string &e)
Definition: Expression.cpp:169
SeExpr2::ExprFunc::init
static void init()
call to define built-in funcs and load standard plugins
Definition: ExprFunc.cpp:112
SeExpr2::Expression::_vars
std::set< std::string > _vars
Definition: Expression.h:294
SeExpr2::Expression::_expression
std::string _expression
Definition: Expression.h:257
SeExpr2::Expression::debugPrintParseTree
void debugPrintParseTree() const
Definition: Expression.cpp:121
SeExpr2::Expression::_wantVec
bool _wantVec
Definition: Expression.h:251
SeExpr2::Expression::_isValid
bool _isValid
Definition: Expression.h:280
SeExpr2::ExprNode::toString
std::string toString() const
Access to original string representation of current expression.
Definition: ExprNode.h:105
SeExpr2::Expression::_returnSlot
int _returnSlot
Definition: Expression.h:307
SeExpr2::ExprParse
bool ExprParse(SeExpr2::ExprNode *&parseTree, std::string &error, int &errorStart, int &errorEnd, std::vector< std::pair< int, int > > &_comments, const SeExpr2::Expression *expr, const char *str, bool wantVec=true)
ExprParser.h
SeExpr2::ExprType::dim
int dim() const
Definition: ExprType.h:160
ExprFunc.h
SeExpr2::ExprType
Definition: ExprType.h:39
SeExpr2::VarBlock::d
std::vector< double > d
copy of Interpreter's double data
Definition: VarBlock.h:68
SeExpr2::Context
Definition: Context.h:24
Platform.h
Platform-specific classes, functions, and includes.
SeExpr2::ExprNode::isVec
bool isVec() const
True if node has a vector result.
Definition: ExprNode.h:99
SeExpr2::Expression::_desiredReturnType
ExprType _desiredReturnType
Definition: Expression.h:266
SeExpr2::Examiner
Definition: ExprWalker.h:33
SeExpr2::TypePrintExaminer::examine
virtual bool examine(const SeExpr2::ExprNode *examinee)
Definition: Expression.cpp:75
SeExpr2::Expression::prepIfNeeded
void prepIfNeeded() const
Definition: Expression.h:274
SeExpr2::Expression::Expression
Expression(EvaluationStrategy be=Expression::defaultEvaluationStrategy)
Definition: Expression.cpp:90
SeExpr2
Definition: Context.h:22
SeExpr2::ExprVarEnvBuilder::reset
void reset()
Reset to factory state (one empty environment that is current)
Definition: ExprEnv.h:153
Evaluator.h
SeExpr2::ExprType::isLifetimeConstant
bool isLifetimeConstant() const
validity check: type is not an error
Definition: ExprType.h:183
ExprType.h
SeExpr2::Expression::_errors
std::vector< Error > _errors
Definition: Expression.h:288
ExprNode.h
SeExpr2::Expression::isConstant
bool isConstant() const
Definition: Expression.cpp:179
SeExpr2::Expression::_evaluationStrategy
EvaluationStrategy _evaluationStrategy
Definition: Expression.h:259
ExprWalker.h
SeExpr2::Expression::_funcs
std::set< std::string > _funcs
Definition: Expression.h:297
SeExpr2::Expression::setContext
void setContext(const Context &context)
Definition: Expression.cpp:154
SeExpr2::ExprNode::buildInterpreter
virtual int buildInterpreter(Interpreter *interpreter) const
builds an interpreter. Returns the location index for the evaluated data
Definition: Interpreter.cpp:538
SeExpr2::Expression::parse
void parse() const
Definition: Expression.cpp:194
SeExpr2::ExprNode::parent
const ExprNode * parent() const
Access parent node - root node has no parent.
Definition: ExprNode.h:112
SeExpr2::LLVMEvaluator::prepLLVM
bool prepLLVM(ExprNode *parseTree, ExprType desiredReturnType)
Definition: Evaluator.h:399
SeExpr2::ExprType::Error
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:102
SeExpr2::Interpreter::allocFP
int allocFP(int n)
! Allocate a floating point set of data of dimension n
Definition: Interpreter.h:104
SeExpr2::Expression::~Expression
virtual ~Expression()
Definition: Expression.cpp:107
SeExpr2::Walker
Definition: ExprWalker.h:43
SeExpr2::ExprType::isFP
bool isFP() const
Direct is predicate checks.
Definition: ExprType.h:164
SeExpr2::TypePrintExaminer
Definition: Expression.cpp:69
SeExpr2::VarBlock::indirectIndex
int indirectIndex
indirect index to add to pointer based data
Definition: VarBlock.h:62
SeExpr2::Interpreter::s
std::vector< char * > s
constant and evaluated pointer data
Definition: Interpreter.h:45
SeExpr2::Expression::_parseError
std::string _parseError
Definition: Expression.h:285
ExprEnv.h
SeExpr2::ExprNode::prep
virtual ExprType prep(bool dontNeedScalar, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:104
SeExpr2::ExprType::toString
std::string toString() const
Stringify the type into a printable string.
Definition: ExprType.h:191
SeExpr2::Expression::_parsed
bool _parsed
Definition: Expression.h:282
SeExpr2::Expression::returnType
const ExprType & returnType() const
Definition: Expression.cpp:299
SeExpr2::Expression::_envBuilder
ExprVarEnvBuilder _envBuilder
Definition: Expression.h:269
SeExpr2::Expression::_interpreter
Interpreter * _interpreter
Definition: Expression.h:306
SeExpr2::chooseDefaultEvaluationStrategy
static Expression::EvaluationStrategy chooseDefaultEvaluationStrategy()
Definition: Expression.cpp:46
SeExpr2::Expression::setDesiredReturnType
void setDesiredReturnType(const ExprType &type)
Definition: Expression.cpp:159
SeExpr2::Expression::EvaluationStrategy
EvaluationStrategy
Types of evaluation strategies that are available.
Definition: Expression.h:79
SeExpr2::VarBlock::threadSafe
bool threadSafe
if true, interpreter's data will be copied to this instance before evaluation.
Definition: VarBlock.h:65
SeExpr2::LLVMEvaluator
Definition: Evaluator.h:388
SeExpr2::Expression::defaultEvaluationStrategy
static EvaluationStrategy defaultEvaluationStrategy
What evaluation strategy to use by default.
Definition: Expression.h:84
SeExpr2::Expression::_context
const Context * _context
Definition: Expression.h:262
SeExpr2::Expression::_llvmEvaluator
LLVMEvaluator * _llvmEvaluator
Definition: Expression.h:310
p
static const int p[514]
Definition: NoiseTables.h:20
SeExpr2::ExprType::valuesCompatible
static bool valuesCompatible(const ExprType &a, const ExprType &b)
Checks if value types are compatible.
Definition: ExprType.h:173
SeExpr2::Expression::evalFP
const double * evalFP(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:304
SeExpr2::Expression::_returnType
ExprType _returnType
Definition: Expression.h:254
SeExpr2::VarBlock::s
std::vector< char * > s
copy of Interpreter's str data
Definition: VarBlock.h:71
SeExpr2::Expression::addError
void addError(const std::string &error, const int startPos, const int endPos) const
Definition: Expression.h:205
SeExpr2::VarBlock::data
char ** data()
Raw data of the data block pointer (used by compiler)
Definition: VarBlock.h:74
SeExpr2::Expression::_varBlockCreator
const VarBlockCreator * _varBlockCreator
Definition: Expression.h:313
SeExpr2::Expression::prep
void prep() const
Definition: Expression.cpp:204
context
If a scalar is used in a vector context
Definition: userdoc.txt:436
SeExpr2::TypePrintExaminer::reset
virtual void reset()
Definition: Expression.cpp:72
SeExpr2::Expression::syntaxOK
bool syntaxOK() const
Definition: Expression.cpp:174
Expression.h
SeExpr2::Interpreter
Definition: Interpreter.h:40
SeExpr2::LLVMEvaluator::evalStr
const char * evalStr(VarBlock *varBlock)
Definition: Evaluator.h:391
SeExpr2::Expression::debugPrintLLVM
void debugPrintLLVM() const
Definition: Expression.cpp:119
SeExpr2::Expression::UseLLVM
Definition: Expression.h:81
SeExpr2::Interpreter::print
void print(int pc=-1) const
Debug by printing program.
Definition: Interpreter.cpp:69
SeExpr2::Interpreter::addOperand
int addOperand(int param)
! Adds an operand. Note this should be done after doing the addOp!
Definition: Interpreter.h:96
SeExpr2::Expression::usesFunc
bool usesFunc(const std::string &name) const
Definition: Expression.cpp:189
SeExpr2::Walker::walk
void walk(T_NODE *examinee)
Preorder walk.
Definition: ExprWalker.cpp:30
SeExpr2::Expression::isVec
bool isVec() const
Definition: Expression.cpp:294