diff --git a/src/com/annimon/everlastingsummer/Parser.java b/src/com/annimon/everlastingsummer/Parser.java index 9931d3b..cdae92b 100644 --- a/src/com/annimon/everlastingsummer/Parser.java +++ b/src/com/annimon/everlastingsummer/Parser.java @@ -37,9 +37,9 @@ public final class Parser { private int position; private final Map labels; - /** Оптимизация, чтобы каждый раз не искать endmenu, + /** Оптимизация, чтобы каждый раз не искать endmenu/endif, * если их попросту нет в необработанном сценарии */ - private boolean hasEndMenu; + private boolean hasEndMenu, hasEndIf; public Parser(List tokens) { this.tokens = tokens; @@ -47,6 +47,7 @@ public final class Parser { position = 0; labels = new HashMap(); hasEndMenu = false; + hasEndIf = false; preScan(); Variables.init(); } @@ -151,13 +152,7 @@ public final class Parser { // Остаток от условного выражения. Пропускаем до появления ENDIF. if (match(token, TokenType.ELSE)) { - int pos = 0; - while (true) { - if (lookMatch(pos, TokenType.ENDIF)) break; - if (lookMatch(pos, TokenType.EOF)) return true; - pos++; - } - position += pos; + if (hasEndIf) position += skipIf(); return false; } } @@ -375,6 +370,7 @@ public final class Parser { final Expression condition = expression(); consume(TokenType.COLON); + if (!hasEndIf) return false; if (condition.eval() == 0) { // Если условие не верно, пропускаем блок до следующего ENDIF int pos = 0; @@ -534,6 +530,8 @@ public final class Parser { final TokenType current = tokens.get(i).getType(); if (current == TokenType.ENDMENU) { hasEndMenu = true; + } else if (current == TokenType.ENDIF) { + hasEndIf = true; } else if ( (current == TokenType.LABEL) && (tokens.get(i + 2).getType() == TokenType.COLON) ) { // label word : @@ -566,6 +564,20 @@ public final class Parser { return pos; } + private int skipIf() { + int pos = 0; + int level = 1; + while (true) { + if (lookMatch(pos, TokenType.IF)) level++; + else if (lookMatch(pos, TokenType.ENDIF)) { + level--; + if (level <= 0) break; + } + pos++; + } + return pos; + } + private double consumeDouble() { return Double.parseDouble(consume(TokenType.NUMBER).getText());