forked from ChristophKirst/SimKernel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpression.h
423 lines (302 loc) · 13 KB
/
expression.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/***************************************************************************
expression.h - code expressions
Christoph Kirst
Max Planck Institue for Dynamics and Self-Organisation Göttingen
HU Berlin, BCCN Göttingen & Berlin (2008)
****************************************************************************/
#ifndef EXPRESSION_H
#define EXPRESSION_H
#include <typeinfo>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <deque>
#include <map>
#include <assert.h>
//#define EXPR_DEBUG(s1, s2) std::cout << "ExprDebug: " << s1 << " " << s2 << std::endl; std::cout.flush();
#define EXPR_DEBUG(s1, s2)
//#define EXPR_PTR_DEBUG(s1, s2) std::cout << "ExprDebug: " << s1 << " " << s2 << std::endl; std::cout.flush();
#define EXPR_PTR_DEBUG(s1, s2)
class ExpressionError
{
std::string what_;
public:
ExpressionError(const std::string w) : what_(w) {};
std::string what() const
{
return what_;
}
};
#define EXPR_EVAL_ASSERT(cond, err, where) if (!(cond)) { std::ostringstream str; str << "Expression Evaluation Error: " << int(err) << " = " << ExprEvalErrorDescription(err) << "\nError occured in Expression: " << where->print() << std::endl; /*assert(false);*/ throw ExpressionError(str.str()); };
#define EXPR_EVAL_CHECK_SYNTAX() ExprSyntaxErrorT synerr = check_syntax(); if (synerr != NoSyntaxError) { std::ostringstream str; str << "Expression Syntax Error in evaluation: " << int(synerr) << " = " << ExprSyntaxErrorDescription(synerr) << "\nError occured in Expression: " << this->print() << std::endl; /*assert(false);*/ throw ExpressionError(str.str()); };
#define EXPR_MAX_RECURSION 256
#define EXPR_MAX_SCOPELEVEL 512
#define EXPR_NAME_DECL() static const ExprNameT Name; ExprNameT name() const;
#define EXPR_NAME_IMPL(expr, expname) const ExprNameT expr::Name = expname; ExprNameT expr::name() const { return Name; };
#define EXPR_BIOP_DECL(expr, expop, exptempl) typedef exptempl<expop> expr; template <> const ExprNameT expr::Name; template <> const std::string expr::OpSymbol; template<> ExprNameT expr::name() const; template <> const expop expr::op;
#define EXPR_BIOP_IMPL(expr, expop, expname, expsymb) template<> const ExprNameT expr::Name = expname; template<> ExprNameT expr::name() const { return Name; }; template<> const std::string expr::OpSymbol = expsymb; template<> const expop expr::op = expop();
#define EXPR_MATU_DECL(expr, expop, exptempl) typedef exptempl<expop> expr; template <> const ExprNameT expr::Name; template <> const expop expr::op; template<> ExprNameT expr::name() const;
#define EXPR_MATU_IMPL(expr, expop, expname) template<> const ExprNameT expr::Name = expname; template<> ExprNameT expr::name() const { return Name; }; template<> const expop expr::op = expop();
class Expression;
class ExpressionPtr;
class ExpressionScope;
typedef ExpressionScope ExprScopeT;
typedef ExpressionPtr ExprPtrT;
typedef long ExprRefT;
typedef int ExprStatusT;
typedef std::string ExprNameT;
typedef unsigned int ExprIndexT;
typedef std::deque<ExprPtrT> ExprArgT;
typedef ExprArgT::iterator ExprArgIteratorT;
typedef ExprArgT::const_iterator ExprArgConstIteratorT;
enum ExprEvalErrorT
{
NoEvalError = 0,
NonNumberToReal,
NonNumberToIntg,
NonStrgToStrg,
NonBoolToBool,
MaxRecursion,
MaxScope,
EvaluateAtOnAtom,
EvaluateAtIllegalArgs,
ExtractOutOfRange,
InsertOutOfRange,
ReplaceOutOfRange,
ReturnToGlobal,
BreakToGlobal,
DivisionByZero,
// Sim Expressions
IteratorExpectList,
IteratorExpectNumber,
IteratorLoop,
CreatorExpectList,
CreatorExpectNumber,
// extras
RandomToNumber,
RandomSeedNotInteger,
// Kernel
TypeMismatch,
// internal errors -> debugging
EvaluateBase,
RecursionUnderflow,
ScopeUnderflow,
OutOfArgRange,
SymbolNameOnNonSymbol,
EvaluationOnNoMatch,
// internal Sim
IteratorInternalError
};
enum ExprSyntaxErrorT
{ // Syntax errors evoked by check_syntax
NoSyntaxError = 0,
SyntaxError,
IllegalArgumentNumber,
PatternExpectSymbol,
SetExpectSymbol,
SetExpectFunctionOrSymbol,
DefineExpectSymbol,
DefineExpectFunctionOrSymbol,
TableExpectList,
TableExpectSymbol,
FunctionExpectSymbolList,
ModuleExpectSymbolList,
ModuleExpectBlock,
//sim
IteratorExpectSymbol,
IteratorExpectIterationList,
IteratorSyntaxError,
CreatorExpectIterationList,
CreatorExpectSymbol,
CreatorSyntaxError,
};
typedef std::map<ExprEvalErrorT, std::string> ExprEvalErrorDescriptionT;
typedef std::map<ExprSyntaxErrorT, std::string> ExprSyntaxErrorDescriptionT;
std::string ExprEvalErrorDescription(const ExprEvalErrorT& e);
std::string ExprSyntaxErrorDescription(const ExprSyntaxErrorT& e);
/*********************************************************************************
Base Class Expression
**********************************************************************************/
class Expression
{
public:
ExprArgT arg; // argument list
ExprRefT refs; // number of ExpressionPointers to this Expression
ExprStatusT status; // status to detect infinite recursions
public:
//Constructors
Expression();
Expression(const ExprIndexT& n);
Expression(const ExprPtrT& arg1);
Expression(const ExprPtrT& arg1, const ExprPtrT& arg2);
Expression(const ExprPtrT& arg1, const ExprPtrT& arg2, const ExprPtrT& arg3);
Expression(const ExprPtrT& arg1, const ExprPtrT& arg2, const ExprPtrT& arg3, const ExprPtrT& arg4);
virtual ~Expression();
public:
virtual ExprNameT name() const = 0;
virtual ExprIndexT nargs() const;
virtual ExprPtrT evaluate(ExprScopeT* scope);
virtual ExprSyntaxErrorT check_syntax() const;
virtual void append(const ExprPtrT& e);
virtual void prepend(const ExprPtrT& e);
virtual void set(const ExprIndexT& i, const ExprPtrT& e);
virtual void insert(const ExprIndexT& i, const ExprPtrT& e);
virtual void clear();
virtual std::string print() const;
virtual void begin_evaluate();
virtual void end_evaluate();
// Type conversion
virtual bool toTypeQ(const std::type_info& ti) const { return false; };
virtual operator double () const;
virtual operator int () const;
virtual operator std::string () const;
virtual operator bool () const;
// Compare Expressions
virtual bool equalQ(const ExprPtrT& rhs) const;
// Pattern ordering
virtual bool lessPatternQ(const ExprPtrT& rhs) const;
// Pattern matching
virtual bool matchQ(const ExprPtrT& expr) const;
// Scoping Patterns
virtual void protectScopePattern(ExprScopeT* scope) const;
virtual void defineScopePattern(ExprScopeT* scope, const ExprPtrT& expr) const;
// Properties
virtual bool integerQ() const { return false; };
virtual bool realQ() const { return false; };
virtual bool numberQ() const { return false; };
virtual bool stringQ() const { return false; };
virtual bool boolQ() const { return false; };
virtual bool symbolQ() const { return false; };
virtual bool atomQ() const { return false; };
virtual bool listQ() const { return false; };
virtual bool functionQ() const { return false; };
virtual bool evalQ() const { return false; };
virtual bool blockQ() const { return false; };
virtual bool globalQ() const { return false; };
virtual bool allQ() const { return false; };
virtual bool automaticQ() const { return false; };
virtual bool noneQ() const { return false; };
virtual bool sequenceQ() const { return false; };
virtual ExprIndexT depth() const { return 0; };
virtual ExprNameT symbolname() const;
};
/*********************************************************************************
Expression Pointer
**********************************************************************************/
class ExpressionPtr
{
public:
Expression* ptr;
explicit ExpressionPtr();
explicit ExpressionPtr(Expression* e);
~ExpressionPtr();
ExpressionPtr(const ExpressionPtr& r);
Expression* get();
Expression* get() const;
Expression* operator -> ();
Expression* operator -> () const;
Expression& operator * ();
Expression& operator * () const;
ExpressionPtr& operator = (const ExpressionPtr& rhs);
ExpressionPtr& operator = (Expression* e);
// equality of pointers !
bool operator == (const ExpressionPtr& rhs) const;
bool operator == (Expression* rhs) const;
bool operator != (const ExpressionPtr& rhs) const;
// Pattern ordering for ExpressionScope
bool operator < (const ExpressionPtr& rhs) const;
};
/*********************************************************************************
Fundamental Expressions
**********************************************************************************/
class ExprNull : public Expression
{
public:
ExprNull();
public:
EXPR_NAME_DECL()
ExprPtrT evaluate(ExprScopeT* scope);
std::string print() const;
};
class ExprNoPattern : public Expression
{
public:
ExprNoPattern();
public:
EXPR_NAME_DECL()
ExprPtrT evaluate(ExprScopeT* scope);
bool lessPatternQ(const ExprPtrT& rhs) const;
bool matchQ(const ExprPtrT& expr) const;
};
class ExprPattern : public Expression
{
public:
ExprPattern(const ExprPtrT& s);
ExprPtrT evaluate(ExprScopeT* scope);
ExprSyntaxErrorT check_syntax() const;
bool lessPatternQ(const ExprPtrT& rhs) const;
bool matchQ(const ExprPtrT& expr) const;
void protectScopePattern(ExprScopeT* scope) const;
void defineScopePattern(ExprScopeT* scope, const ExprPtrT& expr) const;
ExprNameT symbolname() const;
static const ExprNameT Name;
ExprNameT name() const;
std::string print() const;
};
class ExprNoMatch : public Expression
{
public:
ExprNoMatch();
public:
EXPR_NAME_DECL()
ExprPtrT evaluate(ExprScopeT* scope);
std::string print() const;
};
// Pointer to Global Objects
ExprPtrT ExprNullPtr();
ExprPtrT ExprNoPatternPtr();
ExprPtrT ExprNoMatchPtr();
/*********************************************************************************
Expression Scope
**********************************************************************************/
class ExpressionScope
{
public:
typedef std::map<ExprPtrT, ExprPtrT> PatternDefsT;
typedef PatternDefsT::iterator PatternDefsIter;
typedef std::map<ExprNameT, PatternDefsT> DefsT; // optimize: ternary search tree instead of map!
typedef DefsT::iterator DefsIter;
typedef std::deque< DefsT > DefsStackT;
typedef DefsStackT::iterator DefsStackIter;
typedef unsigned int ScopeLevelT;
public:
DefsStackT defs;
DefsStackIter top_defs;
DefsStackIter global_defs;
ScopeLevelT slevel;
public:
ExpressionScope();
void define(const ExprNameT& name, const ExprPtrT& expression);
void define(const ExprNameT& name, const ExprPtrT& pattern, const ExprPtrT& expression);
void define_local(const ExprNameT& name, const ExprPtrT& expression);
void define_local(const ExprNameT& name, const ExprPtrT& pattern, const ExprPtrT& expression);
ExprPtrT match(const ExprNameT& name) const;
std::pair<ExprPtrT,ExprPtrT> match(const ExprNameT& name, const ExprPtrT& expr) const;
void pop();
void push();
void clear();
ScopeLevelT level() const;
//inspection
bool defined(const ExprNameT& name);
bool defined(const ExprNameT& name, const ExprPtrT& pattern);
std::string print_definitions(DefsStackIter it);
std::string info();
};
/*********************************************************************************
io
**********************************************************************************/
std::ostream& operator<<(std::ostream& os, Expression* e);
std::ostream& operator<<(std::ostream& os, const ExprPtrT& e);
#endif