示例#1
0
    def test_if_statement_requires_test_to_be_boolean(self):
        test = Literal('String', 'not a boolean')
        if_case = Literal('Int', 123)
        else_case = Literal('Int', 456)
        if_block = If(test, if_case, else_case)

        if_id = if_block.add_to_rules(self._rules, self._registry)
        with self.assertRaises(InferenceError):
            self._rules.infer()
示例#2
0
    def test_if_statement_requires_branches_to_equal(self):
        test = Literal('Bool', True)
        if_case = Literal('Int', 123)
        else_case = Literal('Float', 456)
        if_block = If(test, if_case, else_case)

        if_id = if_block.add_to_rules(self._rules, self._registry)
        with self.assertRaises(InferenceError):
            self._rules.infer()
示例#3
0
    def test_if_statement(self):
        test = Literal('Bool', True)
        if_case = Literal('Int', 123)
        else_case = Literal('Int', 456)
        if_block = If(test, if_case, else_case)

        if_id = if_block.add_to_rules(self._rules, self._registry)
        result = self._rules.infer()

        self.assertEqual('Int', result.get_type_by_id(if_id))
示例#4
0
 def test_simple_let(self):
     l1 = Literal('Int', 123)
     l2 = Literal('Int', 456)
     lt = Let([('x', l1)], l2)
     lt_id = lt.add_to_rules(self._rules, self._registry)
     l1_id = self._registry.get_id_for(l1)
     l2_id = self._registry.get_id_for(l2)
     # TODO: the test is dependent on order for the name of var_x_1
     self.assertIn(('var_x_2', l1_id), self._rules.equal_calls)
     self.assertIn((lt_id, l2_id), self._rules.equal_calls)
     self.assertEqual([], self._rules.instance_of_calls)
     self.assertIn((l1_id, 'Int'), self._rules.specify_calls)
     self.assertIn((l2_id, 'Int'), self._rules.specify_calls)
 def primary(self):
     if self.match(TokenType.FALSE):
         return Literal(False)
     elif self.match(TokenType.TRUE):
         return Literal(True)
     elif self.match(TokenType.NIL):
         return Literal(None)
     elif self.match(TokenType.NUMBER, TokenType.STRING):
         return Literal(self.previous().literal)
     elif self.match(TokenType.LEFT_PAREN):
         expr = self.expression()
         self.consume(TokenType.RIGHT_PAREN, "Expect ')' after expression")
     else:
         self.error(self.peek(), "Expect expression")
示例#6
0
    def test_let(self):
        l = Literal('Int', 123)
        lt = Let([('x', l)], Variable('x'))
        lt_id = lt.add_to_rules(self._rules, self._registry)

        result = self._rules.infer()
        self.assertEqual('Int', result.get_type_by_id(lt_id))
示例#7
0
 def test_typed_expression_match(self):
     lit = Literal('Int', 123)
     te = TypedExpression('Int', lit)
     te_id = te.add_to_rules(self._rules, self._registry)
     lit_id = self._registry.get_id_for(lit)
     result = self._rules.infer()
     self.assertEqual('Int', result.get_type_by_id(te_id))
     self.assertEqual('Int', result.get_type_by_id(lit_id))
示例#8
0
    def test_let_with_lambda(self):
        lm = Lambda(['x'], Variable('x'))
        var_id = Variable('id')
        app = Application(var_id, [Literal('Int', 123)])
        lt = Let([('id', lm)], app)

        lt_id = lt.add_to_rules(self._rules, self._registry)
        app_id = self._registry.get_id_for(app)
        self.assertIn((lt_id, app_id), self._rules.equal_calls)
示例#9
0
 def test_simple_lambda_expression(self):
     lit = Literal('Int', 123)
     lm = Lambda(['x'], lit) # The `x` argument is unused
     lm_id = lm.add_to_rules(self._rules, self._registry)
     lit_id = self._registry.get_id_for(lit)
     # TODO: test is dependant on order for the name of var_x_2
     self.assertIn(
         (1, ('Fn_1', 'var_x_2', lit_id)),
         self._rules.specify_calls
     )
     self.assertIn((lit_id, 'Int'), self._rules.specify_calls)
示例#10
0
 def test_typed_expression(self):
     l = Literal('Int', 123)
     te = TypedExpression('Num', l)
     self.assertEqual('TypedExpression(Num, Literal(Int, 123))', repr(te))
     te_id = te.add_to_rules(self._rules, self._registry)
     l_id = self._registry.get_id_for(l)
     self.assertNotEqual(l_id, te_id)
     self.assertSetEqual(
         set([(te_id, 'Num'), (l_id, 'Int')]),
         set(self._rules.specify_calls)
     )
示例#11
0
    def test_application(self):
        self._registry.push_new_scope({'times2': ('var_times2_1', True)})
        v = Variable('times2')
        l = Literal('Int', 123)
        a = Application(v, [l])
        a_id = a.add_to_rules(self._rules, self._registry)
        v_id = self._registry.get_id_for(v)
        l_id = self._registry.get_id_for(l)

        result = self._rules.infer()
        self.assertEqual('Int', result.get_type_by_id(l_id))
        self.assertEqual(None, result.get_type_by_id(a_id))
