-
Notifications
You must be signed in to change notification settings - Fork 3
/
Formula.h
133 lines (101 loc) · 2.67 KB
/
Formula.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
#pragma once
enum ResultCode : unsigned {
RESULT_CODE_OK,
RESULT_CODE_SYNTAX_ERROR,
RESULT_CODE_MISSING_DEFINITION,
RESULT_CODE_TYPE_ERROR,
};
enum ResultType : unsigned {
RESULT_TYPE_TOKEN,
RESULT_TYPE_SCALAR,
RESULT_TYPE_VECTOR2,
};
struct Result {
Result () {
type = RESULT_TYPE_SCALAR;
payload.num.value = 0;
}
ResultCode code;
ResultType type;
union ResultPayload {
struct NumericPayload {
ValueT value;
ValueT value2;
} num;
struct TextPayload {
unsigned token;
unsigned scope;
} txt;
} payload;
};
struct ListResult {
ResultCode code;
std::vector<ValueT> values;
};
struct IFormulaContext {
virtual ~IFormulaContext() { }
virtual Result ResolveNumber(const IFormulaContext & context, unsigned scope, unsigned token) const = 0;
virtual ListResult ResolveList(const IFormulaContext & context, unsigned scope, unsigned token) const = 0;
virtual bool ResolveToken (unsigned scope, unsigned token, std::string * out) const {
ref(scope);
ref(token);
ref(out);
return false;
}
virtual const IFormulaContext * ResolveContext (unsigned scope) const {
ref(scope);
return const_cast<IFormulaContext *>(this);
}
};
typedef Result (*FTerminalEvaluator)(const IFormulaContext * context, const class Formula & termSource, unsigned * pindex);
class Formula {
public: // Construction
Formula();
Formula (Formula && other);
Formula (const Formula & other);
public: // Assignment
Formula & operator= (Formula && other);
Formula & operator= (const Formula & other);
public: // Enumerations
enum Operator {
OPERATOR_ADD,
OPERATOR_SUBTRACT,
OPERATOR_MULTIPLY,
OPERATOR_DIVIDE,
OPERATOR_ERROR
};
public: // Setup interface
void Push (ValueT literalValue);
void Push (FTerminalEvaluator evaluator);
void Push (Operator op);
void Push (unsigned scope, unsigned token);
public: // Evaluation interface
Result Evaluate (const IFormulaContext * context) const;
Result EvaluateSubexpression (const IFormulaContext * context, unsigned * pindex) const;
bool EvaluateScopedToken (unsigned index, unsigned * outScope, unsigned * outToken) const;
private: // Internal helper structures
struct Term {
enum Type : unsigned {
TERM_TYPE_LITERAL,
TERM_TYPE_EVALUATOR,
TERM_TYPE_OPERATOR,
TERM_TYPE_TOKEN,
} type;
union PayloadUnion {
ValueT literalValue;
FTerminalEvaluator evaluator;
Operator op;
struct ScopedToken {
unsigned scope;
unsigned token;
} scopedToken;
} payload;
};
private: // Internal state
unsigned m_termCount;
Term m_termBuffer[16];
private: // Shared state
static unsigned s_evaluationCounter;
public:
static unsigned GetEvaluationCounter ();
};