Skip to content

Commit

Permalink
Capitalize HERA op names in Python identifiers
Browse files Browse the repository at this point in the history
Resolves #52
  • Loading branch information
iafisher committed Jan 4, 2019
1 parent 1473d61 commit 50cbd6c
Show file tree
Hide file tree
Showing 8 changed files with 516 additions and 544 deletions.
80 changes: 26 additions & 54 deletions hera/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def exec_one(self, op):
elif op.name in TERNARY_OPS:
self.exec_ternary_op(op)
else:
handler = getattr(self, "exec_" + op.name.lower())
handler = getattr(self, "exec_" + op.name)
handler(*op.args)

def exec_branch(self, op):
Expand Down Expand Up @@ -153,16 +153,14 @@ def access_memory(self, address):
else:
return self.memory[address]

def exec_setlo(self, target, value):
"""Execute the SETLO instruction."""
def exec_SETLO(self, target, value):
if value > 127:
value -= 256

self.store_register(target, to_u16(value))
self.pc += 1

def exec_sethi(self, target, value):
"""Execute the SETHI instruction."""
def exec_SETHI(self, target, value):
self.store_register(target, (value << 8) + (self.get_register(target) & 0x00FF))
self.pc += 1

Expand Down Expand Up @@ -191,7 +189,6 @@ def calculate_SUB(self, left, right):
return result

def calculate_MUL(self, left, right):
"""Execute the MUL instruction."""
if self.flag_sign and not self.flag_carry_block:
# Take the high 16 bits.
left = to_u32(from_u16(left))
Expand All @@ -215,8 +212,7 @@ def calculate_OR(self, left, right):
def calculate_XOR(self, left, right):
return left ^ right

def exec_inc(self, target, value):
"""Execute the INC (increment) instruction."""
def exec_INC(self, target, value):
original = self.get_register(target)
result = (value + original) & 0xFFFF
self.store_register(target, result)
Expand All @@ -226,8 +222,7 @@ def exec_inc(self, target, value):
self.flag_carry = value + original >= 2 ** 16
self.pc += 1

def exec_dec(self, target, value):
"""Execute the DEC (decrement) instruction."""
def exec_DEC(self, target, value):
original = self.get_register(target)
result = to_u16((original - value) & 0xFFFF)
self.store_register(target, result)
Expand All @@ -238,8 +233,7 @@ def exec_dec(self, target, value):
self.pc += 1

@binary_op
def exec_lsl(self, original):
"""Execute the LSL (logical shift left) instruction."""
def exec_LSL(self, original):
carry = 1 if self.flag_carry and not self.flag_carry_block else 0
result = ((original << 1) + carry) & 0xFFFF

Expand All @@ -248,8 +242,7 @@ def exec_lsl(self, original):
return result

@binary_op
def exec_lsr(self, original):
"""Execute the LSR (logical shift right) instruction."""
def exec_LSR(self, original):
carry = 2 ** 15 if self.flag_carry and not self.flag_carry_block else 0
result = (original >> 1) + carry

Expand All @@ -258,18 +251,15 @@ def exec_lsr(self, original):
return result

@binary_op
def exec_lsl8(self, original):
"""Execute the LSL8 (logical shift left by 8) instruction."""
def exec_LSL8(self, original):
return (original << 8) & 0xFFFF

@binary_op
def exec_lsr8(self, original):
"""Execute the LSR8 (logical shift right by 8) instruction."""
def exec_LSR8(self, original):
return original >> 8

@binary_op
def exec_asl(self, original):
"""Execute the ASL (arithmetic shift left) instruction."""
def exec_ASL(self, original):
carry = 1 if self.flag_carry and not self.flag_carry_block else 0
result = ((original << 1) + carry) & 0xFFFF

Expand All @@ -279,8 +269,7 @@ def exec_asl(self, original):
return result

@binary_op
def exec_asr(self, original):
"""Execute the ASR (arithmetic shift right) instruction."""
def exec_ASR(self, original):
# This is a little messy because right shift in Python rounds towards
# negative infinity (7 >> 1 == -4) but in HERA it rounds towards zero
# (7 >> 1 == -3).
Expand All @@ -296,8 +285,7 @@ def exec_asr(self, original):

