예제 #1
0
def test_three_args():
    scope = Scope()

    # module ThreeArgTest = add 1 2 3 where { add x y z = x + y + z }
    module = Module(
        id=Identifier("ThreeArgTest"),
        expr=FunctionApplication(func=FunctionApplication(
            func=FunctionApplication(func=Identifier("add"), expr=Double(1)),
            expr=Double(2)),
                                 expr=Double(3)),
        decls=[
            FunctionDeclaration(
                scope,
                id=Identifier("add"),
                params=[Identifier("x"),
                        Identifier("y"),
                        Identifier("z")],
                expr=BinaryOperator(expr1=BinaryOperator(
                    expr1=Identifier("x"),
                    op=Operator("+"),
                    expr2=Identifier("y")),
                                    op=Operator("+"),
                                    expr2=Identifier("z")))
        ])

    check(module, 6.0, scope)
예제 #2
0
def test_char_function():
    scope = Scope()

    # module CharFuncTest = c where { c = 'c' }
    module = Module(
        id=Identifier("CharFuncTest"),
        expr=Identifier("c"),
        decls=[FunctionDeclaration(scope, id=Identifier("c"), expr=Char("c"))])

    check(module, "c")
예제 #3
0
def test_zero_args():
    scope = Scope()

    # module ZeroArgTest = x where { x = 3 }
    module = Module(
        id=Identifier("ZeroArgTest"),
        expr=Identifier("x"),
        decls=[FunctionDeclaration(scope, id=Identifier("x"), expr=Int(3))])

    check(module, 3, scope)
예제 #4
0
def check(module, expected_output, scope=None):
    """Checks the given Module AST against the expected output (converted to a string)."""
    if not scope:
        scope = Scope()

    module.emit(scope)
    try:
        assert run(module.id.value).lower() == str(expected_output).lower()
        subprocess.run('rm -f *.j *.class', shell=True)
    except:
        if DELETE_ON_FAIL:
            subprocess.run('rm -f *.j *.class', shell=True)
        raise
예제 #5
0
def test_data_constructor():
    scope = Scope()

    # module DataConstructorTest = Foo where { data Bar = Foo; }
    module = Module(id=Identifier("DataConstructorTest"),
                    expr=Constr(id=Identifier("Foo")),
                    decls=[
                        DataTypeDeclaration(
                            scope,
                            id=Identifier("Bar"),
                            constrs=[Constr(id=Identifier("Foo"))])
                    ])

    check(module, "Foo", scope)
예제 #6
0
def test_list_function():
    scope = Scope()

    # module ListFunctionTest = testlist [3, 4] where { testlist x = x }
    module = Module(id=Identifier("ListFunctionTest"),
                    expr=FunctionApplication(
                        func=Identifier("testlist"),
                        expr=Lists(exprs=[Int(3), Int(4)])),
                    decls=[
                        FunctionDeclaration(scope,
                                            id=Identifier("testlist"),
                                            params=[Identifier("x")],
                                            expr=Identifier("x"))
                    ])

    check(module, [3, 4], scope)
예제 #7
0
def test_one_arg():
    scope = Scope()

    # module OneArgTest = f 2 where { f x = x * 3 }
    module = Module(
        id=Identifier("OneArgTest"),
        expr=FunctionApplication(func=Identifier("f"), expr=Int(2)),
        decls=[
            FunctionDeclaration(scope,
                                id=Identifier("f"),
                                params=[Identifier("x")],
                                expr=BinaryOperator(expr1=Identifier("x"),
                                                    op=Operator("*"),
                                                    expr2=Int(3)))
        ])

    check(module, 6, scope)
예제 #8
0
def test_int_operators():
    scope = Scope()

    # module IntOperatorsTest = x + 1 where { x = 3 * 2 }
    module = Module(id=Identifier("IntOperatorsTest"),
                    expr=BinaryOperator(expr1=Identifier("x"),
                                        op=Operator("+"),
                                        expr2=Int(1)),
                    decls=[
                        FunctionDeclaration(scope,
                                            id=Identifier("x"),
                                            expr=BinaryOperator(
                                                expr1=Int(3),
                                                op=Operator("*"),
                                                expr2=Int(2)))
                    ])
    check(module, 7, scope)
예제 #9
0
def test_data_inequality():
    scope = Scope()

    # module DataEqualityTest = X == Y where { data T = X | Y; }
    module = Module(id=Identifier("DataInequalityTest"),
                    expr=BinaryOperator(expr1=Constr(id=Identifier("X")),
                                        op=Operator("=="),
                                        expr2=Constr(id=Identifier("Y"))),
                    decls=[
                        DataTypeDeclaration(scope,
                                            id=Identifier("T"),
                                            constrs=[
                                                Constr(id=Identifier("X")),
                                                Constr(id=Identifier("Y"))
                                            ])
                    ])

    check(module, False, scope)
예제 #10
0
def test_double_operators():
    scope = Scope()

    # module DoubleOperatorsTest = x + 3.5 where { x = 3.0 * 7.0 }
    module = Module(id=Identifier("DoubleOperatorsTest"),
                    expr=BinaryOperator(expr1=Identifier("x"),
                                        op=Operator("+"),
                                        expr2=Double(3.5)),
                    decls=[
                        FunctionDeclaration(scope,
                                            id=Identifier("x"),
                                            expr=BinaryOperator(
                                                expr1=Double(3.0),
                                                op=Operator("*"),
                                                expr2=Double(7.0)))
                    ])

    check(module, 24.5, scope)
예제 #11
0
def test_partial_application():
    scope = Scope()

    # module PartialApplicationTest = add 3 where { add x y = x + y }
    module = Module(id=Identifier("PartialApplicationTest"),
                    expr=FunctionApplication(func=Identifier("add"),
                                             expr=Int(3)),
                    decls=[
                        FunctionDeclaration(
                            scope,
                            id=Identifier("add"),
                            params=[Identifier("x"),
                                    Identifier("y")],
                            expr=BinaryOperator(expr1=Identifier("x"),
                                                op=Operator("+"),
                                                expr2=Identifier("y")))
                    ])

    check(module, 'addFunction with bound parameters: (3)', scope)
예제 #12
0
def test_two_args():
    scope = Scope()

    # module TwoArgTest = mul 2.0 5.0 where { mul x y = x * y }
    module = Module(id=Identifier("TwoArgTest"),
                    expr=FunctionApplication(func=FunctionApplication(
                        func=Identifier("mul"), expr=Double(2)),
                                             expr=Double(5)),
                    decls=[
                        FunctionDeclaration(
                            scope,
                            id=Identifier("mul"),
                            params=[Identifier("x"),
                                    Identifier("y")],
                            expr=BinaryOperator(expr1=Identifier("x"),
                                                op=Operator("*"),
                                                expr2=Identifier("y")))
                    ])

    check(module, 10.0, scope)
예제 #13
0
def test_function_type_spec():
    scope = Scope()

    # module FunctionTypeSpecTest = getint 3 where { getint x = x; getint :: Int }
    module = Module(id=Identifier("FunctionTypeSpecTest"),
                    expr=FunctionApplication(func=Identifier("getint"),
                                             expr=Int(3)),
                    decls=[
                        FunctionDeclaration(scope,
                                            id=Identifier("getint"),
                                            params=[Identifier("x")],
                                            expr=Identifier("x")),
                        TypeDeclaration(
                            scope,
                            id=Identifier("getint"),
                            type=FunctionType(
                                param_type=NamedType(id=Identifier("Int")),
                                return_type=NamedType(id=Identifier("Int"))))
                    ])

    check(module, 3, scope)
예제 #14
0
    def emit(self, scope=Scope()):
        super().emit(scope)

        abstract_fn_decl = """
        .class public abstract AbstractFunction
        .super java/lang/Object
        .field protected param_number I
        .field protected remaining_params I = 1

        .method public <init>()V
            aload_0
            invokenonvirtual java/lang/Object/<init>()V
            return
        .end method
        
        .method public abstract apply(Ljava/lang/Object;)Ljava/lang/Object;
        .end method
        """

        with open('AbstractFunction.j', 'w') as abstract_fn_file:
            abstract_fn_file.write(abstract_fn_decl)