Created
November 2, 2021 10:15
-
-
Save ngoctnq/99589e821f99be27b8c05bc8ae714e98 to your computer and use it in GitHub Desktop.
Hanoi Love interpreter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
I couldn't find a modern interpreter for Hanoi Love so here goes. | |
@author Ngoc N. Tran (@ngoctnq) | |
@created November 2nd, 2021 | |
''' | |
from typing import Union | |
def run_hl(instructions: str, stdin: Union[list, bytes] = []): | |
''' | |
Run the Hanoi Love program. | |
Parameters: | |
:param instructions : the program instructions | |
:param stdin (optional): the stdin to pipe into the program | |
may be a list or anything that can be converted into a list | |
''' | |
stacks = [[], [], [], []] | |
stack_idx = 0 | |
register = 0 | |
skipping = False | |
iomode = False | |
insptr = 0 | |
output = [] | |
if type(stdin) is not list: | |
stdin = list(stdin) | |
while True: | |
if insptr == len(instructions): | |
return bytes(output) | |
c = instructions[insptr] | |
insptr += 1 | |
if skipping: | |
if c == '!': | |
skipping = False | |
continue | |
if c == '.': | |
stack_idx = (stack_idx + 1) % 4 | |
elif c == "'": | |
if iomode: | |
output.append(register) | |
iomode = False | |
elif stack_idx == 3: | |
stacks[3].append(insptr - 2) | |
else: | |
stacks[stack_idx].append(register) | |
elif c == ',': | |
if iomode: | |
register = stdin.pop(0) | |
iomode = False | |
elif len(stacks[stack_idx]) == 0: | |
if stack_idx == 0: | |
register = 1 | |
continue | |
if stack_idx < 3: | |
register = 0 | |
continue | |
raise | |
elif stack_idx == 3: | |
insptr = stacks[3].pop() | |
else: | |
register = stacks[stack_idx].pop() | |
elif c == ';': | |
if iomode: | |
register += stdin.pop(0) | |
iomode = False | |
elif len(stacks[stack_idx]) == 0: | |
if stack_idx == 0: | |
register += 1 | |
continue | |
if stack_idx < 3: | |
continue | |
raise | |
elif stack_idx == 3: | |
stacks[stack_idx].pop() | |
else: | |
register += stacks[stack_idx].pop() | |
elif c == '`': | |
if iomode: | |
register -= stdin.pop(0) | |
iomode = False | |
elif len(stacks[stack_idx]) == 0: | |
if stack_idx == 0: | |
register -= 1 | |
continue | |
if stack_idx < 3: | |
continue | |
raise | |
elif stack_idx == 3: | |
stacks[stack_idx].pop() | |
else: | |
register -= stacks[stack_idx].pop() | |
elif c == '"': | |
iomode = True | |
elif c == ':': | |
if register == 0: | |
skipping = True | |
elif c == '!': | |
return bytes(output) | |
if __name__ == '__main__': | |
assert run_hl('''.'...,;';';;';';';'.,...;"'.'...,;;';;';';;'.,...;"';;;;;;;"'"';;;"'.'.,...'...,;';';';';'.,...;"'..'...,'...,;;';';';'.,...`"'.'...,;;';';';'.,...;"';;;"'``````"'````````"'.'.,..;"'.'.,..;;;;;;;;;;"\'''') == b'Hello World!\n' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment