Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement and test the parser #1

Merged
merged 1 commit into from Sep 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 28 additions & 7 deletions tests/instructions/test_arithmetic.py
Expand Up @@ -11,7 +11,10 @@ def test_it_adds_the_top_two_items_on_the_value_stack(self):
vm.vstack.push(3)
vm.vstack.push(2)

Add(vm).execute()
add = Add()
add.vm = vm

add.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 5)
Expand All @@ -23,7 +26,10 @@ def test_it_subtracts_the_top_two_items_on_the_value_stack(self):
vm.vstack.push(3)
vm.vstack.push(2)

Sub(vm).execute()
sub = Sub()
sub.vm = vm

sub.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 1)
Expand All @@ -35,7 +41,10 @@ def test_it_multiplies_the_top_two_items_on_the_value_stack(self):
vm.vstack.push(3)
vm.vstack.push(2)

Mul(vm).execute()
mul = Mul()
mul.vm = vm

mul.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 6)
Expand All @@ -47,7 +56,10 @@ def test_it_divides_the_top_two_items_on_the_value_stack(self):
vm.vstack.push(7)
vm.vstack.push(2)

Div(vm).execute()
div = Div()
div.vm = vm

div.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 3)
Expand All @@ -57,8 +69,11 @@ def test_when_divisor_is_zero(self):
vm.vstack.push(1)
vm.vstack.push(0)

div = Div()
div.vm = vm

with self.assertRaisesRegex(ZeroDivisionError, 'integer division by zero'):
Div(vm).execute()
div.execute()


class TestMod(unittest.TestCase):
Expand All @@ -67,7 +82,10 @@ def test_it_computes_the_remainder_of_the_top_two_items_on_the_value_stack(self)
vm.vstack.push(7)
vm.vstack.push(2)

Mod(vm).execute()
mod = Mod()
mod.vm = vm

mod.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 1)
Expand All @@ -77,5 +95,8 @@ def test_when_divisor_is_zero(self):
vm.vstack.push(1)
vm.vstack.push(0)

mod = Mod()
mod.vm = vm

with self.assertRaisesRegex(ZeroDivisionError, 'modulo by zero'):
Mod(vm).execute()
mod.execute()
92 changes: 58 additions & 34 deletions tests/instructions/test_flow_control.py
Expand Up @@ -2,27 +2,31 @@

from whitespace.error import Halt, LabelMissingError
from whitespace.instructions.flow_control import Call, End, Label, Njmp, Ret, Ujmp, Zjmp, find_label
from whitespace.instructions.instruction import Noop
from whitespace.vm import VM


class TestLabel(unittest.TestCase):
def test_it_does_not_fail(self):
Label(None, ' ').execute()
Label(' ').execute()


class TestCall(unittest.TestCase):
def test_it_calls_a_subroutine(self):
vm = VM()
vm.load([
'instruction 1',
Label(vm, ' '),
'instruction 3',
'instruction 4',
'instruction 5'
Noop(),
Label(' '),
Noop(),
Noop(),
Noop()
])
vm.pc = 4

Call(vm, ' ').execute()
call = Call(' ')
call.vm = vm

call.execute()

self.assertEqual(len(vm.cstack), 1)
self.assertEqual(vm.cstack.top(), 4)
Expand All @@ -33,13 +37,16 @@ class TestUjmp(unittest.TestCase):
def test_it_changes_the_program_counter_to_the_index_of_the_instruction_after_the_label(self):
vm = VM()
vm.load([
Label(vm, ' '),
'instruction 2',
'instruction 3'
Label(' '),
Noop(),
Noop()
])
vm.pc = 2

Ujmp(vm, ' ').execute()
ujmp = Ujmp(' ')
ujmp.vm = vm

ujmp.execute()

self.assertEqual(vm.pc, 1)

Expand All @@ -48,14 +55,17 @@ class TestZjmpZero(unittest.TestCase):
def test_it_changes_the_program_counter_to_the_index_of_the_instruction_after_the_label(self):
vm = VM()
vm.load([
Label(vm, ' '),
'instruction 2',
'instruction 3'
Label(' '),
Noop(),
Noop()
])
vm.vstack.push(0)
vm.pc = 2

Zjmp(vm, ' ').execute()
zjmp = Zjmp(' ')
zjmp.vm = vm

zjmp.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.pc, 1)
Expand All @@ -65,14 +75,17 @@ class TestZjmpNonZero(unittest.TestCase):
def test_it_does_not_change_the_program_counter(self):
vm = VM()
vm.load([
Label(vm, ' '),
'instruction 2',
'instruction 3'
Label(' '),
Noop(),
Noop()
])
vm.vstack.push(1)
vm.pc = 2

Zjmp(vm, ' ').execute()
zjmp = Zjmp(' ')
zjmp.vm = vm

zjmp.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.pc, 2)
Expand All @@ -82,14 +95,17 @@ class TestNjmpNegative(unittest.TestCase):
def test_it_changes_the_program_counter_to_the_index_of_the_instruction_after_the_label(self):
vm = VM()
vm.load([
Label(vm, ' '),
'instruction 2',
'instruction 3'
Label(' '),
Noop(),
Noop()
])
vm.vstack.push(-1)
vm.pc = 2

