public static Either <ParseException, Pair <List <IToken>, ForLoopNode> > Parse(List <IToken> tokens, SymT symT, IScopedTable <IEntityType, string> parentTypeTable) { Console.WriteLine("ForLoopNode"); SymT NewSymT = new SymT(symT); if (tokens.Count < 1) { return(NotAForLoopException); } if (!(tokens[0] is ForKeywordToken)) { return(NotAForLoopException); } tokens = tokens.Skip(1).ToList(); if (tokens.Count < 1) { return(NotAForLoopException); } if (!(tokens[0] is IdentifierToken)) { return(NotAForLoopException); } IdentifierToken identifier = (IdentifierToken)tokens[0]; var typeTable = new Dictionary <string, IEntityType>(); typeTable.TryAdd( identifier.Lexeme, new VariableType(new PrimitiveTypeRepresentation(new IntegerTypeNode())) ); tokens = tokens.Skip(1).ToList(); var result = new ForLoopNode( identifier, null, null, NewSymT, typeTable, parentTypeTable); var maybeRange = RangeNode.Parse(tokens, result); if (NewSymT.Contain(identifier)) { // TODO: return an exception instead Console.WriteLine("Repeating identifier in the same scope"); } else { NewSymT.Add(identifier); } if (maybeRange.IsLeft) { return(maybeRange.LeftToList()[0]); } RangeNode range = maybeRange.RightToList()[0].Second; tokens = maybeRange.RightToList()[0].First; if (tokens.Count < 1) { return(NotAForLoopException); } if (!(tokens[0] is LoopKeywordToken)) { return(NotAForLoopException); } tokens = tokens.Skip(1).ToList(); var maybeBody = BodyNode.Parse(tokens, NewSymT, result); if (maybeBody.IsLeft) { return(maybeBody.LeftToList()[0]); } BodyNode body = maybeBody.RightToList()[0].Second; tokens = maybeBody.RightToList()[0].First; if (tokens.Count < 1) { return(NotAForLoopException); } if (!(tokens[0] is EndKeywordToken)) { return(NotAForLoopException); } tokens = tokens.Skip(1).ToList(); while (tokens.Count > 0) { if (tokens[0] is NewLineSymbolToken || tokens[0] is CommentToken || tokens[0] is SemicolonSymbolToken) { tokens = tokens.Skip(1).ToList(); } else { break; } } result.Range = range; result.Body = body; return(new Pair <List <IToken>, ForLoopNode>(tokens, result)); }