| 2467 | } |
| 2468 | |
| 2469 | void AddArrayIterator(const char* pos, InplaceStr varName, TypeInfo* type, bool extra) |
| 2470 | { |
| 2471 | CodeInfo::lastKnownStartPos = pos; |
| 2472 | |
| 2473 | // Save current node type, because some information from it is required later |
| 2474 | TypeInfo *startType = CodeInfo::nodeList.back()->typeInfo; |
| 2475 | |
| 2476 | bool extraExpression = false; |
| 2477 | // If value dereference was already called, but we need to get a pointer to array |
| 2478 | if(CodeInfo::nodeList.back()->nodeType == typeNodeDereference) |
| 2479 | { |
| 2480 | ((NodeDereference*)CodeInfo::nodeList.back())->Neutralize(); |
| 2481 | }else if(CodeInfo::nodeList.back()->nodeType != typeNodeFunctionAddress){ |
| 2482 | // Or if it wasn't called, for example, inplace array definition/function call/etc, we make a temporary variable |
| 2483 | AddInplaceVariable(pos); |
| 2484 | // And flag that we have added an extra node |
| 2485 | extraExpression = true; |
| 2486 | } |
| 2487 | |
| 2488 | // Special implementation of for each for built-in arrays |
| 2489 | if(startType->arrLevel) |
| 2490 | { |
| 2491 | assert(startType->subType->size != ~0u); |
| 2492 | |
| 2493 | // Add temporary variable that holds a pointer |
| 2494 | AddInplaceVariable(pos); |
| 2495 | NodeZeroOP *getArray = CodeInfo::nodeList.back(); |
| 2496 | CodeInfo::nodeList.pop_back(); |
| 2497 | |
| 2498 | // Initialization part "iterator_type $temp = 0;" |
| 2499 | CodeInfo::nodeList.push_back(new NodeNumber(0, typeInt)); |
| 2500 | AddInplaceVariable(pos); |
| 2501 | NodeZeroOP *getIterator = CodeInfo::nodeList.back(); |
| 2502 | CodeInfo::nodeList.pop_back(); |
| 2503 | |
| 2504 | AddTwoExpressionNode(NULL); |
| 2505 | if(extraExpression) |
| 2506 | AddTwoExpressionNode(NULL); |
| 2507 | |
| 2508 | // Condition part "$temp < arr.size" |
| 2509 | CodeInfo::nodeList.push_back(getIterator); |
| 2510 | AddGetVariableNode(pos); |
| 2511 | CodeInfo::nodeList.push_back(getArray); |
| 2512 | AddMemberAccessNode(pos, InplaceStr("size")); |
| 2513 | AddGetVariableNode(pos); |
| 2514 | CodeInfo::nodeList.push_back(new NodeBinaryOp(cmdLess)); |
| 2515 | |
| 2516 | // Iteration part "element_type varName = arr[$temp++]; |
| 2517 | NodeOneOP *wrap = new NodeOneOP(); |
| 2518 | wrap->SetFirstNode(getArray); |
| 2519 | CodeInfo::nodeList.push_back(wrap); |
| 2520 | NodeOneOP *wrap2 = new NodeOneOP(); |
| 2521 | wrap2->SetFirstNode(getIterator); |
| 2522 | CodeInfo::nodeList.push_back(wrap2); |
| 2523 | AddUnaryModifyOpNode(pos, OP_INCREMENT, OP_POSTFIX); |
| 2524 | AddArrayIndexNode(pos); |
| 2525 | currType = (TypeInfo*)type ? CodeInfo::GetReferenceType((TypeInfo*)type) : NULL; |
| 2526 | VariableInfo *it = (VariableInfo*)AddVariable(pos, varName); |
no test coverage detected