| 109:6572803cd0ca | 110:7a7a53f1d51b |
|---|---|
| 2 #include "DataBuffer.h" | 2 #include "DataBuffer.h" |
| 3 #include "Lexer.h" | 3 #include "Lexer.h" |
| 4 | 4 |
| 5 struct OperatorInfo | 5 struct OperatorInfo |
| 6 { | 6 { |
| 7 EToken token; | 7 TokenType token; |
| 8 int priority; | 8 int priority; |
| 9 int numoperands; | 9 int numoperands; |
| 10 DataHeader header; | 10 DataHeader header; |
| 11 }; | 11 }; |
| 12 | 12 |
| 13 static const OperatorInfo gOperators[] = | 13 static const OperatorInfo gOperators[] = |
| 14 { | 14 { |
| 15 { tkExclamationMark, 0, 1, DH_NegateLogical, }, | 15 {TK_ExclamationMark, 0, 1, DH_NegateLogical, }, |
| 16 { tkMinus, 0, 1, DH_UnaryMinus, }, | 16 {TK_Minus, 0, 1, DH_UnaryMinus, }, |
| 17 { tkMultiply, 10, 2, DH_Multiply, }, | 17 {TK_Multiply, 10, 2, DH_Multiply, }, |
| 18 { tkDivide, 10, 2, DH_Divide, }, | 18 {TK_Divide, 10, 2, DH_Divide, }, |
| 19 { tkModulus, 10, 2, DH_Modulus, }, | 19 {TK_Modulus, 10, 2, DH_Modulus, }, |
| 20 { tkPlus, 20, 2, DH_Add, }, | 20 {TK_Plus, 20, 2, DH_Add, }, |
| 21 { tkMinus, 20, 2, DH_Subtract, }, | 21 {TK_Minus, 20, 2, DH_Subtract, }, |
| 22 { tkLeftShift, 30, 2, DH_LeftShift, }, | 22 {TK_LeftShift, 30, 2, DH_LeftShift, }, |
| 23 { tkRightShift, 30, 2, DH_RightShift, }, | 23 {TK_RightShift, 30, 2, DH_RightShift, }, |
| 24 { tkLesser, 40, 2, DH_LessThan, }, | 24 {TK_Lesser, 40, 2, DH_LessThan, }, |
| 25 { tkGreater, 40, 2, DH_GreaterThan, }, | 25 {TK_Greater, 40, 2, DH_GreaterThan, }, |
| 26 { tkAtLeast, 40, 2, DH_AtLeast, }, | 26 {TK_AtLeast, 40, 2, DH_AtLeast, }, |
| 27 { tkAtMost, 40, 2, DH_AtMost, }, | 27 {TK_AtMost, 40, 2, DH_AtMost, }, |
| 28 { tkEquals, 50, 2, DH_Equals }, | 28 {TK_Equals, 50, 2, DH_Equals }, |
| 29 { tkNotEquals, 50, 2, DH_NotEquals }, | 29 {TK_NotEquals, 50, 2, DH_NotEquals }, |
| 30 { tkAmperstand, 60, 2, DH_AndBitwise }, | 30 {TK_Amperstand, 60, 2, DH_AndBitwise }, |
| 31 { tkCaret, 70, 2, DH_EorBitwise }, | 31 {TK_Caret, 70, 2, DH_EorBitwise }, |
| 32 { tkBar, 80, 2, DH_OrBitwise }, | 32 {TK_Bar, 80, 2, DH_OrBitwise }, |
| 33 { tkDoubleAmperstand, 90, 2, DH_AndLogical }, | 33 {TK_DoubleAmperstand, 90, 2, DH_AndLogical }, |
| 34 { tkDoubleBar, 100, 2, DH_OrLogical }, | 34 {TK_DoubleBar, 100, 2, DH_OrLogical }, |
| 35 { tkQuMARK_stion, 110, 3, (DataHeader) 0 }, | 35 {TK_QuestionMark, 110, 3, (DataHeader) 0 }, |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 // ============================================================================= | 38 // ============================================================================= |
| 39 // | 39 // |
| 40 Expression::Expression (BotscriptParser* parser, Lexer* lx, DataType reqtype) : | 40 Expression::Expression (BotscriptParser* parser, Lexer* lx, DataType reqtype) : |
| 74 ExpressionSymbol* Expression::ParseSymbol() | 74 ExpressionSymbol* Expression::ParseSymbol() |
| 75 { | 75 { |
| 76 int pos = mLexer->GetPosition(); | 76 int pos = mLexer->GetPosition(); |
| 77 ExpressionValue* op = null; | 77 ExpressionValue* op = null; |
| 78 | 78 |
| 79 if (mLexer->GetNext (tkColon)) | 79 if (mLexer->GetNext (TK_Colon)) |
| 80 return new ExpressionColon; | 80 return new ExpressionColon; |
| 81 | 81 |
| 82 // Check for OPER_erator | 82 // Check for OPER_erator |
| 83 for (const OperatorInfo& op : gOperators) | 83 for (const OperatorInfo& op : gOperators) |
| 84 if (mLexer->GetNext (op.token)) | 84 if (mLexer->GetNext (op.token)) |
| 85 return new ExpressionOperator ((ExpressionOperatorType) (&op - &gOperators[0])); | 85 return new ExpressionOperator ((ExpressionOperatorType) (&op - &gOperators[0])); |
| 86 | 86 |
| 87 // Check sub-expression | 87 // Check sub-expression |
| 88 if (mLexer->GetNext (tkParenStart)) | 88 if (mLexer->GetNext (TK_ParenStart)) |
| 89 { | 89 { |
| 90 Expression expr (mParser, mLexer, mType); | 90 Expression expr (mParser, mLexer, mType); |
| 91 mLexer->MustGetNext (tkParenEnd); | 91 mLexer->MustGetNext (TK_ParenEnd); |
| 92 return expr.GetResult()->Clone(); | 92 return expr.GetResult()->Clone(); |
| 93 } | 93 } |
| 94 | 94 |
| 95 op = new ExpressionValue (mType); | 95 op = new ExpressionValue (mType); |
| 96 | 96 |
| 105 op->SetBuffer (mParser->ParseCommand (comm)); | 105 op->SetBuffer (mParser->ParseCommand (comm)); |
| 106 return op; | 106 return op; |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Check for variables | 109 // Check for variables |
| 110 if (mLexer->GetNext (tkDollarSign)) | 110 if (mLexer->GetNext (TK_DollarSign)) |
| 111 { | 111 { |
| 112 mLexer->MustGetNext (tkSymbol); | 112 mLexer->MustGetNext (TK_Symbol); |
| 113 Variable* var = mParser->FindVariable (GetTokenString()); | 113 Variable* var = mParser->FindVariable (GetTokenString()); |
| 114 | 114 |
| 115 if (var == null) | 115 if (var == null) |
| 116 Error ("unknown variable %1", GetTokenString()); | 116 Error ("unknown variable %1", GetTokenString()); |
| 117 | 117 |
| 119 Error ("expression requires %1, variable $%2 is of type %3", | 119 Error ("expression requires %1, variable $%2 is of type %3", |
| 120 GetTypeName (mType), var->name, GetTypeName (var->type)); | 120 GetTypeName (mType), var->name, GetTypeName (var->type)); |
| 121 | 121 |
| 122 if (var->isarray) | 122 if (var->isarray) |
| 123 { | 123 { |
| 124 mLexer->MustGetNext (tkBracketStart); | 124 mLexer->MustGetNext (TK_BracketStart); |
| 125 Expression expr (mParser, mLexer, TYPE_Int); | 125 Expression expr (mParser, mLexer, TYPE_Int); |
| 126 expr.GetResult()->ConvertToBuffer(); | 126 expr.GetResult()->ConvertToBuffer(); |
| 127 DataBuffer* buf = expr.GetResult()->GetBuffer()->Clone(); | 127 DataBuffer* buf = expr.GetResult()->GetBuffer()->Clone(); |
| 128 buf->WriteDWord (DH_PushGlobalArray); | 128 buf->WriteDWord (DH_PushGlobalArray); |
| 129 buf->WriteDWord (var->index); | 129 buf->WriteDWord (var->index); |
| 130 op->SetBuffer (buf); | 130 op->SetBuffer (buf); |
| 131 mLexer->MustGetNext (tkBracketEnd); | 131 mLexer->MustGetNext (TK_BracketEnd); |
| 132 } | 132 } |
| 133 elif (var->writelevel == WRITE_Constexpr) | 133 elif (var->writelevel == WRITE_Constexpr) |
| 134 op->SetValue (var->value); | 134 op->SetValue (var->value); |
| 135 else | 135 else |
| 136 { | 136 { |
| 158 break; | 158 break; |
| 159 } | 159 } |
| 160 | 160 |
| 161 case TYPE_Bool: | 161 case TYPE_Bool: |
| 162 { | 162 { |
| 163 if (mLexer->GetNext (tkTrue) || mLexer->GetNext (tkFalse)) | 163 if (mLexer->GetNext (TK_True) || mLexer->GetNext (TK_False)) |
| 164 { | 164 { |
| 165 EToken tt = mLexer->GetTokenType(); | 165 TokenType tt = mLexer->GetTokenType(); |
| 166 op->SetValue (tt == tkTrue ? 1 : 0); | 166 op->SetValue (tt ==TK_True ? 1 : 0); |
| 167 return op; | 167 return op; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 case TYPE_Int: | 171 case TYPE_Int: |
| 172 { | 172 { |
| 173 if (mLexer->GetNext (tkNumber)) | 173 if (mLexer->GetNext (TK_Number)) |
| 174 { | 174 { |
| 175 op->SetValue (GetTokenString().ToLong()); | 175 op->SetValue (GetTokenString().ToLong()); |
| 176 return op; | 176 return op; |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 | 179 |
| 180 case TYPE_String: | 180 case TYPE_String: |
| 181 { | 181 { |
| 182 if (mLexer->GetNext (tkString)) | 182 if (mLexer->GetNext (TK_String)) |
| 183 { | 183 { |
| 184 op->SetValue (GetStringTableIndex (GetTokenString())); | 184 op->SetValue (GetStringTableIndex (GetTokenString())); |
| 185 return op; | 185 return op; |
| 186 } | 186 } |
| 187 } | 187 } |
| 195 | 195 |
| 196 // ============================================================================= | 196 // ============================================================================= |
| 197 // | 197 // |
| 198 // The symbol parsing process only does token-based checking for OPER_erators. Thus | 198 // The symbol parsing process only does token-based checking for OPER_erators. Thus |
| 199 // ALL minus OPER_erators are actually unary minuses simply because both have | 199 // ALL minus OPER_erators are actually unary minuses simply because both have |
| 200 // tkMinus as their token and the unary minus is prior to the binary minus in | 200 //TK_Minus as their token and the unary minus is prior to the binary minus in |
| 201 // the OPER_erator table. Now that we have all symbols present, we can correct | 201 // the OPER_erator table. Now that we have all symbols present, we can correct |
| 202 // cases like this. | 202 // cases like this. |
| 203 // | 203 // |
| 204 void Expression::AdjustOperators() | 204 void Expression::AdjustOperators() |
| 205 { | 205 { |