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
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
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
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
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
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
def ifelse_statement(s): return ast.IfStatement(s[2], s[4], s[6])
def if_statement(s): return ast.IfStatement(s[2], s[4], ast.Block([]))