Skip to content

Instantly share code, notes, and snippets.

@TotallyNotSethP
Last active February 10, 2021 17:48
Show Gist options
  • Save TotallyNotSethP/77514667cc22f9d410e752d6a11a30b3 to your computer and use it in GitHub Desktop.
Save TotallyNotSethP/77514667cc22f9d410e752d6a11a30b3 to your computer and use it in GitHub Desktop.
+-=*/@%#()< Interpreter
import keyboard
class Accumulator:
def __init__(self, initial_value=0):
self.accumulator = initial_value
def increment(self, number=1):
self.accumulator += number
return self.accumulator
def decrement(self, number=1):
self.accumulator -= number
return self.accumulator
def output_number(self, **kwargs):
print(self.accumulator, end="", **kwargs)
return self.accumulator
def output_ascii_char(self, **kwargs):
char = chr(self.accumulator)
print(char, end="", **kwargs)
return char
def input_number(self):
exit_loop = False
while not exit_loop:
try:
keyupevent_occurred = False
while not keyupevent_occurred:
event = keyboard.read_event()
key = event.name
keyupevent_occurred = event.event_type == keyboard.KEY_UP
self.accumulator = int(key)
exit_loop = True
except ValueError:
pass
return self.accumulator
def input_ascii_char(self):
exit_loop = False
while not exit_loop:
try:
keyupevent_occurred = False
while not keyupevent_occurred:
event = keyboard.read_event()
key = event.name
keyupevent_occurred = event.event_type == keyboard.KEY_UP
if key == "space":
key = " "
self.accumulator = ord(key)
exit_loop = True
except TypeError:
pass
return key, self.accumulator
def reset(self):
self.accumulator = 0
return self.accumulator
class Interpreter:
def __init__(self):
self.accumulator = Accumulator()
@staticmethod
def _line_proc_iter(line):
skip_until = -1
return_val = []
for i, char in enumerate(line):
if i > skip_until:
return_val.append(char)
if i < len(line) - 1 and line[i+1] == "(":
for j, char_ in enumerate(line[i+1:]):
return_val[-1] += char_
if char_ == ")":
skip_until = i+j+1
break
return return_val
def _run_token(self, token, i):
if len(token) == 1:
if self.keymap[token] == "Special::GoBack":
i -= 2
else:
self.keymap[token]()
else:
if len(token[2:-1]) > 0:
if self.keymap[token[0]] == "Special::GoBack":
i -= int(token[2:-1]) + 1
else:
for _ in range(int(token[2:-1])):
self.keymap[token[0]]()
else:
if self.keymap[token[0]] == "Special::GoBack":
if self.accumulator.accumulator > 0:
i -= self.accumulator.accumulator + 1
else:
for _ in range(int(self.accumulator.accumulator)):
self.keymap[token[0]]()
return i
def interpret_line(self, line):
i = 0
tokens = self._line_proc_iter(line)
while i <= len(tokens) - 1:
i = self._run_token(tokens[i], i)
i += 1
@staticmethod
def _newline():
print()
@property
def keymap(self):
return {
"+": self.accumulator.increment,
"-": self.accumulator.decrement,
"=": self.accumulator.output_number,
"*": self.accumulator.output_ascii_char,
"@": self.accumulator.input_number,
"%": self.accumulator.input_ascii_char,
"/": self.accumulator.reset,
"#": self._newline,
"<": "Special::GoBack",
}
if __name__ == "__main__":
intepreter = Interpreter()
while True:
intepreter.interpret_line(input(">>> "))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment