public override void Visit(ForStmt forStmt)
        {
            forStmt.StartExpr.Accept(this);
            forStmt.EndExpr.Accept(this);
            forStmt.LoopVar.Accept(this);
            Symbol loopSymbol = SymbolTable.GetSymbol(forStmt.LoopVar.IdentifierName);

            for(int i = (int)forStmt.StartExpr.ExprValue; i <= (int)forStmt.EndExpr.ExprValue; i++)
            {
                loopSymbol.Value = i;
                forStmt.Body.Accept(this);
            }
        }
        public void Visit(ForStmt node)
        {
            Node identifierNameStmt = node.Children [0];
            Node startExpr = node.Children [1];
            Node endExpr = node.Children [2];
            Node statements = node.Children [3];

            VisitChildren (startExpr);
            int start = Int32.Parse (ValueStack.Pop ().Value);

            VisitChildren (endExpr);
            int end = Int32.Parse (ValueStack.Pop ().Value);

            for (int i = start; i <= end; i++) {
                SymbolTable [identifierNameStmt.Name].Value = i.ToString ();
                VisitChildren (statements);
            }

            ValueStack = new Stack<StackValue> (); // don't leave anything to stack after the For-loop
        }
        public void Visit(ForStmt node)
        {
            try {
                Node identifierNameStmt = node.Children [0];
                Node startExpr = node.Children [1];
                Node endExpr = node.Children [2];
                Node statements = node.Children [3];

                if (!SymbolTable.ContainsKey (identifierNameStmt.Name)) {
                    throw new SemanticError ("Variable " + identifierNameStmt.Name +
                    " needs to be declared before use", identifierNameStmt.Row,
                    identifierNameStmt.Column);
                } else if (SymbolTable [identifierNameStmt.Name].Type != "Int") {
                    throw new SemanticError ("Variable " + identifierNameStmt.Name +
                    " must be of type int to be used in For-statement", identifierNameStmt.Row,
                    identifierNameStmt.Column);
                }

                VisitChildren (startExpr);
                string type = TypeStack.Pop ();
                if (type != "Int") {
                    throw new SemanticError ("For-range start needs to be int value, not " +
                    type, startExpr.Row, startExpr.Column);
                }

                VisitChildren (endExpr);
                type = TypeStack.Pop ();
                if (type != "Int") {
                    throw new SemanticError ("For-range end needs to be int value, not " +
                    type, endExpr.Row, endExpr.Column);
                }

                VisitChildren (statements);
            } catch (SemanticError error) {
                Errors.Add (error);
            }

            TypeStack.Clear (); // clean the stack as there's no use for the type value(s) at this point
        }
 public override void Visit(ForStmt forStmt)
 {
     Expression start = forStmt.StartExpr;
     Expression end = forStmt.EndExpr;
     IdentifierExpr loopvar = forStmt.LoopVar;
     start.Accept(this);
     end.Accept(this);
     loopvar.Accept(this);
     if (loopvar.Type != ExprType.IntType)
     {
         Errors.AddError(String.Format("For loop variable {0} of type {0} illegal at line {1} column {2}.",
             loopvar.IdentifierName, loopvar.Type, loopvar.Line, loopvar.Column), ErrorTypes.SemanticError);
     }
     if (start.Type != ExprType.IntType || end.Type != ExprType.IntType)
     {
         Errors.AddError(String.Format("For loop expressions must be of type int at line {0} column {1}.",
             forStmt.Line, forStmt.Column), ErrorTypes.SemanticError);
     }
     forStmt.Body.Accept(this);
 }
        private Statement Stmt()
        {
            switch ((Token.Types)currentToken.Type) {
                case Token.Types.Var:
                    VarDeclStmt varDeclStmt = new VarDeclStmt ("VarDecl", currentToken.Row, currentToken.Column);
                    Match (Token.Types.Var);
                    varDeclStmt.AddChild (IdentifierNameStmt ());
                    Match (Token.Types.Colon);
                    varDeclStmt.AddChild (Type ());

                    if ((Token.Types)currentToken.Type == Token.Types.Assign) {
                        Match (Token.Types.Assign);
                        varDeclStmt.AddChild (Expr ());
                        return varDeclStmt;
                    } else if ((Token.Types)currentToken.Type == Token.Types.Semicolon) {
                        return varDeclStmt;
                    }

                    throw new SyntaxError ("Expected Assign, got: " + currentToken.Type, currentToken.Row, currentToken.Column);
                case Token.Types.Identifier:
                    AssignmentStmt assignmentStmt = new AssignmentStmt ("AssignmentStmt", currentToken.Row, currentToken.Column);
                    assignmentStmt.AddChild (IdentifierNameStmt ());
                    Match (Token.Types.Assign);
                    assignmentStmt.AddChild (Expr ());
                    return assignmentStmt;
                case Token.Types.For:
                    ForStmt forStmt = new ForStmt ("ForStmt", currentToken.Row, currentToken.Column);
                    Match (Token.Types.For);
                    forStmt.AddChild (IdentifierNameStmt ());
                    Match (Token.Types.In);
                    forStmt.AddChild (Expr ());
                    Match (Token.Types.Range);
                    forStmt.AddChild (Expr ());
                    Match (Token.Types.Do);
                    forStmt.AddChild (Stmts ());
                    Match (Token.Types.End);
                    Match (Token.Types.For);
                    return forStmt;
                case Token.Types.Read:
                    ReadStmt readStmt = new ReadStmt ("ReadStmt", currentToken.Row, currentToken.Column);
                    Match (Token.Types.Read);
                    readStmt.AddChild (IdentifierNameStmt ());
                    return readStmt;
                case Token.Types.Print:
                    PrintStmt printStmt = new PrintStmt ("PrintStmt", currentToken.Row, currentToken.Column);
                    Match (Token.Types.Print);
                    printStmt.AddChild (Expr ());
                    return printStmt;
                case Token.Types.Assert:
                    AssertStmt assertStmt = new AssertStmt ("AssertStmt", currentToken.Row, currentToken.Column);
                    Match (Token.Types.Assert);
                    Match (Token.Types.LeftParenthesis);
                    assertStmt.AddChild (Expr ());
                    Match (Token.Types.RightParenthesis);
                    return assertStmt;
                default:
                    throw new SyntaxError ("invalid start symbol for statement " + currentToken.Lexeme,
                        currentToken.Row, currentToken.Column);
            }
        }
