254 |
254 |
255 return; |
255 return; |
256 } |
256 } |
257 |
257 |
258 if (m_type == TYPE_String) |
258 if (m_type == TYPE_String) |
259 error ("Cannot perform OPER_erations on strings"); |
259 error ("Cannot perform operations on strings"); |
260 |
260 |
261 bool* verified = new bool[m_symbols.size()]; |
261 bool* verified = new bool[m_symbols.size()]; |
262 memset (verified, 0, m_symbols.size() * sizeof (decltype (*verified))); |
262 memset (verified, 0, m_symbols.size() * sizeof (decltype (*verified))); |
263 const auto last = m_symbols.end() - 1; |
263 const auto last = m_symbols.end() - 1; |
264 const auto first = m_symbols.begin(); |
264 const auto first = m_symbols.begin(); |
426 DataBuffer* b1 = values[1]->buffer(); |
426 DataBuffer* b1 = values[1]->buffer(); |
427 DataBuffer* b2 = values[2]->buffer(); |
427 DataBuffer* b2 = values[2]->buffer(); |
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 (DH_IfNotGoto); // if the first OPER_erand (condition) |
431 buf->writeDWord (DH_IfNotGoto); // if the first operand (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 OPER_erand (true case) |
433 buf->mergeAndDestroy (b1); // otherwise, perform second operand (true case) |
434 buf->writeDWord (DH_Goto); // 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 OPER_erand (false case) |
437 buf->mergeAndDestroy (b2); // perform third operand (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 } |
525 SymbolList::Iterator it; |
525 SymbolList::Iterator it; |
526 |
526 |
527 while ((it = findPrioritizedOperator()) != m_symbols.end()) |
527 while ((it = findPrioritizedOperator()) != m_symbols.end()) |
528 { |
528 { |
529 int i = it - m_symbols.begin(); |
529 int i = it - m_symbols.begin(); |
530 List<SymbolList::Iterator> OPER_erands; |
530 List<SymbolList::Iterator> operands; |
531 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); |
531 ExpressionOperator* op = static_cast<ExpressionOperator*> (*it); |
532 const OperatorInfo* info = &g_Operators[op->id()]; |
532 const OperatorInfo* info = &g_Operators[op->id()]; |
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 OPER_erands << it + 1; |
541 operands << 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 OPER_erands << it - 1 |
549 operands << 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 OPER_erands << it - 1 |
558 operands << it - 1 |
559 << it + 1 |
559 << it + 1 |
560 << it + 3; |
560 << it + 3; |
561 break; |
561 break; |
562 } |
562 } |
563 |
563 |
565 error ("WTF bad expression with %1 operands", info->numoperands); |
565 error ("WTF bad expression with %1 operands", info->numoperands); |
566 } |
566 } |
567 |
567 |
568 List<ExpressionValue*> values; |
568 List<ExpressionValue*> values; |
569 |
569 |
570 for (auto it : OPER_erands) |
570 for (auto it : operands) |
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 |