return result

def exec_savef(self, target):
"""Execute the SAVEF (save flags) instruction."""
def exec_SAVEF(self, target):
value = (
int(self.flag_sign)
+ 2 * int(self.flag_zero)
Expand All @@ -308,8 +296,7 @@ def exec_savef(self, target):
self.store_register(target, value)
self.pc += 1

def exec_rstrf(self, target):
"""Execute the RSTRF (restore flags) instruction."""
def exec_RSTRF(self, target):
value = self.get_register(target)
self.flag_sign = bool(value & 1)
self.flag_zero = bool(value & 0b10)
Expand All @@ -318,50 +305,44 @@ def exec_rstrf(self, target):
self.flag_carry_block = bool(value & 0b10000)
self.pc += 1

def exec_fon(self, value):
"""Execute the FON instruction."""
def exec_FON(self, value):
self.flag_sign = self.flag_sign or bool(value & 1)
self.flag_zero = self.flag_zero or bool(value & 0b10)
self.flag_overflow = self.flag_overflow or bool(value & 0b100)
self.flag_carry = self.flag_carry or bool(value & 0b1000)
self.flag_carry_block = self.flag_carry_block or bool(value & 0b10000)
self.pc += 1

def exec_foff(self, value):
"""Execute the FOFF instruction."""
def exec_FOFF(self, value):
self.flag_sign = self.flag_sign and not bool(value & 1)
self.flag_zero = self.flag_zero and not bool(value & 0b10)
self.flag_overflow = self.flag_overflow and not bool(value & 0b100)
self.flag_carry = self.flag_carry and not bool(value & 0b1000)
self.flag_carry_block = self.flag_carry_block and not bool(value & 0b10000)
self.pc += 1

def exec_fset5(self, value):
"""Execute the FSET5 instruction."""
def exec_FSET5(self, value):
self.flag_sign = bool(value & 1)
self.flag_zero = bool(value & 0b10)
self.flag_overflow = bool(value & 0b100)
self.flag_carry = bool(value & 0b1000)
self.flag_carry_block = bool(value & 0b10000)
self.pc += 1

def exec_fset4(self, value):
"""Execute the FSET4 instruction."""
def exec_FSET4(self, value):
self.flag_sign = bool(value & 1)
self.flag_zero = bool(value & 0b10)
self.flag_overflow = bool(value & 0b100)
self.flag_carry = bool(value & 0b1000)
self.pc += 1

def exec_load(self, target, offset, address):
"""Execute the LOAD instruction."""
def exec_LOAD(self, target, offset, address):
result = self.access_memory(self.get_register(address) + offset)
self.set_zero_and_sign(result)
self.store_register(target, result)
self.pc += 1

def exec_store(self, source, offset, address):
"""Execute the STORE instruction."""
def exec_STORE(self, source, offset, address):
self.assign_memory(
self.get_register(address) + offset, self.get_register(source)
)
Expand Down Expand Up @@ -412,8 +393,7 @@ def should_BV(self):
def should_BNV(self):
return not self.flag_overflow

def exec_call(self, ra, rb):
"""Execute the CALL instruction."""
def exec_CALL(self, ra, rb):
old_pc = self.pc
self.pc = self.get_register(rb)
self.store_register(rb, old_pc + 1)
Expand All @@ -422,35 +402,30 @@ def exec_call(self, ra, rb):
self.store_register(ra, old_fp)

# CALL and RETURN do the exact same thing.
exec_return = exec_call
exec_RETURN = exec_CALL

def exec_swi(self, i):
"""Execute the SWI (software interrupt) instruction."""
def exec_SWI(self, i):
if not self.warned_for_SWI:
emit_warning("SWI is a no-op in this simulator", loc=self.location)
self.warned_for_SWI = True
self.pc += 1

def exec_rti(self):
"""Execute the RTI (return from interrupt) instruction."""
def exec_RTI(self):
if not self.warned_for_RTI:
emit_warning("RTI is a no-op in this simulator", loc=self.location)
self.warned_for_RTI = True
self.pc += 1

def exec_integer(self, i):
"""Execute the INTEGER data instruction."""
def exec_INTEGER(self, i):
self.assign_memory(self.dc, to_u16(i))
self.dc += 1
self.pc += 1

def exec_dskip(self, n):
"""Execute the DSKIP data instruction."""
def exec_DSKIP(self, n):
self.dc += n
self.pc += 1

def exec_lp_string(self, s):
"""Execute the LP_STRING data instruction."""
def exec_LP_STRING(self, s):
self.assign_memory(self.dc, len(s))
self.dc += 1
for c in s:
Expand All @@ -459,17 +434,14 @@ def exec_lp_string(self, s):
self.pc += 1

def exec_print_reg(self, target):
"""Execute the print_reg debugging instruction."""
v = self.get_register(target)
print_register_debug(target, v, to_stderr=False)
self.pc += 1

def exec_print(self, target):
"""Execute the print debugging instruction."""
print(target, end="")
self.pc += 1

def exec_println(self, target):
"""Execute the println debugging instruction."""
print(target)
self.pc += 1
40 changes: 20 additions & 20 deletions test/test_op/test_branch_call_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,66 +219,66 @@ def test_should_not_BV_on_not_overflow(vm):
assert not vm.should_BV()


def test_call_changes_pc(vm):
def test_CALL_changes_pc(vm):
vm.pc = 100
vm.registers[13] = 40
vm.exec_call("R12", "R13")
vm.exec_CALL("R12", "R13")
assert vm.pc == 40


def test_call_updates_second_register(vm):
def test_CALL_updates_second_register(vm):
vm.pc = 100
vm.registers[13] = 40
vm.exec_call("R12", "R13")
vm.exec_CALL("R12", "R13")
assert vm.registers[13] == 101


def test_call_updates_frame_pointer(vm):
def test_CALL_updates_frame_pointer(vm):
vm.registers[12] = 600
vm.registers[13] = 40
vm.exec_call("R12", "R13")
vm.exec_CALL("R12", "R13")
assert vm.registers[14] == 600


def test_call_updates_first_register(vm):
def test_CALL_updates_first_register(vm):
vm.registers[14] = 550
vm.registers[12] = 600
vm.registers[13] = 40
vm.exec_call("R12", "R13")
vm.exec_CALL("R12", "R13")
assert vm.registers[12] == 550


def test_exec_one_delegates_to_return(vm):
with patch("hera.vm.VirtualMachine.exec_return") as mock_exec_return:
def test_exec_one_delegates_to_RETURN(vm):
with patch("hera.vm.VirtualMachine.exec_RETURN") as mock_exec_RETURN:
vm.exec_one(Op("RETURN", ["R12", "R13"]))
assert mock_exec_return.call_count == 1
assert mock_exec_return.call_args == (("R12", "R13"), {})
assert mock_exec_RETURN.call_count == 1
assert mock_exec_RETURN.call_args == (("R12", "R13"), {})


def test_return_changes_pc(vm):
def test_RETURN_changes_pc(vm):
vm.pc = 100
vm.registers[13] = 40
vm.exec_return("R12", "R13")
vm.exec_RETURN("R12", "R13")
assert vm.pc == 40


def test_return_updates_second_register(vm):
def test_RETURN_updates_second_register(vm):
vm.pc = 100
vm.registers[13] = 40
vm.exec_return("R12", "R13")
vm.exec_RETURN("R12", "R13")
assert vm.registers[13] == 101


def test_return_updates_frame_pointer(vm):
def test_RETURN_updates_frame_pointer(vm):
vm.registers[12] = 600
vm.registers[13] = 40
vm.exec_return("R12", "R13")
vm.exec_RETURN("R12", "R13")
assert vm.registers[14] == 600


def test_return_updates_first_register(vm):
def test_RETURN_updates_first_register(vm):
vm.registers[14] = 550
vm.registers[12] = 600
vm.registers[13] = 40
vm.exec_return("R12", "R13")
vm.exec_RETURN("R12", "R13")
assert vm.registers[12] == 550
Loading

0 comments on commit 50cbd6c

Please sign in to comment.