Exemple #6
0
 private Statement ParseStatement()
 {
     if (Accept(Token.Types.KwVar))
     {
         DeclarationStmt declaration = new DeclarationStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token id = Match(Token.Types.Identifier);
         declaration.Identifier = new IdentifierExpr(id.Line, id.Column, id.Content);
         Match(Token.Types.Colon);
         TypeNode typeNode = ParseType();
         declaration.Type = typeNode;
         if (Accept(Token.Types.OpAssignment))
         {
             declaration.AssignmentExpr = ParseExpression();
         }
         return declaration;
     }
     else if (Accept(Token.Types.Identifier))
     {
         AssignmentStmt statement = new AssignmentStmt(AcceptedToken.Line, AcceptedToken.Column);
         statement.Identifier = new IdentifierExpr(AcceptedToken.Line, AcceptedToken.Column, AcceptedToken.Content);
         Match(Token.Types.OpAssignment);
         statement.AssignmentExpr = ParseExpression();
         return statement;
     }
     else if (Accept(Token.Types.KwFor))
     {
         ForStmt statement = new ForStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token idToken = Match(Token.Types.Identifier);
         statement.LoopVar = new IdentifierExpr(idToken.Line, idToken.Column, idToken.Content);
         Match(Token.Types.KwIn);
         statement.StartExpr = ParseExpression();
         Match(Token.Types.OpRange);
         statement.EndExpr = ParseExpression();
         Match(Token.Types.KwDo);
         statement.Body = ParseStatements(new StmtList(CurrentToken.Line, CurrentToken.Column));
         Match(Token.Types.KwEnd);
         Match(Token.Types.KwFor);
         return statement;
     }
     else if (Accept(Token.Types.KwRead))
     {
         ReadStmt statement = new ReadStmt(AcceptedToken.Line, AcceptedToken.Column);
         Token idToken = Match(Token.Types.Identifier);
         statement.Variable = new IdentifierExpr(idToken.Line, idToken.Column, idToken.Content);
         return statement;
     }
     else if (Accept(Token.Types.KwPrint))
     {
         PrintStmt statement = new PrintStmt(AcceptedToken.Line, AcceptedToken.Column);
         statement.PrintExpr = ParseExpression();
         return statement;
     }
     else if (Accept(Token.Types.KwAssert))
     {
         AssertStmt statement = new AssertStmt(AcceptedToken.Line, AcceptedToken.Column);
         Match(Token.Types.LParen);
         statement.AssertExpr = ParseExpression();
         Match(Token.Types.RParen);
         return statement;
     }
     throw new ParserException(String.Format("Expected statement, got {0} instead at line {1} column {2}.",
         CurrentToken.Type, CurrentToken.Line, CurrentToken.Column));
 }