src/Expression.cc

changeset 93
11a24b697f43
parent 92
3a00d396bce2
child 94
8915ee6a277d
equal deleted inserted replaced
92:3a00d396bce2 93:11a24b697f43
4 #include "Variables.h" 4 #include "Variables.h"
5 5
6 struct OperatorInfo 6 struct OperatorInfo
7 { 7 {
8 EToken token; 8 EToken token;
9 int priority;
9 int numoperands; 10 int numoperands;
10 int priority;
11 EDataHeader header; 11 EDataHeader header;
12 }; 12 };
13 13
14 static const OperatorInfo gOperators[] = 14 static const OperatorInfo gOperators[] =
15 { 15 {
72 72
73 for (ExpressionSymbol* sym : mSymbols) 73 for (ExpressionSymbol* sym : mSymbols)
74 { 74 {
75 switch (sym->GetType()) 75 switch (sym->GetType())
76 { 76 {
77 case ExpressionSymbol::eOperatorSymbol: 77 case eOperatorSymbol:
78 { 78 {
79 Print ("\t- Operator: %1\n", static_cast<ExpressionOperator*> (sym)->GetID()); 79 Print ("\t- Operator: %1\n", static_cast<ExpressionOperator*> (sym)->GetID());
80 break; 80 break;
81 } 81 }
82 82
83 case ExpressionSymbol::eValueSymbol: 83 case eValueSymbol:
84 { 84 {
85 ExpressionValue* val = static_cast<ExpressionValue*> (sym); 85 ExpressionValue* val = static_cast<ExpressionValue*> (sym);
86 86
87 if (val->IsConstexpr()) 87 if (val->IsConstexpr())
88 Print ("\t- Constant expression value: %1\n", val->GetValue()); 88 Print ("\t- Constant expression value: %1\n", val->GetValue());
92 val->GetBuffer()->Dump(); 92 val->GetBuffer()->Dump();
93 } 93 }
94 break; 94 break;
95 } 95 }
96 96
97 case ExpressionSymbol::eColonSymbol: 97 case eColonSymbol:
98 { 98 {
99 Print ("\t- Colon"); 99 Print ("\t- Colon");
100 break; 100 break;
101 } 101 }
102 } 102 }
103 } 103 }
104 104
105 Verify();
105 exit (0); 106 exit (0);
106 107
107 /* 108 /*
108 Verify();
109 mResult = Evaluate(); 109 mResult = Evaluate();
110 */ 110 */
111 } 111 }
112 112
113 // ============================================================================= 113 // =============================================================================
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 //

mercurial