src/expression.cpp

changeset 131
8ae8038b0168
parent 125
85814c0918c5
child 132
4d45b1383246
equal deleted inserted replaced
130:885fd60e8bf1 131:8ae8038b0168
66 delete sym; 66 delete sym;
67 } 67 }
68 68
69 // ============================================================================= 69 // =============================================================================
70 // 70 //
71 // Try to parse an expression symbol (i.e. an OPER_erator or OPER_erand or a colon) 71 // Try to parse an expression symbol (i.e. an operator 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 = m_lexer->position(); 76 int pos = m_lexer->position();
77 ExpressionValue* op = null; 77 ExpressionValue* op = null;
78 78
79 if (m_lexer->next (TK_Colon)) 79 if (m_lexer->next (TK_Colon))
80 return new ExpressionColon; 80 return new ExpressionColon;
81 81
82 // Check for OPER_erator 82 // Check for operator
83 for (const OperatorInfo& op : g_Operators) 83 for (const OperatorInfo& op : g_Operators)
84 if (m_lexer->next (op.token)) 84 if (m_lexer->next (op.token))
85 return new ExpressionOperator ((ExpressionOperatorType) (&op - &g_Operators[0])); 85 return new ExpressionOperator ((ExpressionOperatorType) (&op - &g_Operators[0]));
86 86
87 // Check sub-expression 87 // Check sub-expression
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 OPER_erators. 198 // The symbol parsing process only does token-based checking for operators.
199 // Thus ALL minus OPER_erators are actually unary minuses simply because both 199 // Thus ALL minus operators are actually unary minuses simply because both
200 // have TK_Minus as their token and the unary minus is prior to the binary minus 200 // have TK_Minus as their token and the unary minus is prior to the binary minus
201 // in the OPER_erator table. Now that we have all symbols present, we can 201 // in the operator table. Now that we have all symbols present, we can
202 // correct cases like this. 202 // correct cases like this.
203 // 203 //
204 void Expression::adjustOperators() 204 void Expression::adjustOperators()
205 { 205 {
206 for (auto it = m_symbols.begin() + 1; it != m_symbols.end(); ++it) 206 for (auto it = m_symbols.begin() + 1; it != m_symbols.end(); ++it)
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 OPER_erator we skip to its value. The actual OPER_erator will 226 // If it's an unary operator we skip to its value. The actual operator will
227 // be verified separately. 227 // be verified separately.
228 if ((*it)->type() == EXPRSYM_Operator && 228 if ((*it)->type() == EXPRSYM_Operator &&
229 g_Operators[static_cast<ExpressionOperator*> (*it)->id()].numoperands == 1) 229 g_Operators[static_cast<ExpressionOperator*> (*it)->id()].numoperands == 1)
230 { 230 {
231 ++it; 231 ++it;
276 switch (numoperands) 276 switch (numoperands)
277 { 277 {
278 case 1: 278 case 1:
279 { 279 {
280 // Ensure that: 280 // Ensure that:
281 // - unary OPER_erator is not the last symbol 281 // - unary operator is not the last symbol
282 // - unary OPER_erator is succeeded by a value symbol 282 // - unary operator 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 OPER_erator is not the first or last symbol 296 // - binary operator 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 OPER_erator case. This goes a bit nuts. 312 // Ternary operator 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 OPER_erator is not misplaced (first or last) 320 // - questionmark operator is not misplaced (first or last)
321 // - the value behind the OPER_erator (-1) is valid 321 // - the value behind the operator (-1) is valid
322 // - the value after the OPER_erator (+1) is valid 322 // - the value after the operator (+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);
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 OPER_erator with %1 OPER_erands", numoperands); 345 error ("WTF operator with %1 OPER_erands", numoperands);
346 } 346 }
347 } 347 }
348 348
349 for (int i = 0; i < m_symbols.size(); ++i) 349 for (int i = 0; i < m_symbols.size(); ++i)
350 if (verified[i] == false) 350 if (verified[i] == false)
381 return best; 381 return best;
382 } 382 }
383 383
384 // ============================================================================= 384 // =============================================================================
385 // 385 //
386 // Process the given OPER_erator and values into a new value. 386 // Process the given operator 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 = &g_Operators[op->id()]; 391 const OperatorInfo* info = &g_Operators[op->id()];
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->id() == OPER_Ternary) 418 if (op->id() == OPER_Ternary)
419 { 419 {
420 // There isn't a dataheader for ternary OPER_erator. Instead, we use DH_IfNotGoto 420 // There isn't a dataheader for ternary operator. 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->buffer(); 424 DataBuffer* buf = newval->buffer();
425 DataBuffer* b0 = values[0]->buffer(); 425 DataBuffer* b0 = values[0]->buffer();
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 OPER_erator's 445 // Generic case: write all arguments and apply the operator's
446 // data header. 446 // data header.
447 for (ExpressionValue* val : values) 447 for (ExpressionValue* val : values)
448 { 448 {
449 newval->buffer()->mergeAndDestroy (val->buffer()); 449 newval->buffer()->mergeAndDestroy (val->buffer());
450 450

mercurial