Exemple #1
0
    def test_it_counts_from_1_to_10(self):
        screen = TestScreen()

        vm = VM()
        vm.screen = screen
        vm.instructions = [
            Push(1),  # Put a 1 on the stack
            Label(' '),  # Set a Label at this point
            Dup(),  # Duplicate the top stack item
            Putn(),  # Output the current value
            Push(10),  # Put 10 (newline) on the stack...
            Putc(),  # ...and output the newline
            Push(1),  # Put a 1 on the stack
            Add(),  # Increment our current value
            Dup(),  # Duplicate the value to test it
            Push(11),  # Push 11 onto the stack
            Sub(),  # Subtraction
            Zjmp('\t'),  # If we have a 0, jump to the end
            Ujmp(' '),  # Jump to the start
            Label('\t'),  # Set the end label
            Discard(),  # Discard our accumulator, to be tidy
            End()  # Finish
        ]

        vm.run()

        self.assertEqual(screen.contents, '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n')

        screen.turnOff()
Exemple #2
0
    def test_it_does_an_unconditional_jump(self):
        vm = VM()
        vm.instructions = [Label('loop'), noop, noop]
        vm.pc = 2

        Ujmp('loop').execute(vm)

        self.assertEqual(vm.pc, 1)
Exemple #3
0
    def test_find_label(self):
        vm = VM()
        vm.instructions = [Push(1), Label('a'), Push(2), Label('b'), Add()]

        self.assertEqual(vm.find_label('a'), 1)
        self.assertEqual(vm.find_label('b'), 3)

        with self.assertRaisesRegex(LabelMissingError, 'c'):
            vm.find_label('c')
Exemple #4
0
    def test_it_executes_each_instruction_one_by_one_until_an_end_instruction_is_reached(
            self):
        vm = VM()
        vm.instructions = [Push(3), Dup(), Mul(), End(), Dup()]

        vm.run()

        self.assertEqual(len(vm.vstack), 1)
        self.assertEqual(vm.vstack.top(), 9)
Exemple #5
0
    def test_it_does_not_jump_if_non_negative(self):
        vm = VM()
        vm.instructions = [Label('loop'), noop, noop]
        vm.vstack.push(0)
        vm.pc = 2

        Njmp('loop').execute(vm)

        self.assertEqual(len(vm.vstack), 0)
        self.assertEqual(vm.pc, 2)
Exemple #6
0
    def test_it_jumps_if_zero(self):
        vm = VM()
        vm.instructions = [Label('loop'), noop, noop]
        vm.vstack.push(0)
        vm.pc = 2

        Zjmp('loop').execute(vm)

        self.assertEqual(len(vm.vstack), 0)
        self.assertEqual(vm.pc, 1)
Exemple #7
0
    def test_it_calls_a_subroutine(self):
        vm = VM()
        vm.instructions = [noop, Label('f'), noop, noop, noop]
        vm.pc = 4

        Call('f').execute(vm)

        self.assertEqual(len(vm.cstack), 1)
        self.assertEqual(vm.cstack.top(), 4)
        self.assertEqual(vm.pc, 2)
Exemple #8
0
    def test_it_raises_an_error_when_no_end_instruction_is_reached(self):
        vm = VM()
        vm.instructions = [Push(3), Dup(), Mul()]

        with self.assertRaisesRegex(OutOfBoundsError, 'program counter: 3'):
            vm.run()