public BlockNode Parse() { var block = new BlockNode(); while (more()) { block.AddStatement(parseStatement()); } return(block); }
private BlockNode ParseBlock() { Expect(TokenType.LBRACE); Next(); var block = new BlockNode(Position(-1)); while (More() && !Accept(TokenType.RBRACE)) { block.AddStatement(ParseStatement()); } Expect(TokenType.RBRACE); Next(); return(block); }
private BlockNode parseBlock() { expect(TokenType.LBRACE); next(); var block = new BlockNode(); while (more() && current().Type != TokenType.RBRACE) { block.AddStatement(parseStatement()); } expect(TokenType.RBRACE); next(); return(block); }
public void BlockNodesHaveStatements() { var statements = new List <StatementNode>(); statements.Add(new BreakNode(SourcePosition.NIL)); statements.Add(new ContinueNode(SourcePosition.NIL)); statements.Add(new ReturnNode(SourcePosition.NIL, new NilNode(SourcePosition.NIL))); for (var i = 0; i < statements.Count; i++) { subject.AddStatement(statements[i]); } var subjectStatements = subject.Statements.ToList(); Assert.AreEqual(subjectStatements.Count, statements.Count); for (var i = 0; i < subjectStatements.Count; i++) { Assert.AreEqual(subjectStatements[i], statements[i]); } }
private void Statement(BlockNode pn) { Expression expr; Token identifier; switch (this.token.SymbolType) { case SymbolType.Variable: // <stmt> ::= "var" <var_ident> ":" <type> [ ":=" <expr> ] this.token = this.scanner.NextToken(); identifier = this.token; Match(SymbolType.Identifier); Match(SymbolType.Colon); SymbolType type = Type(); pn.AddStatement(new DeclarationNode(identifier.Value, type, identifier)); if (this.token.SymbolType == SymbolType.Assignment) { this.token = this.scanner.NextToken(); expr = Expression(); pn.AddStatement(new AssignmentNode(identifier.Value, expr, identifier)); } break; case SymbolType.Identifier: // <stmt> ::= <var_ident> ":=" <expr> identifier = this.token; this.token = this.scanner.NextToken(); Match(SymbolType.Assignment); expr = Expression(); pn.AddStatement(new AssignmentNode(identifier.Value, expr, identifier)); break; case SymbolType.For: // <stmt> ::= "for" <var_ident> "in" <expr> ".." <expr> "do" <stmts> "end" "for" this.token = this.scanner.NextToken(); identifier = this.token; string forLoopVar = identifier.Value; Match(SymbolType.Identifier); Match(SymbolType.In); expr = Expression(); AssignmentNode assignment = new AssignmentNode(identifier.Value, expr, identifier); Match(SymbolType.Range); expr = Expression(); BinaryExpressionNode condition = new BinaryExpressionNode( new UnaryOperandNode(identifier.Value, SymbolType.Identifier, identifier), "to", new ExpressionOperandNode(expr) // BinaryExpression expects Operands ); ForLoopNode fln = new ForLoopNode(assignment, condition, forLoopVar); Match(SymbolType.Do); Statements(fln); Match(SymbolType.End); Match(SymbolType.For); pn.AddStatement(fln); break; case SymbolType.Read: // <stmt> ::= "read" <var_ident> this.token = this.scanner.NextToken(); identifier = this.token; Match(SymbolType.Identifier); pn.AddStatement(new ReadNode(identifier.Value, "", identifier)); break; case SymbolType.Print: // <stmt> ::= "print" <expr> this.token = this.scanner.NextToken(); expr = Expression(); pn.AddStatement(new PrintNode(expr)); break; case SymbolType.Assert: // <stmt> ::= "assert" "(" <expr> ")" this.token = this.scanner.NextToken(); Match(SymbolType.LeftParenthesis); expr = Expression(); Match(SymbolType.RightParenthesis); pn.AddStatement(new AssertNode(expr)); break; default: throw new Error($"Statement can not start with {this.token.SymbolType}", this.token); } }