src/Expression.cc

changeset 108
6409ece8297c
parent 107
55c2bcd8ed5c
child 110
7a7a53f1d51b
equal deleted inserted replaced
107:55c2bcd8ed5c 108:6409ece8297c
5 struct OperatorInfo 5 struct OperatorInfo
6 { 6 {
7 EToken token; 7 EToken token;
8 int priority; 8 int priority;
9 int numoperands; 9 int numoperands;
10 EDataHeader header; 10 DataHeader header;
11 }; 11 };
12 12
13 static const OperatorInfo gOperators[] = 13 static const OperatorInfo gOperators[] =
14 { 14 {
15 { tkExclamationMark, 0, 1, dhNegateLogical, }, 15 { tkExclamationMark, 0, 1, DH_NegateLogical, },
16 { tkMinus, 0, 1, dhUnaryMinus, }, 16 { tkMinus, 0, 1, DH_UnaryMinus, },
17 { tkMultiply, 10, 2, dhMultiply, }, 17 { tkMultiply, 10, 2, DH_Multiply, },
18 { tkDivide, 10, 2, dhDivide, }, 18 { tkDivide, 10, 2, DH_Divide, },
19 { tkModulus, 10, 2, dhModulus, }, 19 { tkModulus, 10, 2, DH_Modulus, },
20 { tkPlus, 20, 2, dhAdd, }, 20 { tkPlus, 20, 2, DH_Add, },
21 { tkMinus, 20, 2, dhSubtract, }, 21 { tkMinus, 20, 2, DH_Subtract, },
22 { tkLeftShift, 30, 2, dhLeftShift, }, 22 { tkLeftShift, 30, 2, DH_LeftShift, },
23 { tkRightShift, 30, 2, dhRightShift, }, 23 { tkRightShift, 30, 2, DH_RightShift, },
24 { tkLesser, 40, 2, dhLessThan, }, 24 { tkLesser, 40, 2, DH_LessThan, },
25 { tkGreater, 40, 2, dhGreaterThan, }, 25 { tkGreater, 40, 2, DH_GreaterThan, },
26 { tkAtLeast, 40, 2, dhAtLeast, }, 26 { tkAtLeast, 40, 2, DH_AtLeast, },
27 { tkAtMost, 40, 2, dhAtMost, }, 27 { tkAtMost, 40, 2, DH_AtMost, },
28 { tkEquals, 50, 2, dhEquals }, 28 { tkEquals, 50, 2, DH_Equals },
29 { tkNotEquals, 50, 2, dhNotEquals }, 29 { tkNotEquals, 50, 2, DH_NotEquals },
30 { tkAmperstand, 60, 2, dhAndBitwise }, 30 { tkAmperstand, 60, 2, DH_AndBitwise },
31 { tkCaret, 70, 2, dhEorBitwise }, 31 { tkCaret, 70, 2, DH_EorBitwise },
32 { tkBar, 80, 2, dhOrBitwise }, 32 { tkBar, 80, 2, DH_OrBitwise },
33 { tkDoubleAmperstand, 90, 2, dhAndLogical }, 33 { tkDoubleAmperstand, 90, 2, DH_AndLogical },
34 { tkDoubleBar, 100, 2, dhOrLogical }, 34 { tkDoubleBar, 100, 2, DH_OrLogical },
35 { tkQuestionMark, 110, 3, (EDataHeader) 0 }, 35 { tkQuMARK_stion, 110, 3, (DataHeader) 0 },
36 }; 36 };
37 37
38 // ============================================================================= 38 // =============================================================================
39 // 39 //
40 Expression::Expression (BotscriptParser* parser, Lexer* lx, EType reqtype) : 40 Expression::Expression (BotscriptParser* parser, Lexer* lx, DataType reqtype) :
41 mParser (parser), 41 mParser (parser),
42 mLexer (lx), 42 mLexer (lx),
43 mType (reqtype) 43 mType (reqtype)
44 { 44 {
45 ExpressionSymbol* sym; 45 ExpressionSymbol* sym;
66 delete sym; 66 delete sym;
67 } 67 }
68 68
69 // ============================================================================= 69 // =============================================================================
70 // 70 //
71 // Try to parse an expression symbol (i.e. an operator or operand or a colon) 71 // Try to parse an expression symbol (i.e. an OPER_erator or OPER_erand or a colon)
72 // from the lexer. 72 // from the lexer.
73 // 73 //
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 (tkColon))
80 return new ExpressionColon; 80 return new ExpressionColon;
81 81
82 // Check for operator 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 ((EOperator) (&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 (tkParenStart))
89 { 89 {
90 Expression expr (mParser, mLexer, mType); 90 Expression expr (mParser, mLexer, mType);
97 // Check function 97 // Check function
98 if (CommandInfo* comm = FindCommandByName (mLexer->PeekNextString())) 98 if (CommandInfo* comm = FindCommandByName (mLexer->PeekNextString()))
99 { 99 {
100 mLexer->Skip(); 100 mLexer->Skip();
101 101
102 if (mType != EUnknownType && comm->returnvalue != mType) 102 if (mType != TYPE_Unknown && comm->returnvalue != mType)
103 Error ("%1 returns an incompatible data type", comm->name); 103 Error ("%1 returns an incompatible data type", comm->name);
104 104
105 op->SetBuffer (mParser->ParseCommand (comm)); 105 op->SetBuffer (mParser->ParseCommand (comm));
106 return op; 106 return op;
107 } 107 }
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 (tkBracketStart);
125 Expression expr (mParser, mLexer, EIntType); 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 (dhPushGlobalArray); 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 (tkBracketEnd);
132 } 132 }
133 elif (var->writelevel == Variable::WRITE_Constexpr) 133 elif (var->writelevel == WRITE_Constexpr)
134 op->SetValue (var->value); 134 op->SetValue (var->value);
135 else 135 else
136 { 136 {
137 DataBuffer* buf = new DataBuffer (8); 137 DataBuffer* buf = new DataBuffer (8);
138 138
139 if (var->IsGlobal()) 139 if (var->IsGlobal())
140 buf->WriteDWord (dhPushGlobalVar); 140 buf->WriteDWord (DH_PushGlobalVar);
141 else 141 else
142 buf->WriteDWord (dhPushLocalVar); 142 buf->WriteDWord (DH_PushLocalVar);
143 143
144 buf->WriteDWord (var->index); 144 buf->WriteDWord (var->index);
145 op->SetBuffer (buf); 145 op->SetBuffer (buf);
146 } 146 }
147 147
149 } 149 }
150 150
151 // Check for literal 151 // Check for literal
152 switch (mType) 152 switch (mType)
153 { 153 {
154 case EVoidType: 154 case TYPE_Void:
155 case EUnknownType: 155 case TYPE_Unknown:
156 { 156 {
157 Error ("unknown identifier `%1` (expected keyword, function or variable)", GetTokenString()); 157 Error ("unknown identifier `%1` (expected keyword, function or variable)", GetTokenString());
158 break; 158 break;
159 } 159 }
160 160
161 case EBoolType: 161 case TYPE_Bool:
162 { 162 {
163 if (mLexer->GetNext (tkTrue) || mLexer->GetNext (tkFalse)) 163 if (mLexer->GetNext (tkTrue) || mLexer->GetNext (tkFalse))
164 { 164 {
165 EToken tt = mLexer->GetTokenType(); 165 EToken tt = mLexer->GetTokenType();
166 op->SetValue (tt == tkTrue ? 1 : 0); 166 op->SetValue (tt == tkTrue ? 1 : 0);
167 return op; 167 return op;
168 } 168 }
169 } 169 }
170 170
171 case EIntType: 171 case TYPE_Int:
172 { 172 {
173 if (mLexer->GetNext (tkNumber)) 173 if (mLexer->GetNext (tkNumber))
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 EStringType: 180 case TYPE_String:
181 { 181 {
182 if (mLexer->GetNext (tkString)) 182 if (mLexer->GetNext (tkString))
183 { 183 {
184 op->SetValue (GetStringTableIndex (GetTokenString())); 184 op->SetValue (GetStringTableIndex (GetTokenString()));
185 return op; 185 return op;
193 return null; 193 return null;
194 } 194 }
195 195
196 // ============================================================================= 196 // =============================================================================
197 // 197 //
198 // The symbol parsing process only does token-based checking for operators. Thus 198 // The symbol parsing process only does token-based checking for OPER_erators. Thus
199 // ALL minus operators 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 // tkMinus as their token and the unary minus is prior to the binary minus in
201 // the operator 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 {
206 for (auto it = mSymbols.begin() + 1; it != mSymbols.end(); ++it) 206 for (auto it = mSymbols.begin() + 1; it != mSymbols.end(); ++it)
207 { 207 {
208 if ((*it)->GetType() != eOperatorSymbol) 208 if ((*it)->GetType() != EXPRSYM_Operator)
209 continue; 209 continue;
210 210
211 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); 211 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it);
212 212
213 // Unary minus with a value as the previous symbol cannot really be 213 // Unary minus with a value as the previous symbol cannot really be
214 // unary; replace with binary minus. 214 // unary; replace with binary minus.
215 if (op->GetID() == opUnaryMinus && (*(it - 1))->GetType() == eValueSymbol) 215 if (op->GetID() == OPER_UnaryMinus && (*(it - 1))->GetType() == EXPRSYM_Value)
216 op->SetID (opSubtraction); 216 op->SetID (OPER_Subtraction);
217 } 217 }
218 } 218 }
219 219
220 // ============================================================================= 220 // =============================================================================
221 // 221 //
222 // Verifies a single value. Helper function for Expression::Verify. 222 // Verifies a single value. Helper function for Expression::Verify.
223 // 223 //
224 void Expression::TryVerifyValue (bool* verified, SymbolList::Iterator it) 224 void Expression::TryVerifyValue (bool* verified, SymbolList::Iterator it)
225 { 225 {
226 // If it's an unary operator we skip to its value. The actual operator will 226 // If it's an unary OPER_erator we skip to its value. The actual OPER_erator will
227 // be verified separately. 227 // be verified separately.
228 if ((*it)->GetType() == eOperatorSymbol && 228 if ((*it)->GetType() == EXPRSYM_Operator &&
229 gOperators[static_cast<ExpressionOperator*> (*it)->GetID()].numoperands == 1) 229 gOperators[static_cast<ExpressionOperator*> (*it)->GetID()].numoperands == 1)
230 { 230 {
231 ++it; 231 ++it;
232 } 232 }
233 233
234 int i = it - mSymbols.begin(); 234 int i = it - mSymbols.begin();
235 235
236 // Ensure it's an actual value 236 // Ensure it's an actual value
237 if ((*it)->GetType() != eValueSymbol) 237 if ((*it)->GetType() != EXPRSYM_Value)
238 Error ("malformed expression (symbol #%1 is not a value)", i); 238 Error ("malformed expression (symbol #%1 is not a value)", i);
239 239
240 verified[i] = true; 240 verified[i] = true;
241 } 241 }
242 242
247 // 247 //
248 void Expression::Verify() 248 void Expression::Verify()
249 { 249 {
250 if (mSymbols.Size() == 1) 250 if (mSymbols.Size() == 1)
251 { 251 {
252 if (mSymbols[0]->GetType() != eValueSymbol) 252 if (mSymbols[0]->GetType() != EXPRSYM_Value)
253 Error ("bad expression"); 253 Error ("bad expression");
254 254
255 return; 255 return;
256 } 256 }
257 257
258 if (mType == EStringType) 258 if (mType == TYPE_String)
259 Error ("Cannot perform operations on strings"); 259 Error ("Cannot perform OPER_erations on strings");
260 260
261 bool* verified = new bool[mSymbols.Size()]; 261 bool* verified = new bool[mSymbols.Size()];
262 memset (verified, 0, mSymbols.Size() * sizeof (decltype (*verified))); 262 memset (verified, 0, mSymbols.Size() * sizeof (decltype (*verified)));
263 const auto last = mSymbols.end() - 1; 263 const auto last = mSymbols.end() - 1;
264 const auto first = mSymbols.begin(); 264 const auto first = mSymbols.begin();
265 265
266 for (auto it = mSymbols.begin(); it != mSymbols.end(); ++it) 266 for (auto it = mSymbols.begin(); it != mSymbols.end(); ++it)
267 { 267 {
268 int i = (it - first); 268 int i = (it - first);
269 269
270 if ((*it)->GetType() != eOperatorSymbol) 270 if ((*it)->GetType() != EXPRSYM_Operator)
271 continue; 271 continue;
272 272
273 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); 273 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it);
274 int numoperands = gOperators[op->GetID()].numoperands; 274 int numoperands = gOperators[op->GetID()].numoperands;
275 275
276 switch (numoperands) 276 switch (numoperands)
277 { 277 {
278 case 1: 278 case 1:
279 { 279 {
280 // Ensure that: 280 // Ensure that:
281 // - unary operator is not the last symbol 281 // - unary OPER_erator is not the last symbol
282 // - unary operator is succeeded by a value symbol 282 // - unary OPER_erator is succeeded by a value symbol
283 // - neither symbol overlaps with something already verified 283 // - neither symbol overlaps with something already verified
284 TryVerifyValue (verified, it + 1); 284 TryVerifyValue (verified, it + 1);
285 285
286 if (it == last || verified[i] == true) 286 if (it == last || verified[i] == true)
287 Error ("malformed expression"); 287 Error ("malformed expression");
291 } 291 }
292 292
293 case 2: 293 case 2:
294 { 294 {
295 // Ensure that: 295 // Ensure that:
296 // - binary operator is not the first or last symbol 296 // - binary OPER_erator is not the first or last symbol
297 // - is preceded and succeeded by values 297 // - is preceded and succeeded by values
298 // - none of the three tokens are already verified 298 // - none of the three tokens are already verified
299 // 299 //
300 // Basically similar logic as above. 300 // Basically similar logic as above.
301 if (it == first || it == last || verified[i] == true) 301 if (it == first || it == last || verified[i] == true)
307 break; 307 break;
308 } 308 }
309 309
310 case 3: 310 case 3:
311 { 311 {
312 // Ternary operator case. This goes a bit nuts. 312 // Ternary OPER_erator case. This goes a bit nuts.
313 // This time we have the following: 313 // This time we have the following:
314 // 314 //
315 // (VALUE) ? (VALUE) : (VALUE) 315 // (VALUE) ? (VALUE) : (VALUE)
316 // ^ 316 // ^
317 // --------/ we are here 317 // --------/ we are here
318 // 318 //
319 // Check that the: 319 // Check that the:
320 // - questionmark operator is not misplaced (first or last) 320 // - questionmark OPER_erator is not misplaced (first or last)
321 // - the value behind the operator (-1) is valid 321 // - the value behind the OPER_erator (-1) is valid
322 // - the value after the operator (+1) is valid 322 // - the value after the OPER_erator (+1) is valid
323 // - the value after the colon (+3) is valid 323 // - the value after the colon (+3) is valid
324 // - none of the five tokens are verified 324 // - none of the five tokens are verified
325 // 325 //
326 TryVerifyValue (verified, it - 1); 326 TryVerifyValue (verified, it - 1);
327 TryVerifyValue (verified, it + 1); 327 TryVerifyValue (verified, it + 1);
329 329
330 if (it == first || 330 if (it == first ||
331 it >= mSymbols.end() - 3 || 331 it >= mSymbols.end() - 3 ||
332 verified[i] == true || 332 verified[i] == true ||
333 verified[i + 2] == true || 333 verified[i + 2] == true ||
334 (*(it + 2))->GetType() != eColonSymbol) 334 (*(it + 2))->GetType() != EXPRSYM_Colon)
335 { 335 {
336 Error ("malformed expression"); 336 Error ("malformed expression");
337 } 337 }
338 338
339 verified[i] = true; 339 verified[i] = true;
340 verified[i + 2] = true; 340 verified[i + 2] = true;
341 break; 341 break;
342 } 342 }
343 343
344 default: 344 default:
345 Error ("WTF operator with %1 operands", numoperands); 345 Error ("WTF OPER_erator with %1 OPER_erands", numoperands);
346 } 346 }
347 } 347 }
348 348
349 for (int i = 0; i < mSymbols.Size(); ++i) 349 for (int i = 0; i < mSymbols.Size(); ++i)
350 if (verified[i] == false) 350 if (verified[i] == false)
354 } 354 }
355 355
356 356
357 // ============================================================================= 357 // =============================================================================
358 // 358 //
359 // Which operator to evaluate? 359 // Which OPER_erator to evaluate?
360 // 360 //
361 Expression::SymbolList::Iterator Expression::FindPrioritizedOperator() 361 Expression::SymbolList::Iterator Expression::FindPrioritizedOperator()
362 { 362 {
363 SymbolList::Iterator best = mSymbols.end(); 363 SymbolList::Iterator best = mSymbols.end();
364 int bestpriority = INT_MAX; 364 int bestpriority = INT_MAX;
365 365
366 for (SymbolList::Iterator it = mSymbols.begin(); it != mSymbols.end(); ++it) 366 for (SymbolList::Iterator it = mSymbols.begin(); it != mSymbols.end(); ++it)
367 { 367 {
368 if ((*it)->GetType() != eOperatorSymbol) 368 if ((*it)->GetType() != EXPRSYM_Operator)
369 continue; 369 continue;
370 370
371 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); 371 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it);
372 const OperatorInfo* info = &gOperators[op->GetID()]; 372 const OperatorInfo* info = &gOperators[op->GetID()];
373 373
381 return best; 381 return best;
382 } 382 }
383 383
384 // ============================================================================= 384 // =============================================================================
385 // 385 //
386 // Process the given operator and values into a new value. 386 // Process the given OPER_erator and values into a new value.
387 // 387 //
388 ExpressionValue* Expression::EvaluateOperator (const ExpressionOperator* op, 388 ExpressionValue* Expression::EvaluateOperator (const ExpressionOperator* op,
389 const List<ExpressionValue*>& values) 389 const List<ExpressionValue*>& values)
390 { 390 {
391 const OperatorInfo* info = &gOperators[op->GetID()]; 391 const OperatorInfo* info = &gOperators[op->GetID()];
413 // This is not a constant expression so we'll have to use databuffers 413 // This is not a constant expression so we'll have to use databuffers
414 // to convey the expression to bytecode. Actual value cannot be evaluated 414 // to convey the expression to bytecode. Actual value cannot be evaluated
415 // until Zandronum processes it at run-time. 415 // until Zandronum processes it at run-time.
416 newval->SetBuffer (new DataBuffer); 416 newval->SetBuffer (new DataBuffer);
417 417
418 if (op->GetID() == opTernary) 418 if (op->GetID() == OPER_Ternary)
419 { 419 {
420 // There isn't a dataheader for ternary operator. Instead, we use dhIfNotGoto 420 // There isn't a dataheader for ternary OPER_erator. Instead, we use DH_IfNotGoto
421 // to create an "if-block" inside an expression. 421 // to create an "if-block" inside an expression.
422 // Behold, big block of writing madness! :P 422 // Behold, big block of writing madness! :P
423 // 423 //
424 DataBuffer* buf = newval->GetBuffer(); 424 DataBuffer* buf = newval->GetBuffer();
425 DataBuffer* b0 = values[0]->GetBuffer(); 425 DataBuffer* b0 = values[0]->GetBuffer();
426 DataBuffer* b1 = values[1]->GetBuffer(); 426 DataBuffer* b1 = values[1]->GetBuffer();
427 DataBuffer* b2 = values[2]->GetBuffer(); 427 DataBuffer* b2 = values[2]->GetBuffer();
428 ByteMark* mark1 = buf->AddMark (""); // start of "else" case 428 ByteMark* mark1 = buf->AddMark (""); // start of "else" case
429 ByteMark* mark2 = buf->AddMark (""); // end of expression 429 ByteMark* mark2 = buf->AddMark (""); // end of expression
430 buf->MergeAndDestroy (b0); 430 buf->MergeAndDestroy (b0);
431 buf->WriteDWord (dhIfNotGoto); // if the first operand (condition) 431 buf->WriteDWord (DH_IfNotGoto); // if the first OPER_erand (condition)
432 buf->AddReference (mark1); // didn't eval true, jump into mark1 432 buf->AddReference (mark1); // didn't eval true, jump into mark1
433 buf->MergeAndDestroy (b1); // otherwise, perform second operand (true case) 433 buf->MergeAndDestroy (b1); // otherwise, perform second OPER_erand (true case)
434 buf->WriteDWord (dhGoto); // afterwards, jump to the end, which is 434 buf->WriteDWord (DH_Goto); // afterwards, jump to the end, which is
435 buf->AddReference (mark2); // marked by mark2. 435 buf->AddReference (mark2); // marked by mark2.
436 buf->AdjustMark (mark1); // move mark1 at the end of the true case 436 buf->AdjustMark (mark1); // move mark1 at the end of the true case
437 buf->MergeAndDestroy (b2); // perform third operand (false case) 437 buf->MergeAndDestroy (b2); // perform third OPER_erand (false case)
438 buf->AdjustMark (mark2); // move the ending mark2 here 438 buf->AdjustMark (mark2); // move the ending mark2 here
439 439
440 for (int i = 0; i < 3; ++i) 440 for (int i = 0; i < 3; ++i)
441 values[i]->SetBuffer (null); 441 values[i]->SetBuffer (null);
442 } 442 }
443 else 443 else
444 { 444 {
445 // Generic case: write all arguments and apply the operator's 445 // Generic case: write all arguments and apply the OPER_erator's
446 // data header. 446 // data header.
447 for (ExpressionValue* val : values) 447 for (ExpressionValue* val : values)
448 { 448 {
449 newval->GetBuffer()->MergeAndDestroy (val->GetBuffer()); 449 newval->GetBuffer()->MergeAndDestroy (val->GetBuffer());
450 450
466 for (ExpressionValue* val : values) 466 for (ExpressionValue* val : values)
467 nums << val->GetValue(); 467 nums << val->GetValue();
468 468
469 switch (op->GetID()) 469 switch (op->GetID())
470 { 470 {
471 case opAddition: a = nums[0] + nums[1]; break; 471 case OPER_Addition: a = nums[0] + nums[1]; break;
472 case opSubtraction: a = nums[0] - nums[1]; break; 472 case OPER_Subtraction: a = nums[0] - nums[1]; break;
473 case opMultiplication: a = nums[0] * nums[1]; break; 473 case OPER_Multiplication: a = nums[0] * nums[1]; break;
474 case opUnaryMinus: a = -nums[0]; break; 474 case OPER_UnaryMinus: a = -nums[0]; break;
475 case opNegateLogical: a = !nums[0]; break; 475 case OPER_NegateLogical: a = !nums[0]; break;
476 case opLeftShift: a = nums[0] << nums[1]; break; 476 case OPER_LeftShift: a = nums[0] << nums[1]; break;
477 case opRightShift: a = nums[0] >> nums[1]; break; 477 case OPER_RightShift: a = nums[0] >> nums[1]; break;
478 case opCompareLesser: a = (nums[0] < nums[1]) ? 1 : 0; break; 478 case OPER_CompareLesser: a = (nums[0] < nums[1]) ? 1 : 0; break;
479 case opCompareGreater: a = (nums[0] > nums[1]) ? 1 : 0; break; 479 case OPER_CompareGreater: a = (nums[0] > nums[1]) ? 1 : 0; break;
480 case opCompareAtLeast: a = (nums[0] <= nums[1]) ? 1 : 0; break; 480 case OPER_CompareAtLeast: a = (nums[0] <= nums[1]) ? 1 : 0; break;
481 case opCompareAtMost: a = (nums[0] >= nums[1]) ? 1 : 0; break; 481 case OPER_CompareAtMost: a = (nums[0] >= nums[1]) ? 1 : 0; break;
482 case opCompareEquals: a = (nums[0] == nums[1]) ? 1 : 0; break; 482 case OPER_CompareEquals: a = (nums[0] == nums[1]) ? 1 : 0; break;
483 case opCompareNotEquals: a = (nums[0] != nums[1]) ? 1 : 0; break; 483 case OPER_CompareNotEquals: a = (nums[0] != nums[1]) ? 1 : 0; break;
484 case opBitwiseAnd: a = nums[0] & nums[1]; break; 484 case OPER_BitwiseAnd: a = nums[0] & nums[1]; break;
485 case opBitwiseOr: a = nums[0] | nums[1]; break; 485 case OPER_BitwiseOr: a = nums[0] | nums[1]; break;
486 case opBitwiseXOr: a = nums[0] ^ nums[1]; break; 486 case OPER_BitwiseXOr: a = nums[0] ^ nums[1]; break;
487 case opLogicalAnd: a = (nums[0] && nums[1]) ? 1 : 0; break; 487 case OPER_LogicalAnd: a = (nums[0] && nums[1]) ? 1 : 0; break;
488 case opLogicalOr: a = (nums[0] || nums[1]) ? 1 : 0; break; 488 case OPER_LogicalOr: a = (nums[0] || nums[1]) ? 1 : 0; break;
489 case opTernary: a = (nums[0] != 0) ? nums[1] : nums[2]; break; 489 case OPER_Ternary: a = (nums[0] != 0) ? nums[1] : nums[2]; break;
490 490
491 case opDivision: 491 case OPER_Division:
492 { 492 {
493 if (nums[1] == 0) 493 if (nums[1] == 0)
494 Error ("division by zero in constant expression"); 494 Error ("division by zero in constant expression");
495 495
496 a = nums[0] / nums[1]; 496 a = nums[0] / nums[1];
497 break; 497 break;
498 } 498 }
499 499
500 case opModulus: 500 case OPER_Modulus:
501 { 501 {
502 if (nums[1] == 0) 502 if (nums[1] == 0)
503 Error ("modulus by zero in constant expression"); 503 Error ("modulus by zero in constant expression");
504 504
505 a = nums[0] % nums[1]; 505 a = nums[0] % nums[1];
525 SymbolList::Iterator it; 525 SymbolList::Iterator it;
526 526
527 while ((it = FindPrioritizedOperator()) != mSymbols.end()) 527 while ((it = FindPrioritizedOperator()) != mSymbols.end())
528 { 528 {
529 int i = it - mSymbols.begin(); 529 int i = it - mSymbols.begin();
530 List<SymbolList::Iterator> operands; 530 List<SymbolList::Iterator> OPER_erands;
531 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); 531 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it);
532 const OperatorInfo* info = &gOperators[op->GetID()]; 532 const OperatorInfo* info = &gOperators[op->GetID()];
533 int lower, upper; // Boundaries of area to replace 533 int lower, upper; // Boundaries of area to replace
534 534
535 switch (info->numoperands) 535 switch (info->numoperands)
536 { 536 {
537 case 1: 537 case 1:
538 { 538 {
539 lower = i; 539 lower = i;
540 upper = i + 1; 540 upper = i + 1;
541 operands << it + 1; 541 OPER_erands << it + 1;
542 break; 542 break;
543 } 543 }
544 544
545 case 2: 545 case 2:
546 { 546 {
547 lower = i - 1; 547 lower = i - 1;
548 upper = i + 1; 548 upper = i + 1;
549 operands << it - 1 549 OPER_erands << it - 1
550 << it + 1; 550 << it + 1;
551 break; 551 break;
552 } 552 }
553 553
554 case 3: 554 case 3:
555 { 555 {
556 lower = i - 1; 556 lower = i - 1;
557 upper = i + 3; 557 upper = i + 3;
558 operands << it - 1 558 OPER_erands << it - 1
559 << it + 1 559 << it + 1
560 << it + 3; 560 << it + 3;
561 break; 561 break;
562 } 562 }
563 563
565 assert (false); 565 assert (false);
566 } 566 }
567 567
568 List<ExpressionValue*> values; 568 List<ExpressionValue*> values;
569 569
570 for (auto it : operands) 570 for (auto it : OPER_erands)
571 values << static_cast<ExpressionValue*> (*it); 571 values << static_cast<ExpressionValue*> (*it);
572 572
573 // Note: @op and all of @values are invalid after this call. 573 // Note: @op and all of @values are invalid after this call.
574 ExpressionValue* newvalue = EvaluateOperator (op, values); 574 ExpressionValue* newvalue = EvaluateOperator (op, values);
575 575
577 mSymbols.RemoveAt (i); 577 mSymbols.RemoveAt (i);
578 578
579 mSymbols.Insert (lower, newvalue); 579 mSymbols.Insert (lower, newvalue);
580 } 580 }
581 581
582 assert (mSymbols.Size() == 1 && mSymbols.First()->GetType() == eValueSymbol); 582 assert (mSymbols.Size() == 1 && mSymbols.First()->GetType() == EXPRSYM_Value);
583 ExpressionValue* val = static_cast<ExpressionValue*> (mSymbols.First()); 583 ExpressionValue* val = static_cast<ExpressionValue*> (mSymbols.First());
584 return val; 584 return val;
585 } 585 }
586 586
587 // ============================================================================= 587 // =============================================================================
598 return mLexer->GetToken()->text; 598 return mLexer->GetToken()->text;
599 } 599 }
600 600
601 // ============================================================================= 601 // =============================================================================
602 // 602 //
603 ExpressionOperator::ExpressionOperator (EOperator id) : 603 ExpressionOperator::ExpressionOperator (ExpressionOperatorType id) :
604 ExpressionSymbol (Expression::eOperatorSymbol), 604 ExpressionSymbol (EXPRSYM_Operator),
605 mID (id) {} 605 mID (id) {}
606 606
607 // ============================================================================= 607 // =============================================================================
608 // 608 //
609 ExpressionValue::ExpressionValue (EType valuetype) : 609 ExpressionValue::ExpressionValue (DataType valuetype) :
610 ExpressionSymbol (Expression::eValueSymbol), 610 ExpressionSymbol (EXPRSYM_Value),
611 mBuffer (null), 611 mBuffer (null),
612 mValueType (valuetype) {} 612 mValueType (valuetype) {}
613 613
614 // ============================================================================= 614 // =============================================================================
615 // 615 //
627 627
628 SetBuffer (new DataBuffer); 628 SetBuffer (new DataBuffer);
629 629
630 switch (mValueType) 630 switch (mValueType)
631 { 631 {
632 case EBoolType: 632 case TYPE_Bool:
633 case EIntType: 633 case TYPE_Int:
634 GetBuffer()->WriteDWord (dhPushNumber); 634 GetBuffer()->WriteDWord (DH_PushNumber);
635 GetBuffer()->WriteDWord (abs (mValue)); 635 GetBuffer()->WriteDWord (abs (mValue));
636 636
637 if (mValue < 0) 637 if (mValue < 0)
638 GetBuffer()->WriteDWord (dhUnaryMinus); 638 GetBuffer()->WriteDWord (DH_UnaryMinus);
639 break; 639 break;
640 640
641 case EStringType: 641 case TYPE_String:
642 GetBuffer()->WriteDWord (dhPushStringIndex); 642 GetBuffer()->WriteDWord (DH_PushStringIndex);
643 GetBuffer()->WriteDWord (mValue); 643 GetBuffer()->WriteDWord (mValue);
644 break; 644 break;
645 645
646 case EVoidType: 646 case TYPE_Void:
647 case EUnknownType: 647 case TYPE_Unknown:
648 assert (false); 648 assert (false);
649 break; 649 break;
650 } 650 }
651 } 651 }

mercurial