示例#12
0
    def test_application(self):
        scoped_id = 'var_times2_1'
        self._registry.push_new_scope({'times2': (scoped_id, True)})
        v = Variable('times2')
        l = Literal('Int', 123)
        a = Application(v, [l])
        a_id = a.add_to_rules(self._rules, self._registry)
        v_id = self._registry.get_id_for(v)
        l_id = self._registry.get_id_for(l)

        self.assertIn((v_id, scoped_id), self._rules.instance_of_calls)
        self.assertIn((v_id, ('Fn_1', l_id, a_id)), self._rules.specify_calls)
示例#13
0
    def test_let(self):
        l = Literal('Int', 123)
        var_x = Variable('x')
        var_y = Variable('y')
        lt = Let([('x', var_y), ('y', l)], var_x)
        lt_id = lt.add_to_rules(self._rules, self._registry)
        l_id = self._registry.get_id_for(l)
        var_x_id = self._registry.get_id_for(var_x)
        var_y_id = self._registry.get_id_for(var_y)

        self.assertIn((lt_id, var_x_id), self._rules.equal_calls)
        self.assertIn(('var_x_2', var_y_id), self._rules.equal_calls)
        self.assertIn(('var_y_3', l_id), self._rules.equal_calls)
示例#14
0
    def test_polymorphism(self):
        ''' ML code:
        let id = \\x -> x
        in (id id) 123
        '''
        lm = Lambda(['x'], Variable('x'))
        app1 = Application(Variable('id'), [Variable('id')])
        app2 = Application(app1, [Literal('Int', 123)])
        lt = Let([('id', lm)], app2)
        lt_id = lt.add_to_rules(self._rules, self._registry)

        result = self._rules.infer()
        self.assertEqual('Int', result.get_type_by_id(lt_id))
示例#15
0
    def test_let_with_lambda(self):
        ''' ML code:
        let id = \\x -> x
        in id 'foo'
        '''
        lm = Lambda(['x'], Variable('x'))
        var_id = Variable('id')
        app = Application(var_id, [Literal('String', 'foo')])
        lt = Let([('id', lm)], app)
        lt_id = lt.add_to_rules(self._rules, self._registry)

        result = self._rules.infer()
        self.assertEqual('String', result.get_type_by_id(lt_id))
示例#16
0
    def test_mutual_recursion(self):
        '''
        Equivalent ML:

        let-rec f = if True then 123 else g
                g = f
        in f
        '''
        test = Literal('Bool', True)
        if_case = Literal('Int', 123)
        else_case = Application(Variable('g'), [])
        if_block = If(test, if_case, else_case)
        f_func = Lambda([], if_block)

        g_body = Application(Variable('f'), [])
        g_func = Lambda([], g_body)

        let_body = Variable('f')
        let_expr = Let([('f', f_func), ('g', g_func)], let_body)

        let_id = let_expr.add_to_rules(self._rules, self._registry)
        result = self._rules.infer()
        self.assertEqual(('Fn_0', 'Int'), result.get_full_type_by_id(let_id))
示例#17
0
    def test_generic_mutual_recursion(self):
        '''
        Equivalent ML:

        let-rec f x = if True then x else g x
                g y = f y
        in g
        '''
        test = Literal('Bool', True)
        if_case = Variable('x')
        else_case = Application(Variable('g'), [Variable('x')])
        if_block = If(test, if_case, else_case)
        f_func = Lambda(['x'], if_block)

        g_body = Application(Variable('f'), [Variable('y')])
        g_func = Lambda(['y'], g_body)

        let_body = Variable('f')
        let_expr = Let([('f', f_func), ('g', g_func)], let_body)

        let_id = let_expr.add_to_rules(self._rules, self._registry)
        result = self._rules.infer()
        self.assertEqual(('Fn_1', 'a0', 'a0'), result.get_full_type_by_id(let_id))
    def visitBinaryExpr(self, expr_instance):
        return self.parenthesize(expr_instance.operator.lexeme, expr_instance.left, expr_instance.right)

    def visitGroupingExpr(self, expr_instance):
        return self.parenthesize('group', expr_instance.expression);

    def visitLiteralExpr(self, expr_instance):
        if expr_instance.value == None:
            return 'nil'
        else:
            return str(expr_instance.value)

    def visitUnaryExpr(self, expr_instance):
        return self.parenthesize(expr_instance.operator, expr_instance.right)

    def parenthesize(self, name, *expressions):
        output = ''
        output += f'({name}'
        for expression in expressions:
            output += ' '
            output += expression.accept(self)
        output += ')'

        return output

if __name__ == '__main__':
    # Test to see if AstPrinter does what it should
    expression = Binary(Unary(Token(TokenType.MINUS, '-', '', 1), Literal(123)), Token(TokenType.STAR, '*', '', 1), Grouping(Literal(45.67)))
    print(AstPrinter().print(expression))
示例#19
0
 def test_literal(self):
     l = Literal('Int', 123)
     l_id = l.add_to_rules(self._rules, self._registry)
     self.assertTrue(l_id > 0)
     self.assertEqual([(l_id, 'Int')], self._rules.specify_calls)
示例#20
0
 def test_literal_repr(self):
     self.assertEqual('Literal(Int, 123)', repr(Literal('Int', 123)))
示例#21
0
 def test_literal(self):
     l = Literal('Int', 123)
     l_id = l.add_to_rules(self._rules, self._registry)
     self.assertEqual(Result({l_id: 'Int'}, {}), self._rules.infer())
示例#22
0
 def test_typed_expression_mismatch(self):
     te = TypedExpression('String', Literal('Int', 123))
     te_id = te.add_to_rules(self._rules, self._registry)
     with self.assertRaises(InferenceError):
         self._rules.infer()