예제 #1
0
    def test_single_if_statement(self):
        '''Can parse a single if statement
           `if (1) {
              duck = 3;
            }`
        '''
        given = iter([
            Token('IF', 'if'),
            Token('LPAREN', '('),
            Token('INTEGER', '1'),
            Token('RPAREN', ')'),

            Token('LCURLY', '{'),
            Token('ID', 'duck'),
            Token('EQUAL', '='),
            Token('INTEGER', '3'),
            Token('SEMI', ';'),
            Token('RCURLY', '}'),
        ])

        expected = ast.Block([
            ast.IfStatement(
                ast.Integer(1),
                ast.Block([
                    ast.Assignment(ast.ID('duck'), ast.Integer(3))
                ]),
                ast.Block([])
            )
        ])

        result = parser.parse(given)

        assert expected == result
예제 #2
0
    def test_if_statement_error(self):
        '''An error with given program:
           `int x;
            if (x) {
              x = 1.0;
            } else {
              x = 0;
            }`'''

        given = ast.Block([
            ast.Declaration('int', [ast.ID('x')]),
            ast.IfStatement(
                ast.ID('x'),
                ast.Block([ast.Assignment(ast.ID('x'), ast.Float(1.0))]),
                ast.Block([ast.Assignment(ast.ID('x'), ast.Integer(0))]),
            )
        ])

        report = typechecker.typecheck(given)
        expected_errors = [
            TypecheckerError(ast.Assignment(ast.ID('x'), ast.Float(1.0)))
        ]

        for (r, e) in zip_longest(report.get_errors(), expected_errors):
            assert r == e
예제 #3
0
    def test_simple_program_correct(self):
        '''Can typecheck a simple program:
           `int wildcat, animals[2];
            float duck;

            wildcat = 1;
            duck = 1.0;

            if(duck) {
              animals[0] = wildcat;
              animals[1] = 2;
            } else {
              animals[0] = 1;
            }

            duck = (duck + 2.5) * 33.0 / 2.0;
            `
        '''

        given = ast.Block([
            ast.Declaration('int', [
                ast.ID('wildcat'),
                ast.ArrayRef(ast.ID('animals'), ast.Integer(2))
            ]),
            ast.Declaration('float', [ast.ID('duck')]),
            ast.Assignment(ast.ID('wildcat'), ast.Integer(1)),
            ast.Assignment(ast.ID('duck'), ast.Float(1.0)),
            ast.IfStatement(
                ast.ID('duck'),
                ast.Block([
                    ast.Assignment(
                        ast.ArrayRef(ast.ID('animals'), ast.Integer(0)),
                        ast.ID('wildcat')),
                    ast.Assignment(
                        ast.ArrayRef(ast.ID('animals'), ast.Integer(1)),
                        ast.Integer(2))
                ]),
                ast.Block([
                    ast.Assignment(
                        ast.ArrayRef(ast.ID('animals'), ast.Integer(0)),
                        ast.Integer(1))
                ])),
            ast.Assignment(
                ast.ID('duck'),
                ast.BinOp(
                    '/',
                    ast.BinOp('*',
                              ast.BinOp('+', ast.ID('duck'), ast.Float(2.5)),
                              ast.Float(33.0)), ast.Float(2.0)))
        ])

        report = typechecker.typecheck(given)
        expected_errors = []

        for (r, e) in zip_longest(report.get_errors(), expected_errors):
            assert r == e
예제 #4
0
    def test_compiler_parse(self):
        '''Can parse a simple program:'''
        given = '''
            float duck, goose, birds[2];
            int wildcat;

            duck = 1.0;
            goose = -1;

            wildcat = 1;

            birds[0] = duck;

            if (duck) {
              birds[1] = goose;
            } else {
              birds[1] = wildcat;
            }
        '''

        result = compiler.parse(given)

        expected = ast.Block([
            ast.Declaration('float', [
                ast.ID('duck'),
                ast.ID('goose'),
                ast.ArrayRef(ast.ID('birds'), ast.Integer(2))
            ]),
            ast.Declaration('int', [ast.ID('wildcat')]),
            ast.Assignment(ast.ID('duck'), ast.Float(1.0)),
            ast.Assignment(ast.ID('goose'), ast.UnaryOp('-', ast.Integer(1))),
            ast.Assignment(ast.ID('wildcat'), ast.Integer(1)),
            ast.Assignment(ast.ArrayRef(ast.ID('birds'), ast.Integer(0)),
                           ast.ID('duck')),
            ast.IfStatement(
                ast.ID('duck'),
                ast.Block([
                    ast.Assignment(
                        ast.ArrayRef(ast.ID('birds'), ast.Integer(1)),
                        ast.ID('goose'))
                ]),
                ast.Block([
                    ast.Assignment(
                        ast.ArrayRef(ast.ID('birds'), ast.Integer(1)),
                        ast.ID('wildcat'))
                ])),
        ])

        assert result == expected
