def test_static_to_local(): assert compile_snippet('a = 5') == [OpcodeAssignStatic(A_ID, STATIC_START)] assert compile_snippet('a = "hello"') == [ OpcodePushStatic(STATIC_START), internal_call('text.as number'), OpcodePopLocal(A_ID) ]
def test_member_to_local(): assert compile_snippet('a = inst.val1') == [ OpcodePushMember(INST_ID, VAL1_ID), OpcodePopLocal(A_ID) ] assert compile_snippet('b = inst.val2') == [ OpcodePushMember(INST_ID, VAL2_ID), OpcodePopLocal(B_ID) ]
def test_self_member_to_local(): assert compile_snippet('a = self.val1') == [ OpcodePushMember(SELF_ID, VAL1_ID), OpcodePopLocal(A_ID) ] assert compile_snippet('b = self.val2') == [ OpcodePushMember(SELF_ID, VAL2_ID), OpcodePopLocal(B_ID) ]
def test_inner_member_to_local(): assert compile_snippet('a = inst.inner.inner1') == [ OpcodePushMember(INST_ID, INNER_ID), OpcodeDereference(INNER1_ID), OpcodePopLocal(A_ID) ] assert compile_snippet('b = inst.inner.inner2') == [ OpcodePushMember(INST_ID, INNER_ID), OpcodeDereference(INNER2_ID), OpcodePopLocal(B_ID) ]
def test_local_list_non_immediate_index(): assert compile_snippet('lst[a]') == [ OpcodePushLocal(A_ID), OpcodePushLocal(LST_ID), internal_call('list.get') ] assert compile_snippet('lst[self.val1]') == [ OpcodePushMember(SELF_ID, VAL1_ID), OpcodePushLocal(LST_ID), internal_call('list.get') ]
def test_member_access_via_method_call(): assert compile_snippet('a_inst.me().a1') == [ OpcodePushLocal(A_INST), OpcodeCallVirtual(1), OpcodeDereference(0) ] assert compile_snippet('a_inst.me().me().a1') == [ OpcodePushLocal(A_INST), OpcodeCallVirtual(1), OpcodeCallVirtual(1), OpcodeDereference(0) ]
def test_access_in_method_args(): assert compile_snippet('self.action(lst[123])') == [ OpcodePushStatic(STATIC_START), OpcodePushLocal(LST_ID), internal_call('list.get'), OpcodePushLocal(SELF_ID), OpcodeCallVirtual(1) ] assert compile_snippet('self.action(lst[self.val1])') == [ OpcodePushMember(SELF_ID, VAL1_ID), OpcodePushLocal(LST_ID), internal_call('list.get'), OpcodePushLocal(SELF_ID), OpcodeCallVirtual(1) ]
def test_static_to_indexed(): assert compile_snippet('lst[0] = Container()') == [ OpcodePushStatic(STATIC_START), # Push index 0 OpcodeCallStatic(CONTAINER, 0), # Push constant 5 OpcodePushLocal(LST_ID), # Push the list internal_call('list.set') ]
def test_static_to_member_of_indexed(): assert compile_snippet('lst[0].inner1 = 5') == [ OpcodePushStatic(STATIC_START), # Push index 0 OpcodePushStatic(STATIC_START + 1), # Push constant 5 OpcodePushLocal(LST_ID), # Push the list internal_call('list.get'), OpcodePopDereferenced(INNER1_ID) ]
def test_simple_continue(): assert compile_snippet({'while true': ['Console.write("")', 'continue', 'Console.write("")']}) == [ OpcodePushStatic(STATIC_START), OpcodeJumpConditional(28), OpcodePushStatic(STATIC_START + 1), internal_call('Console.write'), OpcodeJump(20), OpcodePushStatic(STATIC_START + 2), internal_call('Console.write'), OpcodeJump(20) ]
def test_simple_break(): assert compile_snippet({'while true': ['Console.write("")', 'break', 'Console.write("")']}) == [ OpcodePushStatic(STATIC_START), OpcodeJumpConditional(28), OpcodePushStatic(STATIC_START + 1), internal_call('Console.write'), OpcodeJump(28), # TODO: optimize case where `if something: break` OpcodePushStatic(STATIC_START + 2), internal_call('Console.write'), OpcodeJump(20) ]
def test_iteration_loop(): assert compile_snippet('for Container x in lst') == [ OpcodePushLocal(LST_ID), internal_call('list.iterator'), # Create iterator OpcodePopLocal(IMPLICIT_ITERATOR_ID), # Insert it into the frame OpcodePushLocal(IMPLICIT_ITERATOR_ID), # TODO: is this optimal? internal_call('iterator.has_next'), OpcodeJumpConditional(30), # Jump outside if not OpcodePushLocal(IMPLICIT_ITERATOR_ID), internal_call('iterator.next'), # Call next OpcodePopLocal(IMPLICIT_ITERATION_ID), # Insert into frame OpcodeJump(23) ]
def test_instance_method_on_class(): with pytest.raises(CalledInstanceMethodOnClass): compile_snippet('Generic.instance_method()')
def test_regular_inheritance_member_access(): assert compile_snippet('a_inst.a1') == [OpcodePushMember(A_INST, 0)] assert compile_snippet('b_inst.b1') == [OpcodePushMember(B_INST, 1)] assert compile_snippet('b_inst.a1') == [OpcodePushMember(B_INST, 0)]
def test_invalid_instance_usage(): with pytest.raises(UnfilledGenericParameters): compile_snippet('Generic().instance_method()')
def test_both_parameters_unfilled(): with pytest.raises(UnfilledGenericParameters): compile_snippet('list my_lst = list()')
def test_local_to_local(): assert compile_snippet('a = b') == [OpcodeAssignLocal(A_ID, B_ID)]
def test_simple_conditional(): assert compile_snippet({'if "dog" == "dog"': ['Console.write("executing")']}) == PREFIX + [ OpcodeJumpConditional(26), OpcodePushStatic(STATIC_START + 2), internal_call('Console.write') ]
def test_empty_conditional(): assert compile_snippet({'if "dog" == "dog"': ['pass']}) == PREFIX + [ OpcodeJumpConditional(24) ]
def test_nested_member_access(): assert compile_snippet('self.inner.inner.inner') == [ OpcodePushMember(SELF_ID, INNER_ID), OpcodeDereference(CONTAINER_INNER_ID), OpcodeDereference(CONTAINER_INNER_ID) ]
def test_valid_static_usage(): compile_snippet('Generic.static_method()')
def test_local_list_immediate_index(): assert compile_snippet('lst[123]') == [ OpcodePushStatic(STATIC_START), OpcodePushLocal(LST_ID), internal_call('list.get') ]
def test_regular_inheritance_invalid_member_access(): with pytest.raises(InvalidReference): compile_snippet('a_inst.b1') with pytest.raises(InvalidReference): compile_snippet('b_inst.c1')
def test_direct_member_access(): assert compile_snippet('a_inst.a1') == [OpcodePushMember(A_INST, 0)]
def test_left_parameter_unfilled(): with pytest.raises(UnfilledGenericParameters): compile_snippet('list my_lst = list<Container>()')