private boolean isConditionTrue(String operator, double left, double right, int lineIndex) {
   if (operator.equals("=")) {
     return left == right;
   }
   if (operator.equals("!")) {
     return left != right;
   }
   if (operator.equals("<")) {
     return left < right;
   }
   if (operator.equals(">")) {
     return left > right;
   }
   throw new IllegalStateException(messages.unrecognizedIfOperator(operator, lineIndex));
 }
 private List<ScheduledCommand> interpret(List<Iterable<String>> linesAsTokens) {
   final ImmutableList.Builder<ScheduledCommand> result = ImmutableList.builder();
   for (int lineIndex = 0; lineIndex < linesAsTokens.size(); lineIndex++) {
     Iterable<String> lineTokens = linesAsTokens.get(lineIndex);
     String command = getFirst(lineTokens, "");
     {
       if (command.startsWith(";")) {
         // Comment, do nothing
       } else if (command.equalsIgnoreCase(localizedCommands.forwardCommand())) {
         result.addAll(createMoveCommands(getValue(getLast(lineTokens))));
       } else if (command.equalsIgnoreCase(localizedCommands.backwardCommand())) {
         result.addAll(createMoveCommands(-1 * getValue(getLast(lineTokens))));
       } else if (command.equalsIgnoreCase(localizedCommands.leftCommand())) {
         workspace.turn(-1 * getValue(getLast(lineTokens)));
       } else if (command.equalsIgnoreCase(localizedCommands.rightCommand())) {
         workspace.turn((getValue(getLast(lineTokens))));
       } else if (command.equalsIgnoreCase(localizedCommands.setXCommand())) {
         workspace.setX(getValue(getLast(lineTokens)));
       } else if (command.equalsIgnoreCase(localizedCommands.setYCommand())) {
         workspace.setY(getValue(getLast(lineTokens)));
       } else if (command.equalsIgnoreCase(localizedCommands.penDownCommand())) {
         workspace.penDown();
       } else if (command.equalsIgnoreCase(localizedCommands.penUpCommand())) {
         workspace.penUp();
       } else if (command.equalsIgnoreCase(localizedCommands.newCommand())) {
         workspace.newCommand();
       } else if (command.equalsIgnoreCase(localizedCommands.penColorCommand())) {
         if (size(lineTokens) == 2) {
           workspace.penColor(getLast(lineTokens));
         } else {
           int red = getValue(get(lineTokens, 1)).intValue();
           int green = getValue(get(lineTokens, 2)).intValue();
           int blue = getValue(get(lineTokens, 3)).intValue();
           int alpha = getValue(get(lineTokens, 4)).intValue();
           workspace.penColor(rgbaString(red, green, blue, alpha));
         }
       } else if (command.equalsIgnoreCase(localizedCommands.canvasColorCommand())) {
         if (size(lineTokens) == 2) {
           workspace.canvasColor(getLast(lineTokens));
         } else {
           int red = getValue(get(lineTokens, 1)).intValue();
           int green = getValue(get(lineTokens, 2)).intValue();
           int blue = getValue(get(lineTokens, 3)).intValue();
           int alpha = getValue(get(lineTokens, 4)).intValue();
           workspace.canvasColor(rgbaString(red, green, blue, alpha));
         }
       } else if (command.equalsIgnoreCase(localizedCommands.drawStringCommand())) {
         workspace.drawString(stringJoiner.join(skip(lineTokens, 1)));
       } else if (command.equalsIgnoreCase(localizedCommands.fontSizeCommand())) {
         workspace.fontSize(getValue(getLast(lineTokens)).intValue());
       } else if (command.equalsIgnoreCase(localizedCommands.fontStyleCommand())) {
         workspace.fontStyle(getLast(lineTokens));
       } else if (command.equalsIgnoreCase(localizedCommands.fontNameCommand())) {
         workspace.fontName(getLast(lineTokens));
       } else if (command.equalsIgnoreCase(localizedCommands.clearCommand())) {
         workspace.newCommand();
       } else if (command.equalsIgnoreCase(localizedCommands.homeCommand())) {
         workspace.home();
       } else if (command.equalsIgnoreCase(localizedCommands.makeCommand())) {
         userVariables.put(get(lineTokens, 1).toLowerCase(), getValue(get(lineTokens, 3)));
       } else if (command.equalsIgnoreCase(localizedCommands.contentCommand())) {
         String variableName = getLast(lineTokens);
         Window.alert(variableName + " : " + getValue(variableName));
       } else if (command.equalsIgnoreCase(localizedCommands.sumCommand())) {
         handleVariableMath(lineTokens);
       } else if (command.equalsIgnoreCase(localizedCommands.subtractCommand())) {
         handleVariableMath(lineTokens);
       } else if (command.equalsIgnoreCase(localizedCommands.multiplyCommand())) {
         handleVariableMath(lineTokens);
       } else if (command.equalsIgnoreCase(localizedCommands.divideCommand())) {
         handleVariableMath(lineTokens);
       } else if (command.equalsIgnoreCase(localizedCommands.remainderCommand())) {
         handleVariableMath(lineTokens);
       } else if (command.equalsIgnoreCase(localizedCommands.hideCommand())) {
         //				tortueCanvas.hideTurtle();
       } else if (command.equalsIgnoreCase(localizedCommands.showCommand())) {
         //				tortueCanvas.showTurtle();
       } else if (command.equalsIgnoreCase(localizedCommands.repeatCommand())) {
         int unclosedRepeatCommands = 1; // to detect nested repeats
         ImmutableList.Builder<Iterable<String>> linesToRepeat = ImmutableList.builder();
         for (int lineAfterRepeat = lineIndex + 1;
             lineAfterRepeat < linesAsTokens.size();
             lineAfterRepeat++) {
           Iterable<String> lineToRepeat = linesAsTokens.get(lineAfterRepeat);
           if (get(lineToRepeat, 0).equalsIgnoreCase(localizedCommands.repeatCommand())) {
             unclosedRepeatCommands++;
           }
           if (size(lineToRepeat) >= 2 //
               && get(lineToRepeat, 0).equalsIgnoreCase(localizedCommands.endCommand())
               && get(lineToRepeat, 1).equalsIgnoreCase(localizedCommands.repeatCommand())) {
             unclosedRepeatCommands--;
             if (unclosedRepeatCommands == 0) {
               lineIndex = lineAfterRepeat + 1;
               break;
             }
           }
           linesToRepeat.add(lineToRepeat);
         }
         if (unclosedRepeatCommands != 0) {
           throw new IllegalStateException(messages.unclosedRepeatStatement(lineIndex));
         }
         int repeats = getValue(getLast(lineTokens)).intValue();
         for (int i = 0; i < repeats; i++) {
           result.addAll(interpret(linesToRepeat.build()));
         }
       } else if (command.equalsIgnoreCase(localizedCommands.ifCommand())) {
         int unclosedIfs = 1;
         ImmutableList.Builder<Iterable<String>> conditionedLines = ImmutableList.builder();
         for (int lineAfterIf = lineIndex + 1; lineAfterIf < linesAsTokens.size(); lineAfterIf++) {
           Iterable<String> conditionedLine = linesAsTokens.get(lineAfterIf);
           if (get(conditionedLine, 0).equalsIgnoreCase(localizedCommands.ifCommand())) {
             unclosedIfs++;
           }
           if (size(conditionedLine) >= 2 //
               && get(conditionedLine, 0).equalsIgnoreCase(localizedCommands.endCommand()) //
               && get(conditionedLine, 1).equalsIgnoreCase(localizedCommands.ifCommand())) {
             unclosedIfs--;
             if (unclosedIfs == 0) {
               lineIndex = lineAfterIf + 1;
               break;
             }
           }
           conditionedLines.add(conditionedLine);
         }
         if (unclosedIfs != 0) {
           throw new IllegalStateException(messages.unclosedIfStatement(lineIndex));
         }
         if (isConditionTrue(
             get(lineTokens, 2),
             getValue(get(lineTokens, 1)),
             getValue(get(lineTokens, 3)),
             lineIndex)) {
           result.addAll(interpret(conditionedLines.build()));
         }
       } else if (command.equalsIgnoreCase(localizedCommands.toCommand())) {
         boolean endTagFound = false;
         ImmutableList.Builder<Iterable<String>> functionLines = ImmutableList.builder();
         int functionLineIndex = lineIndex + 1;
         for (; functionLineIndex < linesAsTokens.size(); functionLineIndex++) {
           Iterable<String> functionLine = linesAsTokens.get(functionLineIndex);
           if (size(functionLine) >= 2 //
               && get(functionLine, 0).equalsIgnoreCase(localizedCommands.endCommand()) //
               && get(functionLine, 1).equalsIgnoreCase(localizedCommands.toCommand())) {
             endTagFound = true;
             break;
           }
           functionLines.add(functionLine);
         }
         if (!endTagFound) {
           throw new IllegalStateException(messages.unclosedFunctionStatement(lineIndex));
         }
         functions.put(get(lineTokens, 1).toLowerCase(), functionLines.build());
         lineIndex = functionLineIndex;
       } else {
         if (functions.containsKey(command.toLowerCase())) {
           result.addAll(interpret(functions.get(command.toLowerCase())));
         } else {
           throw new IllegalStateException(messages.unrecognizedStatement(lineIndex));
         }
       }
     }
   }
   return result.build();
 }