def test_new_type_node_and_let_node(): program_ast = ProgramNode([ ClassNode('Main', features=[ MethodNode( 'main', [], 'Int', BlockNode([ LetVarNode([(('io', 'IO'), NewTypeNode('IO'))], DispatchNode('out_string', [StrNode('Hello World')], ObjectNode('io'))), LetVarNode([(('i', 'Int'), IntNode(0))], AssignNode(ObjectNode('i'), IntNode(4))), IntNode(0) ])) ]) ]) program_code = ''' class Main { main() : Int { { let io: IO <- new IO in io.out_string("Hello World"); let i: Int <- 0 in i <- 4; 0; } }; }; ''' parser_result = parser.parse(program_code, lexer=lexer) verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_let_statement_with_three_vars(): program = """ class A { funk():Type { let x:TypeX, y:TypeY <- 3, z:ZType <- (2 + 2) * 5 in x + 1 }; };""" expected = ProgramNode([ ClassNode( 'A', 'Object', [ MethodNode( 'funk', [], 'Type', LetVarNode( [ (('x', 'TypeX'), None), (('y', 'TypeY'), IntNode(3)), # (('z', 'ZType'), PlusNode(IntNode(2),StarNode(IntNode(2),IntNode(5))))], (('z', 'ZType'), StarNode(PlusNode(IntNode(2), IntNode(2)), IntNode(5))) ], PlusNode(ObjectNode('x'), IntNode(1)))), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_loop_check(): program_ast = ProgramNode([ ClassNode( 'Main', features=[ MethodNode( 'main', [], 'Object', BlockNode([ LoopNode( BoolNode('true'), BlockNode([ ConditionalNode( LowerEqualThanNode(IntNode(2), IntNode(3)), BlockNode([ LetVarNode([ (('io', 'IO'), NewTypeNode('IO')) ], DispatchNode( 'out_string', [StrNode('True')], ObjectNode('io'))), ]), BlockNode([ LetVarNode([ (('io', 'IO'), NewTypeNode('IO')) ], DispatchNode( 'out_string', [StrNode('False')], ObjectNode('io'))) ])) ])), IntNode(0) ])) ]) ]) program_code = ''' class Main { main() : Object {{ while true loop { if 2<=3 then { let io: IO <- new IO in io.out_string("True"); } else { let io: IO <- new IO in io.out_string("False"); } fi; } pool; 0;} }; }; ''' parser_result = parser.parse(program_code, lexer=lexer) verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_class_with_method_without_formals(): program = """class A { funk():ReturnType { returnvalue }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [], 'ReturnType', ObjectNode('returnvalue')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_class_with_method_returning_str(): program = """class A { funk():ReturnType { "blabla" }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [], 'ReturnType', StrNode('"blabla"')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_class_with_method_with_formals(): program = """class A { funk(x:X, y:Y):ReturnType { x }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [('x', 'X'), ('y', 'Y')], 'ReturnType', ObjectNode('x')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_class_with_initialized_attributes(): program = """ class A { attr1:AttrType <- otherObj; attr2: AttrType <- initialObj; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ AttributeNode('attr1', 'AttrType', ObjectNode('otherObj')), AttributeNode('attr2', 'AttrType', ObjectNode('initialObj')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_new(): program = """ class A { funk():Type { new B }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [], 'Type', NewTypeNode('B')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_isvoid(): program = """ class A { funk():Type { isvoid b }; };""" expected = ProgramNode([ ClassNode( 'A', 'Object', [MethodNode('funk', [], 'Type', IsVoidNode(ObjectNode('b')))]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_simple_dispatch_with_one_arg(): program = """ class A { funk():Type { obj.method(2) }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [], 'Type', DispatchNode('method', [IntNode(2)], ObjectNode('obj'))) ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_new_type_node_and_let_node2(): program_ast = ProgramNode([ ClassNode( 'Main', features=[ MethodNode( 'main', [], 'Int', BlockNode([ LetVarNode([(('io', 'IO'), NewTypeNode('IO'))], DispatchNode('out_string', [StrNode('"Hello World"')], ObjectNode('io'))), LetVarNode([(('a', 'A'), NewTypeNode("A")), (('b', 'Int'), None)], PlusNode( DispatchNode('funk', [(BoolNode('true'))], ObjectNode('a')), ObjectNode('b'))) ])) ]), ClassNode('A', features=[ MethodNode( 'funk', [('a', 'Bool')], 'Int', LetVarNode([(('x', 'Int'), None)], PlusNode(ObjectNode('x'), IntNode(1)))) ]) ]) program_code = ''' class Main { main() : Int { { let io: IO <- new IO in io.out_string("Hello World"); let a:A <- new A, b: Int in a.funk() + b; } }; }; class A { funk():Int { let x:Int in x + 1 }; }; ''' parser_result = parser.parse(program_code, lexer=lexer) # verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_static_dispatch_with_no_args(): program = """ class A { funk():Type { [email protected]() }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', StaticDispatchNode('method', [], ObjectNode('obj'), 'Klass')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_if_statements(): program = """ class A { funk():Type { if x < 0 then 1 else 2 fi }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', ConditionalNode(LowerThanNode(ObjectNode('x'), IntNode(0)), IntNode(1), IntNode(2))), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_while_statements(): program = """ class A { funk():Type { while x < 0 loop 1 pool }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', LoopNode(LowerThanNode(ObjectNode('x'), IntNode(0)), IntNode(1))), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_let_statement(): program = """ class A { funk():Type { let x:TypeX in x + 1 }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', LetVarNode([(('x', 'TypeX'), None)], PlusNode(ObjectNode('x'), IntNode(1)))), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_class_with_method_with_block(): program = """ class A inherits WithVar { set_var(num : Int) : SELF_TYPE { { self; } }; };""" expected = ProgramNode([ ClassNode('A', 'WithVar', [ MethodNode('set_var', [('num', 'Int')], 'SELF_TYPE', BlockNode([ObjectNode('self')])), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_not(): program = """ class A { funk():Type { case not 1 of x:Int => 10; esac }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', CaseNode(NotNode(IntNode(1)), [(('x', 'Int'), IntNode(10))])), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_case(): program = """ class A { funk():Type { case 1 of x:Int => 10; x:String => 9; x:Guru => 8; esac }; };""" expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode( 'funk', [], 'Type', CaseNode(IntNode(1), [(('x', 'Int'), IntNode(10)), (('x', 'String'), IntNode(9)), (('x', 'Guru'), IntNode(8))])) ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_two_classes_defined(): program = """ class A { funk():Type { a }; }; class B { funk():Type { a }; }; """ expected = ProgramNode([ ClassNode('A', 'Object', [ MethodNode('funk', [], 'Type', ObjectNode('a')), ]), ClassNode('B', 'Object', [ MethodNode('funk', [], 'Type', ObjectNode('a')), ]) ]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_hello_world(): program_ast = ProgramNode([ ClassNode('Main', features=[ MethodNode( 'main', [], 'IO', DispatchNode('out_string', [StrNode('Hello, World')], None)) ], inherit='IO') ]) program_code = ''' class Main inherits IO { main(): IO { --Hola afafaf-- out_string("Hello, World") }; }; ''' parser_result = parser.parse(program_code, lexer=lexer) verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_conditional(): program_ast = ProgramNode([ ClassNode( 'Main', features=[ MethodNode( 'main', [], 'IO', BlockNode([ ConditionalNode( LowerEqualThanNode(IntNode(2), IntNode(3)), LetVarNode([(('io', 'IO'), NewTypeNode('IO'))], DispatchNode('out_string', [StrNode('True')], ObjectNode('io'))), LetVarNode([(('io', 'IO'), NewTypeNode('IO'))], DispatchNode('out_string', [StrNode('False')], ObjectNode('io')))) ])) ]) ]) program_code = ''' class Main { main() : IO { { if 2<=3 then let io: IO <- new IO in io.out_string("True") else let io: IO <- new IO in io.out_string("False") fi; } }; }; ''' parser_result = parser.parse(program_code, lexer=lexer) verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_class_definition_with_inherits(): program = "class A inherits Top { };" expected = ProgramNode([ClassNode('A', 'Top')]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_empty_class_definition(): program = "class A { };" expected = ProgramNode([ClassNode('A', 'Object')]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)
def test_case(): program_ast = ProgramNode([ ClassNode( 'Main', features=[ MethodNode( 'main', [], 'Int', BlockNode([ LoopNode( LowerThanNode(IntNode(1), IntNode(2)), BlockNode([ CaseNode( PlusNode(IntNode(1), IntNode(2)), [(('id1', 'Int'), PlusNode(ObjectNode('id1'), IntNode(5))), (('id2', 'Object'), ObjectNode('id2')), (('id3', 'String'), ObjectNode('id3'))]), ConditionalNode( LowerEqualThanNode(IntNode(2), IntNode(3)), BlockNode([ LetVarNode([ (('io', 'IO'), NewTypeNode('IO')) ], DispatchNode( 'out_string', [StrNode('True')], ObjectNode('io'))), ]), BlockNode([ LetVarNode([ (('io', 'IO'), NewTypeNode('IO')) ], DispatchNode( 'out_string', [StrNode('False')], ObjectNode('io'))) ])) ])), IntNode(0) ])) ]), ClassNode( 'A', features=[ AttributeNode('attr1', 'Int', IntNode(24)), MethodNode('attr1', [], 'Int', ObjectNode('attr1')), MethodNode('method2', [], 'Int', DispatchNode('attr1')), MethodNode( 'method3', [('index', 'Int')], 'Int', ConditionalNode( EqualThanNode(ObjectNode('index'), IntNode(0)), DispatchNode('method2'), BlockNode([ LetVarNode([(('io', 'IO'), NewTypeNode('IO'))], DispatchNode('out_string', [StrNode("Call method3")], ObjectNode('io'))), DispatchNode( 'method3', [MinusNode(ObjectNode('index'), IntNode(1))]) ]))) ]), ClassNode( 'B', inherit='A', features=[MethodNode('method2', [], 'Int', DispatchNode('attr1'))]) ]) program_code = ''' class Main { main() : Int { { while 1 < 2 loop { case 1+2 of id1:Int => id1+5; id2:Object => id2; id3:String => id3; esac; if 2<=3 then { let io: IO <- new IO in io.out_string("True"); } else { let io: IO <- new IO in io.out_string("False"); } fi; } pool; 0; } }; }; class A { attr1:Int<-24; attr1() : Int {attr1}; method2():Int {attr1()}; method3(index:Int):Int { if index = 0 then method2() else { let io: IO <- new IO in io.out_string("Call method3"); method3(index - 1); } fi }; }; class B inherits A { method2():Int {attr1()}; }; ''' parser_result = parser.parse(program_code, lexer=lexer) verify_asts(program_ast, parser_result, Node) check_semantic(program_ast)
def test_class_with_method_returning_int(): program = """class A { funk():ReturnType { 12 }; };""" funk_method = MethodNode('funk', [], 'ReturnType', IntNode(12)) expected = ProgramNode([ClassNode('A', 'Object', [funk_method])]) parser_result = parser.parse(program) verify_asts(expected, parser_result, Node)