Beispiel #1
0
    def test_expr_comma_seq(self):
        self._assert_parse_fails("", "expr_comma_seq")

        parse.quiet_parse("1", "expr_comma_seq").should.equal([self.one])
        parse.quiet_parse("1, 2", "expr_comma_seq").should.equal(
            [self.one, self.two]
        )
Beispiel #2
0
 def test_simple_pattern_seq(self):
     self._assert_parse_fails("", "simple_pattern_seq")
     red, blue = ast.Pattern("Red"), ast.Pattern("Blue")
     parse.quiet_parse("Red", "simple_pattern_seq").should.equal([red])
     parse.quiet_parse("Red Blue", "simple_pattern_seq").should.equal(
         [red, blue]
     )
Beispiel #3
0
    def test_quiet_parse(self):
        mock = error.LoggerMock()
        p1 = parse.Parser(logger=mock)
        (parse.quiet_parse("")).should.equal(p1.parse(""))

        p2 = parse.Parser(start='type')
        (parse.quiet_parse("int", start='type')).should.equal(p2.parse("int"))
Beispiel #4
0
 def test_if_expr(self):
     parse.quiet_parse("if true then 1 else 2", "expr").should.equal(
         ast.IfExpression(self.true, self.one, self.two)
     )
     parse.quiet_parse("if true then ()", "expr").should.equal(
         ast.IfExpression(self.true, self.unit)
     )
Beispiel #5
0
 def test_constr(self):
     parse.quiet_parse("Node", "constr").should.equal(
         ast.Constructor("Node", [])
     )
     parse.quiet_parse("Node of int", "constr").should.equal(
         ast.Constructor("Node", [ast.Int()])
     )
Beispiel #6
0
    def test_simple_variable_def(self):
        foo_var = ast.VariableDef("foo")
        parse.quiet_parse("mutable foo : int", "def").should.equal(
            ast.VariableDef("foo", ast.Ref(ast.Int()))
        )

        parse.quiet_parse("mutable foo", "def").should.equal(foo_var)
Beispiel #7
0
    def test_constr_pipe_seq(self):
        self._assert_parse_fails("", "constr_pipe_seq")

        parse.quiet_parse("Black | White", "constr_pipe_seq").should.equal(
            [ast.Constructor("Black"),
             ast.Constructor("White")]
        )
Beispiel #8
0
    def test_simple_expr_seq(self):
        self._assert_parse_fails("", "simple_expr_seq")

        parse.quiet_parse("1", "simple_expr_seq").should.equal([self.one])
        parse.quiet_parse("1 2", "simple_expr_seq").should.equal(
            [self.one, self.two]
        )
Beispiel #9
0
    def test_constant_def(self):
        parse.quiet_parse("let x = 1", "def").should.equal(
            ast.ConstantDef("x", self.one)
        )

        parse.quiet_parse("let x : int = 1", "def").should.equal(
            ast.ConstantDef("x", self.one, ast.Int())
        )
Beispiel #10
0
    def test_tdef(self):
        parse.quiet_parse("color = Red", "tdef").should.equal(
            ast.TDef(ast.User("color"), [ast.Constructor("Red")])
        )

        parse.quiet_parse("int = Red", "tdef").should.equal(
            ast.TDef(ast.Int(), [ast.Constructor("Red")])
        )
Beispiel #11
0
    def test_param(self):
        parse.quiet_parse("my_parameter", "param").should.equal(
            ast.Param("my_parameter")
        )
        parse.quiet_parse("(my_parameter: int)", "param").should.equal(
            ast.Param("my_parameter", ast.Int())
        )

        self._assert_parse_fails("my_parameter: int", "param")
Beispiel #12
0
    def test_dim_expr(self):
        parsed = parse.quiet_parse("dim name", "expr")
        parsed.should.be.an(ast.DimExpression)
        parsed.name.should.equal("name")

        parsed = parse.quiet_parse("dim 2 name", "expr")
        parsed.should.be.an(ast.DimExpression)
        parsed.name.should.equal("name")
        parsed.dimension.should.equal(2)
