| 12 | namespace Compiler |
| 13 | { |
| 14 | bool ControlParser::parseIfBody(int keyword, const TokenLoc& loc, Scanner& scanner) |
| 15 | { |
| 16 | if (keyword == Scanner::K_endif || keyword == Scanner::K_elseif || keyword == Scanner::K_else) |
| 17 | { |
| 18 | std::pair<Codes, Codes> entry; |
| 19 | |
| 20 | if (mState != IfElseBodyState) |
| 21 | mExprParser.append(entry.first); |
| 22 | |
| 23 | std::copy(mCodeBlock.begin(), mCodeBlock.end(), std::back_inserter(entry.second)); |
| 24 | |
| 25 | mIfCode.push_back(std::move(entry)); |
| 26 | |
| 27 | mCodeBlock.clear(); |
| 28 | |
| 29 | if (keyword == Scanner::K_endif) |
| 30 | { |
| 31 | // store code for if-cascade |
| 32 | Codes codes; |
| 33 | |
| 34 | for (auto iter(mIfCode.rbegin()); iter != mIfCode.rend(); ++iter) |
| 35 | { |
| 36 | Codes block; |
| 37 | |
| 38 | if (iter != mIfCode.rbegin()) |
| 39 | Generator::jump(iter->second, static_cast<int>(codes.size() + 1)); |
| 40 | |
| 41 | if (!iter->first.empty()) |
| 42 | { |
| 43 | // if or elseif |
| 44 | std::copy(iter->first.begin(), iter->first.end(), std::back_inserter(block)); |
| 45 | Generator::jumpOnZero(block, static_cast<int>(iter->second.size() + 1)); |
| 46 | } |
| 47 | |
| 48 | std::copy(iter->second.begin(), iter->second.end(), std::back_inserter(block)); |
| 49 | |
| 50 | std::swap(codes, block); |
| 51 | |
| 52 | std::copy(block.begin(), block.end(), std::back_inserter(codes)); |
| 53 | } |
| 54 | |
| 55 | std::copy(codes.begin(), codes.end(), std::back_inserter(mCode)); |
| 56 | |
| 57 | mIfCode.clear(); |
| 58 | mState = IfEndifState; |
| 59 | } |
| 60 | else if (keyword == Scanner::K_elseif) |
| 61 | { |
| 62 | mExprParser.reset(); |
| 63 | scanner.scan(mExprParser); |
| 64 | |
| 65 | mState = IfElseifEndState; |
| 66 | } |
| 67 | else if (keyword == Scanner::K_else) |
| 68 | { |
| 69 | mState = IfElseJunkState; /// \todo should be IfElseEndState; add an option for that |
| 70 | } |
| 71 |
nothing calls this directly
no test coverage detected