예제 #1
0
        public BlockNode Parse()
        {
            var block = new BlockNode();

            while (more())
            {
                block.AddStatement(parseStatement());
            }

            return(block);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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]);
            }
        }
예제 #5
0
        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);
            }
        }