Beispiel #13
0
    def test_param_seq(self):
        self._assert_parse_fails("", "param_seq")

        parse.quiet_parse("my_param", "param_seq").should.equal(
            [ast.Param("my_param")]
        )

        parse.quiet_parse("a b", "param_seq").should.equal(
            [ast.Param("a"), ast.Param("b")]
        )
Beispiel #14
0
    def test_clause_seq(self):
        self._assert_parse_fails("", "clause_seq")

        clause1 = ast.Clause(self.one, self.two)
        clause2 = ast.Clause(self.true, self.false)
        parse.quiet_parse(
            "1 -> 2 | true -> false", "clause_seq"
        ).should.equal(
            [clause1, clause2]
        )
Beispiel #15
0
 def test_letdef(self):
     parse.quiet_parse("let x = 1", "letdef").should.equal(
         ast.LetDef(
             [ast.FunctionDef("x", [], self.one)]
         )
     )
     parse.quiet_parse("let rec x = 1", "letdef").should.equal(
         ast.LetDef(
             [ast.FunctionDef("x", [], self.one)], True
         )
     )
Beispiel #16
0
    def test_tdef_and_seq(self):
        self._assert_parse_fails("", "tdef_and_seq")

        parse.quiet_parse(
            "color = Red and shoes = Slacks", "tdef_and_seq"
        ).should.equal(
            [
                ast.TDef(ast.User("color"), [ast.Constructor("Red")]),
                ast.TDef(ast.User("shoes"), [ast.Constructor("Slacks")])
            ]
        )
Beispiel #17
0
    def _assert_non_equivalent(self, expr1, expr2=None, start="expr"):
        """
        Assert that two expressions are not parsed as equivalent ASTs.
        The API is similar to _assert_equivalent.
        """

        if expr2 is None:
            # sequence of expressions
            exprs = expr1
            for expr1, expr2 in exprs:
                self._assert_non_equivalent(expr1, expr2, start)
        else:
            parsed1 = parse.quiet_parse(expr1, start)
            parsed2 = parse.quiet_parse(expr2, start)
            parsed1.shouldnt.equal(parsed2)
Beispiel #18
0
    def test_function_def(self):
        parse.quiet_parse("let x y (z:int) = 1", "def").should.equal(
            ast.FunctionDef(
                "x",
                [ast.Param("y"), ast.Param("z", ast.Int())],
                self.one
            )
        )

        parse.quiet_parse("let x y z:int = 1", "def").should.equal(
            ast.FunctionDef(
                "x",
                [ast.Param("y"), ast.Param("z")], self.one, ast.Int()
            )
        )
Beispiel #19
0
    def test_for_expr(self):
        parse.quiet_parse("for i = 1 to 2 do () done", "expr").should.equal(
            ast.ForExpression(
                "i", self.one, self.two, self.unit
            )
        )

        parse.quiet_parse(
            "for i = 2 downto 1 do () done",
            "expr"
        ).should.equal(
            ast.ForExpression(
                "i", self.two, self.one, self.unit, True
            )
        )
Beispiel #20
0
 def _check_binary_operator(self, operator):
     expr = "1 %s 2" % operator
     parsed = parse.quiet_parse(expr, "expr")
     parsed.should.be.an(ast.BinaryExpression)
     parsed.operator.should.equal(operator)
     parsed.leftOperand.should.equal(self.one)
     parsed.rightOperand.should.equal(self.two)