예제 #5
0
    def test_if_else_statement(self):
        '''Can parse an if-else statement
           `if (x + 3) {
              duck = x;
            } else {
              goose = x;
            }`
        '''
        given = iter([
            Token('IF', 'if'),
            Token('LPAREN', '('),
            Token('ID', 'x'),
            Token('PLUS', '+'),
            Token('INTEGER', '3'),
            Token('RPAREN', ')'),

            Token('LCURLY', '{'),
            Token('ID', 'duck'),
            Token('EQUAL', '='),
            Token('ID', 'x'),
            Token('SEMI', ';'),
            Token('RCURLY', '}'),

            Token('ELSE', 'else'),

            Token('LCURLY', '{'),
            Token('ID', 'goose'),
            Token('EQUAL', '='),
            Token('ID', 'x'),
            Token('SEMI', ';'),
            Token('RCURLY', '}'),
        ])

        expected = ast.Block([
            ast.IfStatement(
                ast.BinOp('+', ast.ID('x'), ast.Integer(3)),
                ast.Block([
                    ast.Assignment(ast.ID('duck'), ast.ID('x'))
                ]),
                ast.Block([
                    ast.Assignment(ast.ID('goose'), ast.ID('x'))
                ])
            )
        ])

        result = parser.parse(given)

        assert expected == result
예제 #6
0
    def test_simple_program(self):
        '''Can parse a simple program
           `int x[3], duck, goose, wildcat;

            duck = 1;
            goose = 2;

            x[0] = duck;
            x[duck] = goose;

            if (duck + x[duck]) {
              wildcat = duck;
            } else {
              wildcat = goose;
            }
            x[2] = wildcat;`
        '''
        given = iter([
            Token('INT_TYPE', 'int'),
            Token('ID', 'x'), Token('LBRACE', '['), Token('INTEGER', '3'), Token('RBRACE', ']'), Token('COMMA', ','),
            Token('ID', 'duck'), Token('COMMA', ','),
            Token('ID', 'goose'), Token('COMMA', ','),
            Token('ID', 'wildcat'), Token('SEMI', ';'),

            Token('ID', 'duck'), Token('EQUAL', '='), Token('INTEGER', '1'), Token('SEMI', ';'),
            Token('ID', 'goose'), Token('EQUAL', '='), Token('INTEGER', '2'), Token('SEMI', ';'),
            Token('ID', 'x'), Token('LBRACE', '['), Token('INTEGER', '0'), Token('RBRACE', ']'), Token('EQUAL', '='), Token('ID', 'duck'), Token('SEMI', ';'),
            Token('ID', 'x'), Token('LBRACE', '['), Token('ID', 'duck'), Token('RBRACE', ']'), Token('EQUAL', '='), Token('ID', 'goose'), Token('SEMI', ';'),
            Token('IF', 'if'), Token('LPAREN', '('), Token('ID', 'duck'), Token('PLUS', '+'), Token('ID', 'x'), Token('LBRACE', '['), Token('ID', 'duck'), Token('RBRACE', ']'), Token('RPAREN', ')'),
            Token('LCURLY', '{'), Token('ID', 'wildcat'), Token('EQUAL', '='), Token('ID', 'duck'), Token('SEMI', ';'), Token('RCURLY', '}'),
            Token('ELSE', 'else'), Token('LCURLY', '{'), Token('ID', 'wildcat'), Token('EQUAL', '='), Token('ID', 'goose'), Token('SEMI', ';'), Token('RCURLY', '}'),
            Token('ID', 'x'), Token('LBRACE', '['), Token('INTEGER', '2'), Token('RBRACE', ']'), Token('EQUAL', '='), Token('ID', 'wildcat'), Token('SEMI', ';')
        ])

        expected = ast.Block([
            ast.Declaration(
                'int',
                [ast.ArrayRef(ast.ID('x'), ast.Integer(3)), ast.ID('duck'), ast.ID('goose'), ast.ID('wildcat')]
            ),
            ast.Assignment(ast.ID('duck'), ast.Integer(1)),
            ast.Assignment(ast.ID('goose'), ast.Integer(2)),

            ast.Assignment(ast.ArrayRef(ast.ID('x'), ast.Integer(0)), ast.ID('duck')),
            ast.Assignment(ast.ArrayRef(ast.ID('x'), ast.ID('duck')), ast.ID('goose')),

            ast.IfStatement(
                ast.BinOp('+', ast.ID('duck'), ast.ArrayRef(ast.ID('x'), ast.ID('duck'))),
                ast.Block([
                    ast.Assignment(ast.ID('wildcat'), ast.ID('duck'))
                ]),
                ast.Block([
                    ast.Assignment(ast.ID('wildcat'), ast.ID('goose'))
                ])
            ),

            ast.Assignment(ast.ArrayRef(ast.ID('x'), ast.Integer(2)), ast.ID('wildcat')),
        ])

        result = parser.parse(given)

        assert expected == result
예제 #7
0
 def ifelse_statement(s):
     return ast.IfStatement(s[2], s[4], s[6])
예제 #8
0
 def if_statement(s):
     return ast.IfStatement(s[2], s[4], ast.Block([]))