コード例 #1
0
def test_user_operators(op):
    assume(not op.startswith("--"))
    assert (
        parse(f"a {op} b")
        == parse(f"({op}) a b")
        == Application(Application(Identifier(op), Identifier("a")), Identifier("b"))
    )
コード例 #2
0
def test_wfe_float_literals(n):
    code = f"{n!r:.60}"
    assert parse(code) == Literal(n, NumberType)

    assert parse("1_000_.500") == Literal(1000.5, NumberType)
    assert parse("_1e+10") == Application(
        Application(Identifier("+"), Identifier("_1e")), Literal(10, NumberType)
    )
    with pytest.raises(LarkError):
        tokenize("_0.1")
コード例 #3
0
def test_list_cons_operator():
    assert (
        parse("a:b:xs")
        == parse("a:(b:xs)")
        == Application(
            Application(Identifier(":"), Identifier("a")),
            Application(
                Application(Identifier(":"), Identifier("b")), Identifier("xs")
            ),
        )
    )
コード例 #4
0
def test_annotated_numbers():
    assert parse("1e+10@km") == Literal(1e10, NumberType, Identifier("km"))
    assert parse('1e+10@"km"') == Literal(1e10, NumberType, Literal("km", StringType))
    assert parse("1e+10@'m'") == Literal(1e10, NumberType, Literal("m", CharType))

    assert parse("1e+10 @ km") == Application(
        Application(Identifier("@"), Literal(1e10, NumberType)), Identifier("km")
    )

    assert parse("a @ b") == Application(
        Application(Identifier("@"), Identifier("a")), Identifier("b")
    )
コード例 #5
0
def test_pattern_matching_let():
    code = """let if True t f = t
                  if False t f = f
              in g . if"""
    result = parse(code)
    expected = ConcreteLet(
        [
            Equation("if", [ConsPattern("True"), "t", "f"], Identifier("t")),
            Equation("if", [ConsPattern("False"), "t", "f"], Identifier("f")),
        ],
        Application(Application(Identifier("."), Identifier("g")), Identifier("if")),
    )
    assert result == expected
コード例 #6
0
def test_wfe_composition():
    assert (
        parse("a . b")
        == parse("(.) a b")
        == Application(Application(Identifier("."), Identifier("a")), Identifier("b"))
    )
    assert parse("a . b . c") == parse("a . (b . c)")

    # yay! partial application
    assert parse("((.) a) b") == parse("a . b")
    assert parse("(.)a") == Application(Identifier("."), Identifier("a"))

    # Application is stronger than composition
    assert parse("a . b c") == parse("a . (b c)")
コード例 #7
0
def test_datetime_literals_application(d):
    code = f"f <{d!s}>"
    res = parse(code)
    assert res == Application(Identifier("f"), Literal(d, DateTimeType))

    code = f"f <{d!s}> x"
    res = parse(code)
    assert res == Application(
        Application(Identifier("f"), Literal(d, DateTimeType)), Identifier("x")
    )

    # Semantically incorrect but parser must accept it
    code = f"<{d!s}> x"
    res = parse(code)
    assert res == Application(Literal(d, DateTimeType), Identifier("x"))
コード例 #8
0
ファイル: match.py プロジェクト: merchise/xotl.fl
    def compile(self) -> AST:
        """Return the compiled form of the function definition.

        """
        from xotl.fl.ast.expressions import build_lambda, build_application

        # This is similar to the function `match` in 5.2 of [PeytonJones1987];
        # but I want to avoid *enlarging* simple functions needlessly.
        if self.arity:
            vars = list(namesupply(f".{self.name}_arg", limit=self.arity))
            body: AST = NO_MATCH_ERROR
            for eq in self.equations:
                dfn = eq.body
                patterns: Iterable[Tuple[str,
                                         Pattern]] = zip(vars, eq.patterns)
                for var, pattern in patterns:
                    if isinstance(pattern, str):
                        # Our algorithm is trivial but comes with a cost:
                        # ``id x = x`` is must be translated to
                        # ``id = \.id_arg0 -> (\x -> x) .id_arg0``.
                        dfn = Application(Lambda(pattern, dfn),
                                          Identifier(var))
                    elif isinstance(pattern, Literal):
                        # ``fib 0 = 1``; is transformed to
                        # ``fib = \.fib_arg0 -> <MatchLiteral 0> .fib_arg0 1``
                        dfn = build_application(
                            Identifier(MatchLiteral(pattern)),  # type: ignore
                            Identifier(var),
                            dfn,
                        )
                    elif isinstance(pattern, ConsPattern):
                        if not pattern.params:
                            # This is just a Match; similar to MatchLiteral
                            dfn = build_application(
                                Identifier(Match(
                                    pattern.cons)),  # type: ignore
                                Identifier(var),
                                dfn,
                            )
                        else:
                            for i, param in reversed(
                                    list(enumerate(pattern.params, 1))):
                                if isinstance(param, str):
                                    dfn = build_application(
                                        Identifier(Extract(pattern.cons,
                                                           i)),  # type: ignore
                                        Identifier(var),
                                        Lambda(param, dfn),
                                    )
                                else:
                                    raise NotImplementedError(
                                        f"Nested patterns {param}")
                    else:
                        assert False
                body = build_lambda(
                    vars, build_application(MATCH_OPERATOR, dfn, body))
            return body
        else:
            # This should be a simple value, so we return the body of the
            # first equation.
            return self.equations[0].body  # type: ignore
コード例 #9
0
def test_comma_as_an_operator():
    assert (
        parse("(a, b)")
        == parse("(,) a b")
        == Application(Application(Identifier(","), Identifier("a")), Identifier("b"))
    )
コード例 #10
0
def test_wfe_application():
    assert parse("a b") == Application(Identifier("a"), Identifier("b"))
    assert parse("a b c") == parse("(a b) c")
    assert parse("(a)(b)") == parse("(a)b") == parse("a(b)") == parse("a b")
    assert parse("a b") == parse("(a b)")