|
1 #ifndef BOTC_EXPRESSION_H |
|
2 #define BOTC_EXPRESSION_H |
|
3 #include "parser.h" |
|
4 |
|
5 class DataBuffer; |
|
6 class ExpressionSymbol; |
|
7 class ExpressionValue; |
|
8 class ExpressionOperator; |
|
9 |
|
10 // ============================================================================= |
|
11 // |
|
12 named_enum ExpressionOperatorType |
|
13 { |
|
14 OPER_NegateLogical, |
|
15 OPER_UnaryMinus, |
|
16 OPER_Multiplication, |
|
17 OPER_Division, |
|
18 OPER_Modulus, |
|
19 OPER_Addition, |
|
20 OPER_Subtraction, |
|
21 OPER_LeftShift, |
|
22 OPER_RightShift, |
|
23 OPER_CompareLesser, |
|
24 OPER_CompareGreater, |
|
25 OPER_CompareAtLeast, |
|
26 OPER_CompareAtMost, |
|
27 OPER_CompareEquals, |
|
28 OPER_CompareNotEquals, |
|
29 OPER_BitwiseAnd, |
|
30 OPER_BitwiseXOr, |
|
31 OPER_BitwiseOr, |
|
32 OPER_LogicalAnd, |
|
33 OPER_LogicalOr, |
|
34 OPER_Ternary, |
|
35 }; |
|
36 |
|
37 // ============================================================================= |
|
38 // |
|
39 enum ExpressionSymbolType |
|
40 { |
|
41 EXPRSYM_Operator, |
|
42 EXPRSYM_Value, |
|
43 EXPRSYM_Colon, |
|
44 }; |
|
45 |
|
46 class Expression final |
|
47 { |
|
48 public: |
|
49 using SymbolList = List<ExpressionSymbol*>; |
|
50 |
|
51 Expression (BotscriptParser* parser, Lexer* lx, DataType reqtype); |
|
52 ~Expression(); |
|
53 ExpressionValue* getResult(); |
|
54 |
|
55 private: |
|
56 BotscriptParser* m_parser; |
|
57 Lexer* m_lexer; |
|
58 SymbolList m_symbols; |
|
59 DataType m_type; |
|
60 String m_badTokenText; |
|
61 |
|
62 ExpressionValue* evaluate(); // Process the expression and yield a result |
|
63 ExpressionSymbol* parseSymbol(); |
|
64 String getTokenString(); |
|
65 void adjustOperators(); |
|
66 void verify(); // Ensure the expr is valid |
|
67 void tryVerifyValue (bool* verified, SymbolList::Iterator it); |
|
68 ExpressionValue* evaluateOperator (const ExpressionOperator* op, |
|
69 const List<ExpressionValue*>& values); |
|
70 SymbolList::Iterator findPrioritizedOperator(); |
|
71 }; |
|
72 |
|
73 // ============================================================================= |
|
74 // |
|
75 class ExpressionSymbol |
|
76 { |
|
77 public: |
|
78 ExpressionSymbol (ExpressionSymbolType type) : |
|
79 m_type (type) {} |
|
80 |
|
81 PROPERTY (private, ExpressionSymbolType, type, setType, STOCK_WRITE) |
|
82 }; |
|
83 |
|
84 // ============================================================================= |
|
85 // |
|
86 class ExpressionOperator final : public ExpressionSymbol |
|
87 { |
|
88 PROPERTY (public, ExpressionOperatorType, id, setID, STOCK_WRITE) |
|
89 |
|
90 public: |
|
91 ExpressionOperator (ExpressionOperatorType id); |
|
92 }; |
|
93 |
|
94 // ============================================================================= |
|
95 // |
|
96 class ExpressionValue final : public ExpressionSymbol |
|
97 { |
|
98 PROPERTY (public, int, value, setValue, STOCK_WRITE) |
|
99 PROPERTY (public, DataBuffer*, buffer, setBuffer, STOCK_WRITE) |
|
100 PROPERTY (public, DataType, valueType, setValueType, STOCK_WRITE) |
|
101 |
|
102 public: |
|
103 ExpressionValue (DataType valuetype); |
|
104 ~ExpressionValue(); |
|
105 |
|
106 void convertToBuffer(); |
|
107 |
|
108 inline ExpressionValue* clone() const |
|
109 { |
|
110 return new ExpressionValue (*this); |
|
111 } |
|
112 |
|
113 inline bool isConstexpr() const |
|
114 { |
|
115 return buffer() == null; |
|
116 } |
|
117 }; |
|
118 |
|
119 // ============================================================================= |
|
120 // |
|
121 // This class represents a ":" in the expression. It serves as the colon for the |
|
122 // ternary ?: OPER_erator. It's not an OPER_erand nor is an OPER_erator, nor can we just |
|
123 // skip it so it is its own thing here. |
|
124 // |
|
125 class ExpressionColon final : public ExpressionSymbol |
|
126 { |
|
127 public: |
|
128 ExpressionColon() : |
|
129 ExpressionSymbol (EXPRSYM_Colon) {} |
|
130 }; |
|
131 |
|
132 #endif // BOTC_EXPRESSION_H |