Skip to content

Commit

Permalink
Add integration test for error message for invalid register
Browse files Browse the repository at this point in the history
  • Loading branch information
iafisher committed Nov 20, 2018
1 parent aaedcef commit 005b784
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
3 changes: 1 addition & 2 deletions hera/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,14 @@ def execute_program(program, *, opt_dump_state=False):

try:
program = preprocess(parse(program))
vm.exec_many(program)
except HERAError as e:
if e.line:
msg = "{0}, line {0.line}\n\n {1}\n".format(e, lines[e.line - 1])
else:
msg = str(e)
error_and_exit(msg)
else:
vm.exec_many(program)

if opt_dump_state:
dump_state(vm)

Expand Down
15 changes: 13 additions & 2 deletions hera/preprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,13 @@ def preprocess_first_pass(self, program):
except AttributeError:
nprogram.append(op)
else:
nprogram.extend(handler(*op.args))
new_ops = handler(*op.args)
# Copy over the line number and column information from the old op.
new_ops = [
Op(copy_token(new_op.name, op.name), new_op.args)
for new_op in new_ops
]
nprogram.extend(new_ops)
return nprogram

def preprocess_second_pass(self, program):
Expand All @@ -103,7 +109,7 @@ def preprocess_second_pass(self, program):
else:
nop = handler(*op.args)
if nop:
nprogram.append(nop)
nprogram.append(Op(copy_token(nop.name, op.name), nop.args))
return nprogram

def resolve_labels(self, program):
Expand Down Expand Up @@ -222,6 +228,7 @@ def preprocess1_set(self, d, v):
v = to_u16(v)
lo = v & 0xFF
hi = v >> 8

if hi:
return [Op("SETLO", [d, lo]), Op("SETHI", [d, hi])]
else:
Expand Down Expand Up @@ -320,3 +327,7 @@ def preprocess2_sethi(self, d, v):
return Op("SETHI", [d, self.labels[v] >> 8])
else:
return Op("SETHI", [d, v])


def copy_token(val, otkn):
return Token(otkn.type, val, line=otkn.line, column=otkn.column)
19 changes: 15 additions & 4 deletions hera/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import functools

from .preprocessor import HERA_DATA_START
from .utils import from_u16, to_u16, to_u32, register_to_index
from .utils import from_u16, to_u16, to_u32, register_to_index, HERAError


def ternary_op(f):
Expand Down Expand Up @@ -120,17 +120,28 @@ def exec_many(self, program):
self.reset()
while self.pc < len(program):
opc = self.pc
self.exec_one(program[self.pc])
try:
self.exec_one(program[self.pc])
except HERAError as e:
e.line = program[self.pc].name.line
raise e
if opc == self.pc:
break

def get_register(self, name):
"""Get the contents of the register with the given name."""
return self.registers[register_to_index(name)]
try:
index = register_to_index(name)
except ValueError as e:
raise HERAError(str(e)) from None
return self.registers[index]

def store_register(self, target, value):
"""Store the value in the target register (a string)."""
index = register_to_index(target)
try:
index = register_to_index(target)
except ValueError as e:
raise HERAError(str(e)) from None
if index != 0:
self.registers[index] = value

Expand Down
11 changes: 11 additions & 0 deletions test/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,14 @@ def test_error_message_for_missing_comma():
msg = mock_exit.call_args[0][0]
assert line in msg
assert "line 1" in msg


def test_error_message_for_invalid_register():
line = "SET(R17, 65)"
with patch("hera.main.error_and_exit") as mock_exit:
execute_program(line)
msg = mock_exit.call_args[0][0]
assert line in msg
assert "line 1" in msg
assert "R17" in msg
assert "not a valid register" in msg
5 changes: 4 additions & 1 deletion test/test_preprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ def test_resolve_labels_with_empty_lp_string(ppr):


def test_assemble_constant(ppr):
program = [Op("CONSTANT", ["n", 100]), Op("SET", ["R1", Token("SYMBOL", "n")])]
program = [
Op("CONSTANT", ["n", 100]),
Op(Token("SYMBOL", "SET"), ["R1", Token("SYMBOL", "n")]),
]
assert preprocess(program) == [Op("SETLO", ["R1", 100]), Op("SETHI", ["R1", 0])]


Expand Down

0 comments on commit 005b784

Please sign in to comment.