public static RoutineType ToRoutineType(this RoutineDeclarationNode node) =>
 new RoutineType(
     node.ReturnType
     .Map(t => t.ToTypeRepresentation()),
     node.Parameters
     .Select(pn => pn.Type.ToTypeRepresentation())
     .ToImmutableList()
     );
        public static Either <ParseException, ProgramNode> Parse(List <IToken> tokens)
        {
            Console.WriteLine("ProgramNode");

            var declarations = new List <IDeclarationNode>();
            var typeTable    = new Dictionary <string, IEntityType>();
            var symT         = new SymT();

            var result = new ProgramNode(declarations, symT, typeTable);

            while (tokens.Count > 0)
            {
                var maybeRoutineDeclaration = RoutineDeclarationNode.Parse(tokens, symT, result);
                if (maybeRoutineDeclaration.IsRight)
                {
                    tokens = maybeRoutineDeclaration.RightToList()[0].First;

                    var routineDeclaration = maybeRoutineDeclaration.RightToList()[0].Second;
                    declarations.Add(routineDeclaration);
                    typeTable.TryAdd(routineDeclaration.Identifier.Lexeme, routineDeclaration.ToRoutineType());
                    continue;
                }

                var maybeVariableDeclaration = VariableDeclarationNode.Parse(tokens, symT, result);
                if (maybeVariableDeclaration.IsRight)
                {
                    tokens = maybeVariableDeclaration.RightToList()[0].First;
                    var varDecl = maybeVariableDeclaration.RightToList()[0].Second;
                    declarations.Add(varDecl);
                    typeTable.TryAdd(varDecl.Identifier.Lexeme, varDecl.ToVariableType());
                    continue;
                }

                var maybeTypeDeclaration = TypeDeclarationNode.Parse(tokens, symT, result);
                if (maybeTypeDeclaration.IsRight)
                {
                    tokens = maybeTypeDeclaration.RightToList()[0].First;
                    var typeDecl = maybeTypeDeclaration.RightToList()[0].Second;
                    declarations.Add(typeDecl);
                    typeTable.TryAdd(typeDecl.Identifier.Lexeme, typeDecl.ToTypeAliasType());
                    continue;
                }

                return(maybeTypeDeclaration.LeftToList()[0]);
            }

            Console.WriteLine("Program is interprited Successfully");
            return(new ProgramNode(declarations, symT, typeTable));
            //return Either<ParseException, ProgramNode>.Bottom;
        }