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); } }
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)); }