Beispiel #21
0
    def test_type_process_wrong(self):
        wrong_testcases = (
            (
                (
                    "type bool = BoolCon",
                    "type char = CharCon",
                    "type float = FloatCon",
                    "type int = IntCon",
                    "type unit = UnitCon",
                ),
                type.RedefBuiltinTypeError,
                1
            ),
            (
                (
                    "type dup = ConDup | ConDup",
                    """
                    type one = Con
                    type two = Con
                    """,
                ),
                type.RedefConstructorError,
                2
            ),
            (
                (
                    """
                    type same = Foo1
                    type same = Foo2
                    """,
                ),
                type.RedefUserTypeError,
                2
            ),
            (
                (
                    "type what = What of undeftype",
                ),
                type.UndefTypeError,
                1
            )
        )

        for cases, error, exc_node_count in wrong_testcases:
            for case in cases:
                table = type.Table()
                tree = parse.quiet_parse(case)
                with self.assertRaises(error) as context:
                    for typeDefList in tree:
                        table.process(typeDefList)

                exc = context.exception
                exc.should.have.property("node")
                self._assert_node_lineinfo(exc.node)
                if exc_node_count == 2:
                    exc.should.have.property("prev")
                    exc.prev.shouldnt.be(exc.node)
                    self._assert_node_lineinfo(exc.prev)
Beispiel #22
0
    def setUpClass(cls):
        cls.one = parse.quiet_parse("1", "expr")
        cls.two = parse.quiet_parse("2", "expr")
        cls.true = parse.quiet_parse("true", "expr")
        cls.false = parse.quiet_parse("false", "expr")
        cls.unit = parse.quiet_parse("()", "expr")

        cls.xfunc = parse.quiet_parse("let x = 1", "letdef")
        cls.yfunc = parse.quiet_parse("let y = 2", "letdef")
Beispiel #23
0
    def _assert_equivalent(self, expr1, expr2=None, start="expr"):
        """
        Assert that two expressions are parsed into equivalent ASTs.
        You can pass either two expressions (expr1, expr2) or a sequence
        of expression tuples as expr1, leaving expr2 to None.
        """

        if expr2 is None:
            # sequence of expressions
            exprs = expr1
            for expr1, expr2 in exprs:
                self._assert_equivalent(expr1, expr2, start)
        else:
            # self.assertEqual(
            #     parse.quiet_parse(expr1, "expr"),
            #     parse.quiet_parse(expr2, "expr"),
            #     "'%s' must equal '%s'" % (expr1, expr2)
            # )
            parsed1 = parse.quiet_parse(expr1, start)
            parsed2 = parse.quiet_parse(expr2, start)
            parsed1.should.equal(parsed2)
Beispiel #24
0
    def test_def_list(self):
        parse.quiet_parse("", "def_list").should.equal([])

        parse.quiet_parse("let x = 1", "def_list").should.equal([self.xfunc])

        parse.quiet_parse("let x = 1 let y = 2", "def_list").should.equal(
            [self.xfunc, self.yfunc]
        )
Beispiel #25
0
    def test_is_array(self):
        for typecon in ast.builtin_types_map.values():
            self.assertFalse(typesem.is_array(typecon()))

        right_testcases = (
            "array of int",
            "array of foo",
            "array [*, *] of int"
        )

        for case in right_testcases:
            tree = parse.quiet_parse(case, "type")
            self.assertTrue(typesem.is_array(tree))

        wrong_testcases = (
            "foo",
            "int ref",
            "int -> int",
        )

        for case in wrong_testcases:
            tree = parse.quiet_parse(case, "type")
            self.assertFalse(typesem.is_array(tree))
Beispiel #26
0
    def test_param_list(self):
        parse.quiet_parse("", "param_list").should.equal([])

        parse.quiet_parse("my_param", "param_list").should.equal(
            [ast.Param("my_param")]
        )

        parse.quiet_parse("a b", "param_list").should.equal(
            [ast.Param("a"), ast.Param("b")]
        )
Beispiel #27
0
    def test_type_process_correct(self):
        right_testcases = (
            "type color = Red | Green | Blue",
            "type list = Nil | Cons of int list",
            """
            type number = Integer of int | Real of float
                        | Complex of float float
            """,
            """
            type tree = Leaf | Node of int forest
            and  forest = Empty | NonEmpty of tree forest
            """
        )

        table = type.Table()
        proc = table.process
        for case in right_testcases:
            tree = parse.quiet_parse(case, "typedef")
            proc.when.called_with(tree).shouldnt.throw(type.InvalidTypeError)