Njmp(vm, ' ').execute()
njmp = Njmp(' ')
njmp.vm = vm

njmp.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.pc, 1)
Expand All @@ -99,14 +115,17 @@ class TestNjmpNonNegative(unittest.TestCase):
def test_it_does_not_change_the_program_counter(self):
vm = VM()
vm.load([
Label(vm, ' '),
'instruction 2',
'instruction 3'
Label(' '),
Noop(),
Noop()
])
vm.vstack.push(0)
vm.pc = 2

Njmp(vm, ' ').execute()
njmp = Njmp(' ')
njmp.vm = vm

njmp.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.pc, 2)
Expand All @@ -117,26 +136,31 @@ def test_it_changes_the_program_counter_to_the_value_at_the_top_of_the_call_stac
vm = VM()
vm.cstack.push(5)

Ret(vm).execute()
ret = Ret()
ret.vm = vm

ret.execute()

self.assertEqual(len(vm.cstack), 0)
self.assertEqual(vm.pc, 5)


class TestEnd(unittest.TestCase):
def test_it_raises_halt(self):
end = End()

with self.assertRaises(Halt):
End(None).execute()
end.execute()


class TestFindLabel(unittest.TestCase):
def setUp(self):
self.instructions = [
'instruction 1',
Label(None, ' '),
'instruction 3',
Label(None, ' '),
'instruction 5'
Noop(),
Label(' '),
Noop(),
Label(' '),
Noop()
]

def test_it_returns_index_when_the_label_exists(self):
Expand Down
10 changes: 8 additions & 2 deletions tests/instructions/test_heap_access.py
Expand Up @@ -10,7 +10,10 @@ def test_it_stores_the_value_at_the_given_address(self):
vm.vstack.push(1000)
vm.vstack.push(1)

Store(vm).execute()
store = Store()
store.vm = vm

store.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.memory[1000], 1)
Expand All @@ -22,7 +25,10 @@ def test_it_retrieves_the_value_from_the_given_address(self):
vm.memory[1000] = 5
vm.vstack.push(1000)

Retrieve(vm).execute()
retrieve = Retrieve()
retrieve.vm = vm

retrieve.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 5)
20 changes: 16 additions & 4 deletions tests/instructions/test_io.py
Expand Up @@ -12,7 +12,10 @@ def test_it_outputs_the_character_at_the_top_of_the_value_stack(self):
vm = VM(console=console)
vm.vstack.push(97)

Putc(vm).execute()
putc = Putc()
putc.vm = vm

putc.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(console.output.getvalue(), 'a')
Expand All @@ -26,7 +29,10 @@ def test_it_outputs_the_number_at_the_top_of_the_value_stack(self):
vm = VM(console=console)
vm.vstack.push(97)

Putn(vm).execute()
putn = Putn()
putn.vm = vm

putn.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(console.output.getvalue(), '97')
Expand All @@ -40,7 +46,10 @@ def test_it_reads_a_character_and_places_it_in_the_location_given_by_the_top_of_
vm = VM(console=console)
vm.vstack.push(100)

Getc(vm).execute()
getc = Getc()
getc.vm = vm

getc.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.memory[100], 97)
Expand All @@ -54,7 +63,10 @@ def test_it_reads_a_number_and_places_it_in_the_location_given_by_the_top_of_the
vm = VM(console=console)
vm.vstack.push(100)

Getn(vm).execute()
getn = Getn()
getn.vm = vm

getn.execute()

self.assertEqual(len(vm.vstack), 0)
self.assertEqual(vm.memory[100], 1234)
Expand Down
20 changes: 16 additions & 4 deletions tests/instructions/test_stack_manipulation.py
Expand Up @@ -8,7 +8,10 @@ class TestPush(unittest.TestCase):
def test_it_pushes_a_number_onto_the_value_stack(self):
vm = VM()

Push(vm, 1).execute()
push = Push(1)
push.vm = vm

push.execute()

self.assertEqual(len(vm.vstack), 1)
self.assertEqual(vm.vstack.top(), 1)
Expand All @@ -19,7 +22,10 @@ def test_it_duplicates_the_top_item_on_the_value_stack(self):
vm = VM()
vm.vstack.push(1)

Dup(vm).execute()
dup = Dup()
dup.vm = vm

dup.execute()

self.assertEqual(len(vm.vstack), 2)
self.assertEqual(vm.vstack.pop(), 1)
Expand All @@ -32,7 +38,10 @@ def test_it_swaps_the_two_top_items_on_the_value_stack(self):
vm.vstack.push(1)
vm.vstack.push(2)

Swap(vm).execute()
swap = Swap()
swap.vm = vm

swap.execute()

self.assertEqual(len(vm.vstack), 2)
self.assertEqual(vm.vstack.pop(), 1)
Expand All @@ -44,6 +53,9 @@ def test_it_discards_the_top_item_on_the_value_stack(self):
vm = VM()
vm.vstack.push(1)

Discard(vm).execute()
discard = Discard()
discard.vm = vm

discard.execute()

self.assertEqual(len(vm.vstack), 0)