267 // |
267 // |
268 void Expression::AdjustOperators() |
268 void Expression::AdjustOperators() |
269 { |
269 { |
270 for (auto it = mSymbols.begin() + 1; it != mSymbols.end(); ++it) |
270 for (auto it = mSymbols.begin() + 1; it != mSymbols.end(); ++it) |
271 { |
271 { |
272 if ((*it)->GetType() != ExpressionSymbol::eOperatorSymbol) |
272 if ((*it)->GetType() != eOperatorSymbol) |
273 continue; |
273 continue; |
274 |
274 |
275 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); |
275 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); |
276 |
276 |
277 // Unary minus with a value as the previous symbol cannot really be |
277 // Unary minus with a value as the previous symbol cannot really be |
278 // unary; replace with binary minus. |
278 // unary; replace with binary minus. |
279 if (op->GetID() == opUnaryMinus && (*(it - 1))->GetType() == ExpressionSymbol::eValueSymbol) |
279 if (op->GetID() == opUnaryMinus && (*(it - 1))->GetType() == eValueSymbol) |
280 { |
280 { |
281 Print ("Changing symbol operator #%1 from %2 to %3\n", |
281 Print ("Changing symbol operator #%1 from %2 to %3\n", |
282 it - mSymbols.begin(), op->GetID(), opSubtraction); |
282 it - mSymbols.begin(), op->GetID(), opSubtraction); |
283 op->SetID (opSubtraction); |
283 op->SetID (opSubtraction); |
284 } |
284 } |
285 } |
285 } |
286 } |
286 } |
287 |
287 |
288 // ============================================================================= |
288 // ============================================================================= |
289 // |
289 // |
|
290 // Verifies a single value. Helper function for Expression::Verify. |
|
291 // |
|
292 void Expression::TryVerifyValue (bool* verified, SymbolList::Iterator it) |
|
293 { |
|
294 int i = it - mSymbols.begin(); |
|
295 |
|
296 // Ensure it's an actual value |
|
297 if ((*it)->GetType() != eValueSymbol) |
|
298 Error ("malformed expression (symbol #%1 is not a value)", i); |
|
299 |
|
300 verified[i] = true; |
|
301 } |
|
302 |
|
303 // ============================================================================= |
|
304 // |
|
305 // Ensures the expression is valid and well-formed and not OMGWTFBBQ. Throws an |
|
306 // error if this is not the case. |
|
307 // |
|
308 void Expression::Verify() |
|
309 { |
|
310 if (mSymbols.Size() == 1) |
|
311 { |
|
312 if (mSymbols[0]->GetType() != eValueSymbol) |
|
313 Error ("bad expression"); |
|
314 |
|
315 Print ("Expression speedy-verified (1 expr symbol)"); |
|
316 return; |
|
317 } |
|
318 |
|
319 bool* verified = new bool[mSymbols.Size()]; |
|
320 memset (verified, 0, mSymbols.Size() * sizeof (decltype (*verified))); |
|
321 const auto last = mSymbols.end() - 1; |
|
322 const auto first = mSymbols.begin(); |
|
323 |
|
324 for (auto it = mSymbols.begin(); it != mSymbols.end(); ++it) |
|
325 { |
|
326 int i = (it - first); |
|
327 |
|
328 if ((*it)->GetType() != eOperatorSymbol) |
|
329 continue; |
|
330 |
|
331 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); |
|
332 int numoperands = gOperators[op->GetID()].numoperands; |
|
333 |
|
334 switch (numoperands) |
|
335 { |
|
336 case 1: |
|
337 { |
|
338 // Ensure that: |
|
339 // - unary operator is not the last symbol |
|
340 // - unary operator is succeeded by a value symbol |
|
341 // - neither symbol overlaps with something already verified |
|
342 TryVerifyValue (verified, it + 1); |
|
343 |
|
344 if (it == last || verified[i] == true) |
|
345 Error ("malformed expression"); |
|
346 |
|
347 verified[i] = true; |
|
348 break; |
|
349 } |
|
350 |
|
351 case 2: |
|
352 { |
|
353 // Ensure that: |
|
354 // - binary operator is not the first or last symbol |
|
355 // - is preceded and succeeded by values |
|
356 // - none of the three tokens are already verified |
|
357 // |
|
358 // Basically similar logic as above. |
|
359 if (it == first || it == last || verified[i] == true) |
|
360 Error ("malformed expression"); |
|
361 |
|
362 TryVerifyValue (verified, it + 1); |
|
363 TryVerifyValue (verified, it - 1); |
|
364 verified[i] = true; |
|
365 break; |
|
366 } |
|
367 |
|
368 case 3: |
|
369 { |
|
370 // Ternary operator case. This goes a bit nuts. |
|
371 // This time we have the following: |
|
372 // |
|
373 // (VALUE) ? (VALUE) : (VALUE) |
|
374 // ^ |
|
375 // --------/ we are here |
|
376 // |
|
377 // Check that the: |
|
378 // - questionmark operator is not misplaced (first or last) |
|
379 // - the value behind the operator (-1) is valid |
|
380 // - the value after the operator (+1) is valid |
|
381 // - the value after the colon (+3) is valid |
|
382 // - none of the five tokens are verified |
|
383 // |
|
384 TryVerifyValue (verified, it - 1); |
|
385 TryVerifyValue (verified, it + 1); |
|
386 TryVerifyValue (verified, it + 3); |
|
387 |
|
388 if (it == first || |
|
389 it >= mSymbols.end() - 3 || |
|
390 verified[i] == true || |
|
391 verified[i + 2] == true || |
|
392 (*(it + 2))->GetType() != eColonSymbol) |
|
393 { |
|
394 Error ("malformed expression"); |
|
395 } |
|
396 |
|
397 verified[i] = true; |
|
398 verified[i + 2] = true; |
|
399 break; |
|
400 } |
|
401 |
|
402 default: |
|
403 Error ("WTF operator with %1 operands", numoperands); |
|
404 } |
|
405 } |
|
406 |
|
407 for (int i = 0; i < mSymbols.Size(); ++i) |
|
408 if (verified[i] == false) |
|
409 Error ("malformed expression: expr symbol #%1 is was left unverified", i); |
|
410 |
|
411 Print ("Expression verified.\n"); |
|
412 } |
|
413 |
|
414 // ============================================================================= |
|
415 // |
290 ExpressionValue* Expression::Evaluate() |
416 ExpressionValue* Expression::Evaluate() |
291 { |
417 { |
292 |
418 |
293 } |
419 } |
294 |
420 |
307 } |
433 } |
308 |
434 |
309 // ============================================================================= |
435 // ============================================================================= |
310 // |
436 // |
311 ExpressionOperator::ExpressionOperator (EOperator id) : |
437 ExpressionOperator::ExpressionOperator (EOperator id) : |
312 ExpressionSymbol (eOperatorSymbol), |
438 ExpressionSymbol (Expression::eOperatorSymbol), |
313 mID (id) {} |
439 mID (id) {} |
314 |
440 |
315 // ============================================================================= |
441 // ============================================================================= |
316 // |
442 // |
317 ExpressionValue::ExpressionValue (EType valuetype) : |
443 ExpressionValue::ExpressionValue (EType valuetype) : |
318 ExpressionSymbol (eValueSymbol), |
444 ExpressionSymbol (Expression::eValueSymbol), |
319 mBuffer (null), |
445 mBuffer (null), |
320 mValueType (valuetype) {} |
446 mValueType (valuetype) {} |
321 |
447 |
322 // ============================================================================= |
448 // ============================================================================= |
323 // |
449 // |