Beispiel #28
0
    def test_validate(self):
        """Test the validating of types."""
        table = typesem.Table()
        foo_tree = parse.quiet_parse("type foo = Foo")
        for typeDefList in foo_tree:
            table.process(typeDefList)

        proc = table.validate
        error = typesem.InvalidTypeError

        for typecon in ast.builtin_types_map.values():
            proc.when.called_with(typecon()).shouldnt.throw(error)

        right_testcases = (
            "foo",

            "int ref",
            "foo ref",
            "(int -> int) ref",
            "(int ref) ref",

            "array of int",
            "array of foo",
            "array of (int ref)",
            "array of (foo ref)",
            "array [*, *] of int",

            "int -> int",
            "foo -> int",
            "int -> foo",
            "int ref -> int",
            "int -> (int ref)",
            "(array of int) -> int",
            "int -> (array of int -> int)",
            "(int -> int) -> int"
        )

        for case in right_testcases:
            tree = parse.quiet_parse(case, "type")
            proc.when.called_with(tree).shouldnt.throw(error)

        wrong_testcases = (
            (
                (
                    "array of (array of int)",
                    "(array of (array of int)) -> int",
                    "((array of (array of int)) -> int) ref",
                ),
                typesem.ArrayOfArrayError
            ),
            (
                (
                    "(array of int) ref",
                    "((array of int) ref) -> int",
                    "array of ((array of int) ref)",
                ),
                typesem.RefOfArrayError
            ),
            (
                (
                    "int -> array of int",
                    "int -> (int -> array of int)",
                    "(int -> array of int) ref",
                ),
                typesem.ArrayReturnError
            ),
            (
                (
                    "undeftype",
                ),
                typesem.UndefTypeError
            )
        )

        for cases, error in wrong_testcases:
            for case in cases:
                tree = parse.quiet_parse(case, "type")
                with self.assertRaises(error) as context:
                    proc(tree)
                exc = context.exception
                exc.should.have.property("node")

                self._assert_node_lineinfo(exc.node)
Beispiel #29
0
    def test_process(self):
        right_testcases = (
            "type color = Red | Green | Blue",
            "type list = Nil | Cons of int list",
            """
            type number = Integer of int | Real of float
                        | Complex of float float
            """,
            """
            type tree = Leaf | Node of int forest
            and  forest = Empty | NonEmpty of tree forest
            """
        )

        table = typesem.Table()
        proc = table.process
        for case in right_testcases:
            tree = parse.quiet_parse(case, "typedef")
            proc.when.called_with(tree).shouldnt.throw(
                typesem.InvalidTypeError
            )

        wrong_testcases = (
            (
                (
                    "type bool = BoolCon",
                    "type char = CharCon",
                    "type float = FloatCon",
                    "type int = IntCon",
                    "type unit = UnitCon",
                ),
                typesem.RedefBuiltinTypeError,
                1
            ),
            (
                (
                    "type dup = ConDup | ConDup",
                    """
                    type one = Con
                    type two = Con
                    """,
                ),
                typesem.RedefConstructorError,
                2
            ),
            (
                (
                    """
                    type same = Foo1
                    type same = Foo2
                    """,
                ),
                typesem.RedefUserTypeError,
                2
            ),
            (
                (
                    "type what = What of undeftype",
                ),
                typesem.UndefTypeError,
                1
            ),
            (
                (
                    "type invalid = Foo of (array of int) ref",
                ),
                typesem.RefOfArrayError,
                1
            )
        )

        for cases, error, exc_node_count in wrong_testcases:
            for case in cases:
                table = typesem.Table()
                tree = parse.quiet_parse(case)
                with self.assertRaises(error) as context:
                    for typeDefList in tree:
                        table.process(typeDefList)

                exc = context.exception
                exc.should.have.property("node")
                self._assert_node_lineinfo(exc.node)
                if exc_node_count == 2:
                    exc.should.have.property("prev")
                    exc.prev.shouldnt.be(exc.node)
                    self._assert_node_lineinfo(exc.prev)
Beispiel #30
0
 def test_table_process(self):
     tree = parse.quiet_parse("type foo = Foo of int", "typedef")
     typesem.Table().process(tree)