Пример #1
0
def test_length_fn():
    """
    let length = fun(l)
        if null(l)
            then 0
            else succ(length(tail(l)))
    in length([true, false])
    """
    checker = check.Checker()

    length = Ident("length")
    l = Ident("l")
    tail = Ident("tail")
    succ = Ident("succ")
    null = Ident("null")

    tail_call = Call(tail, l)
    rec_call = Call(length, tail_call)
    succ_call = Call(succ, rec_call)

    if_stmt = If(Call(null, l), Const(0, Int), succ_call)

    fn = Lambda(l, if_stmt)

    body = Call(length, Const([True, False], List(Bool)))
    let = Let(length, fn, body)

    inferred = let.infer_type(checker)
    assert checker.concretize(inferred) == Int
Пример #2
0
def test_bad_application():
    fn = parse.parse("""
        fn f => pair (f 3) (f true)
    """)

    checker = check.Checker()
    with pytest.raises(UnificationError):
        fn.infer_type(checker)
Пример #3
0
def test_ident():
    """
    x : int
    """
    checker = check.Checker()
    x = Ident("x")
    checker.type_env[x] = Int
    assert x.infer_type(checker) == Int
Пример #4
0
def test_const():
    """
    3 : int
    """
    checker = check.Checker()
    three = Const(3, Int)
    assert three.infer_type(checker) == Int

    t = Const(True, Bool)
    assert t.infer_type(checker) == Bool
Пример #5
0
def test_parser_let():
    checker = check.Checker()
    let = parse.parse("""
        let
          val f = fn x => x
        in
          pair (f 3) (f true)
        end
    """)
    inferred = let.infer_type(checker)
    assert checker.concretize(inferred) == Tuple(Int, Bool)
Пример #6
0
def test_complex_let():
    let = parse.parse("""
        let
          val f = fn a => a
        in
          pair (f 3) (f true)
        end
    """)

    checker = check.Checker()
    inferred = let.infer_type(checker)
    assert checker.concretize(inferred) == Tuple(Int, Bool)
Пример #7
0
def test_simple_let():
    let: Let = parse.parse("""
        let
          val x = 3
        in
          x
        end
    """)

    checker = check.Checker()
    assert checker.concretize(let.infer_type(checker)) == Int
    assert let.right.type == Int
Пример #8
0
def test_instantiation_call():
    """
    define id = fun(x) x;
    id(3) : int
    """
    checker = check.Checker()

    id = Lambda(Ident("x"), Ident("x"))
    checker.type_env[Ident("id")] = id.infer_type(checker)

    call = Call(Ident("id"), Const(3, Int))
    assert checker.concretize(call.infer_type(checker)) == Int
Пример #9
0
def test_lambda():
    """
    fun(x) x : t -> t
    """
    checker = check.Checker()

    id = Lambda(Ident("x"), Ident("x"))
    id_type = id.infer_type(checker)

    T = checker.fresh_var()
    equiv_type = Fn(T, T)
    checker.unify(id_type, equiv_type)
    assert True
Пример #10
0
def repl():
    checker = check.Checker()

    while True:
        inp = input("==> ")

        try:
            ast = parse.parse(inp)
        except rply.errors.LexingError as err:
            idx = err.source_pos.idx
            lineno = err.source_pos.lineno
            colno = err.source_pos.colno

            if lineno < 0 and colno < 0:
                pos = f"at index {idx}"
            else:
                pos = f"on line {lineno}, column {colno} "

            print(f"Lexing Error: Unexpected character {pos}!")
            continue
        except rply.errors.ParsingError as err:
            lineno = err.source_pos.lineno
            colno = err.source_pos.colno
            print(
                f"Parsing Error: Unexpected token on line {lineno}, column {colno}!"
            )
            continue

        try:
            t = ast.infer_type(checker)
            t = checker.unifiers.concretize(t)
            print(f"_ : {t}")
        except env.EnvKeyError as err:
            print(f"Semantic Error: Unrecognized symbol '{err.key}'!")
            continue
        except unifier_set.UnificationError as err:
            print(err.msg)
            continue
Пример #11
0
def test_two_arg_fn_call():
    call = parse.parse("pair 3 true")
    checker = check.Checker()
    assert checker.concretize(call.infer_type(checker)) == Tuple(Int, Bool)
Пример #12
0
def test_lambda_zero():
    fn: Lambda = parse.parse("fn x => zero x")
    checker = check.Checker()
    fn_type = fn.infer_type(checker)
    assert checker.concretize(fn_type) == Fn(Int, Bool)
    assert fn.body.type == Bool