From 671df531bef4a8948cfb0e9fc77d6378f1cda60d Mon Sep 17 00:00:00 2001 From: JonoCode9374 <36217120+JonoCode9374@users.noreply.github.com> Date: Sat, 4 Jan 2020 19:18:18 +1100 Subject: [PATCH] Very rudimentary interpreter completed --- ekg/Code_Token.py | 35 ++++++ ekg/Parse.py | 77 +++++++++++- ekg/TokenLib.py | 2 +- ekg/chainify.py | 304 +++++++++++++++++++++++++++++++++------------- ekg/functions.py | 29 +++++ 5 files changed, 358 insertions(+), 89 deletions(-) create mode 100644 ekg/Code_Token.py create mode 100644 ekg/functions.py diff --git a/ekg/Code_Token.py b/ekg/Code_Token.py new file mode 100644 index 0000000..7fd88e0 --- /dev/null +++ b/ekg/Code_Token.py @@ -0,0 +1,35 @@ +class Code_Token(): + def __init__(self, function, left, right): + ''' + + function: a callable function object + left: the left argument (if applicable) + right: the right argument + + ''' + self.fn = function + self.left_arg = left + self.right_arg = right + + def execute(self, surrounds=None): + if self.left_arg == Relative_Argument: + if surrounds: + self.left_arg = surrounds[0] + else: + self.left_arg = eval(input()) + + if self.right_arg == Relative_Argument: + if surrounds: + self.right_arg = surrounds[-1] + else: + self.right_arg = eval(input()) + + if type(self.left_arg) == Code_Token: + self.left_arg = self.left_arg.execute() + + if type(self.right_arg) == Code_Token: + self.right_arg = self.right_arg.execute() + return self.fn(self.left_arg, self.right_arg) + +class Relative_Argument: + pass diff --git a/ekg/Parse.py b/ekg/Parse.py index ffc857c..9f475ad 100644 --- a/ekg/Parse.py +++ b/ekg/Parse.py @@ -19,6 +19,10 @@ class Parser(): block_level = 0 temp_block = "" token_list = [] + string_mode = False + temp_string = "" + integer_mode = False + temp_integer = "" if optional_source: code = optional_source @@ -26,14 +30,70 @@ class Parser(): code = self.source for char in code: - if escaped: + #print(char, temp_integer, [str(x) for x in token_list]) + if integer_mode: + if char not in "0123456789" and char != ".": + integer_mode = False + if block_level: + temp_block += temp_integer + else: + token_list.append(Token(TokenLib.NUMBER, + eval(temp_integer))) + + + temp_integer = "" + + elif char == ".": + if "." in temp_integer: + raise SyntaxError("Misplaced '.'") + temp_integer += "." + + else: + temp_integer += char + continue + + elif string_mode: + if escaped: + escaped = False + temp_string += char + else: + if char == '"': + string_mode = False + if block_level: + temp_block += '"' + temp_string + '"' + else: + token_list.append(Token(TokenLib.STRING, + temp_string)) + + temp_string = "" + + elif char == "\\": + escaped = True + temp_string += char + + else: + temp_string += char + continue + + elif escaped: self.token_list.append(Token(TokenLib.ESCAPE, char)) escaped = False + continue elif char == "\\": escaped = True + continue - elif char == "[": + elif char in "0123456789": + temp_integer += char + integer_mode = True + continue + + elif char == '"': + string_mode = True + continue + + if char == "[": if block_level >= 1: block_level += 1 temp_block += char @@ -57,6 +117,8 @@ class Parser(): temp_block += char else: + if char == " ": + continue token_list.append(Token(TokenLib.INSTRUCTION, char)) @@ -64,10 +126,19 @@ class Parser(): token_list.append(Token(TokenLib.BLOCK, temp_block)) + elif temp_integer: + token_list.append(Token(TokenLib.NUMBER, + eval(temp_integer))) + + elif temp_string: + token_list.append(Token(TokenLib.STRING, + temp_string)) + + return token_list if __name__ == "__main__": - source: str = "[P[DD+s]]S3" + source: str = "384+89" parser: Parser = Parser(source) tokens: [Token] = parser.parse() diff --git a/ekg/TokenLib.py b/ekg/TokenLib.py index 92b66ad..03af64e 100644 --- a/ekg/TokenLib.py +++ b/ekg/TokenLib.py @@ -26,5 +26,5 @@ class Token(): INSTRUCTION = "instruction" BLOCK = "block" STRING = "string" -INTEGER = "integer" +NUMBER = "number" ESCAPE = "escape" diff --git a/ekg/chainify.py b/ekg/chainify.py index ff0e3d0..5b30d7b 100644 --- a/ekg/chainify.py +++ b/ekg/chainify.py @@ -1,12 +1,16 @@ import Parse import TokenLib import string +from Code_Token import * +import functions -dyads: str = string.punctuation +dyads: str = string.punctuation + "i" monads: str = string.ascii_uppercase nilads: str = "1234567890" -source: str = str(reversed(input())) +self = lambda x, y: y + + def balance(source: str) -> str: @@ -82,124 +86,254 @@ def arities(source: [TokenLib.Token]) -> [(int, TokenLib.Token)]: if token.get_name() == TokenLib.BLOCK: arity_list.append([0, arities(token.get_data())]) - -''' -arities = [] -for char in source: - if char in dyads: - arities.append((2, char)) + elif str(token.get_value()) in dyads: + arity_list.append([2, token]) - elif char in monads: - arities.append((1, char)) + elif str(token.get_value()) in monads: + arity_list.append([1, token]) - else: - arities.append((0, char)) + else: + arity_list.append([0, token]) -exprs = [] -expr = [] -patterns = ["0", "1", "2", - "020", "021", "022", "02", "10", "11", "12", "20", "21", "22", - "102", "110", "111", "112", "120", "121", "122", - "202", "210", "211", "212", "220", "221", "222"] -pattern = "" -while len(arities): - if pattern in patterns and pattern + str(arities[-1][0]) not in patterns: + return arity_list + +def code_tokenify(arity_list: [(int, TokenLib.Token)]) -> [Code_Token]: + code_tokens = [] + exprs = [] + expr = [] + patterns = ["0", "1", "2", + "020", "021", "022", "02", "10", "11", "12", "20", "21", "22", + "102", "110", "111", "112", "120", "121", "122", + "202", "210", "211", "212", "220", "221", "222"] + pattern = "" + while len(arity_list): + if (pattern in patterns and + pattern + str(arity_list[-1][0]) not in patterns): + exprs.append([pattern, expr]) + expr = [] + pattern = "" + + pattern += str(arity_list[-1][0]) + expr.append(arity_list[-1][1]) + arity_list.pop() + + if expr and pattern in patterns: exprs.append([pattern, expr]) expr = [] pattern = "" + + + for expr in exprs: + arity_pattern, data = expr + ctkn = None + #print(arity_pattern, [m.get_data() for m in data]) + + if arity_pattern == "0": + # Nilad + ctkn = Code_Token(self, None, data[0].get_value()) + + elif arity_pattern == "1": + # Monad + ctkn = Code_Token(functions.search(data[0]), + None, Relative_Argument) + + elif arity_pattern == "2": + # Dyad + ctkn = Code_Token(functions.search(data[0]), + Relative_Argument, Relative_Argument) + + elif arity_pattern == "020": + # Nilad-Dyad-Nilad + ctkn = Code_Token(functions.search(data[1]), + data[0].get_value(), data[2].get_value()) + + elif arity_pattern == "021": + # Nilad-Dyad-Monad + right = Code_Token(functions.search(data[2]), + None, Relative_Argument) + ctkn = Code_Token(functions.search(data[1]), + data[0].get_value(), right) + + elif arity_pattern == "02": + # Nilad-Dyad + ctkn = Code_Token(functions.search(data[1]), + data[0].get_value(), Relative_Argument) + + elif arity_pattern == "10": + # Monad-Nilad + ctkn = Code_Token(functions.search(data[0]), + None, data[1].get_value()) + + elif arity_pattern == "11": + # Monad-Monad + right = Code_Token(functions.search(data[1]), + None, Relative_Argument) + + ctkn = Code_Token(functions.search(data[0]), + None, right) + + elif arity_pattern == "12": + # Monad-Dyad + left = Code_Token(functions.search(data[0]), + None, Relative_Argument) + + ctkn = Code_Token(functions.search(data[1]), + left, Relative_Argument) + + elif arity_pattern == "20": + # Dyad-Nilad + ctkn = Code_Token(functions.search(data[0]), + Relative_Argument, data[1].get_value()) - pattern += str(arities[-1][0]) - expr.append(arities[-1][1]) - arities.pop() + elif arity_pattern == "21": + # Dyad-Monad + right = Code_Token(functions.search(data[1]), + None, Relative_Argument) -if expr and pattern in patterns: - exprs.append([pattern, expr]) - expr = [] - pattern = "" + ctkn = Code_Token(functions.search(data[0]), + Relative_Argument, right) -print(exprs) + elif arity_pattern == "22": + # Dyad-Dyad + left = Code_Token(functions.search(data[0]), + Relative_Argument, Relative_Argument) + ctkn = Code_Token(functions.search(data[1]), + left, Relative_Argument) -for exp in exprs: - pattern, fns = exp + elif arity_pattern == "102": + # Monad-Nilad-Dyad + left = Code_Token(functions.search(data[0]), + None, data[1].get_value()) - if pattern == "0": - print(fns[0]) + ctkn = Code_Token(functions.search(data[2]), + left, Relative_Argument) - elif pattern == "1": - print(fns[0] + "(R)") + elif arity_pattern == "110": + # Monad-Monad-Nilad + right = Code_Token(functions.search(data[1]), + None, data[2].get_value()) - elif pattern == "2": - print(fns[0] + "(L, R)") + ctkn = Code_Token(functions.search(data[0]), + None, right) - elif pattern == "020": - print(fns[1] + "(" + fns[0] + ", " + fns[2] + ")") + elif arity_pattern == "111": + # Monad-Monad-Monad + right_1 = Code_Token(functions.search(data[2]), + None, Relative_Argument) - elif pattern == "021": - print(fns[1] + "(" + fns[0] + ", " + fns[2] + "(R))") + right = Code_Token(functions.search(data[1]), + None, right_1) - elif pattern == "022": - print(fns[1] + "(" + fns[0] + ", " + fns[2] + "(L, R))") + ctkn = Code_Token(functions.search(data[0]), + None, right) - elif pattern == "02": - print(fns[1] + "(" + fns[0] + ", R)") + elif arity_pattern == "120": + # Monad-Dyad-Nilad + left = Code_Token(functions.search(data[0]), + None, Relative_Argument) - elif pattern == "10": - print(fns[0] + "(" + fns[1] + ")") + ctkn = Code_Token(functions.search(data[1]), + left, data[2].get_value()) - elif pattern == "11": - print(fns[0] + "(" + fns[1] + "(R))") + elif arity_pattern == "121": + # Monad-Dyad-Monad + left = Code_Token(functions.search(data[0]), + None, Relative_Argument) - elif pattern == "12": - print(fns[1] + "(" + fns[0] + ", " + "R)") + right = Code_Token(functions.search(data[2]), + None, Relative_Argument) - elif pattern == "20": - print(fns[0] + "(L, " + fns[1] + ")") + ctkn = Code_Token(functions.search(data[1]), + left, right) - elif pattern == "21": - print(fns[0] + "(L, " + fns[1] + ")") + elif arity_pattern == "122": + # Monad-Dyad-Dyad + left = Code_Token(functions.search(data[0]), + None, Relative_Argument) - elif pattern == "22": - print(fns[1] + "(" + fns[0] + "(L, R), R*)") + right = Code_Token(functions.search(data[2]), + Relative_Argument, Relative_Argument) - elif pattern == "102": - print(fns[2] + "(" + fns[0] + "(" + fns[1] + "), R)") + ctkn = Code_Token(functions.search(data[1]), + left, right) - elif pattern == "110": - print(fns[0] + "(" + fns[1] + "(" + fns[2] + "))") + elif arity_pattern == "202": + # Dyad-Nilad-Dyad + left = Code_Token(functions.search(data[0]), + Relative_Argument, data[1].get_value()) - elif pattern == "111": - print(fns[0] + "(" + fns[1] + "(" + fns[2] + "(R)))") + ctkn = Code_Token(functions.search(data[2]), + left, Relative_Argument) - elif pattern == "120": - print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + ")") + elif arity_pattern == "210": + # Dyad-Monad-Nilad + right = Code_Token(functions.search(data[1]), + None, data[2].get_value()) - elif pattern == "121": - print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + "(R*))") + ctkn = Code_Token(functions.search(data[0]), + Relative_Argument, right) - elif pattern == "122": - print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + "(L*, R*))") + elif arity_pattern == "211": + # Dyad-Monad-Monad + right_1 = Code_Token(functions.search(data[2]), + None, Relative_Argument) - elif pattern == "202": - print(fns[2] + "(" + fns[0] + "(L, " + fns[1] + "), R*)") + right = Code_Token(functions.search(data[1]), + None, right_1) - elif pattern == "210": - print(fns[0] + "(L, " + fns[1] + "(" + fns[2] + "))") + ctkn = Code_Token(functions.search(data[0]), + Relative_Argument, right) - elif pattern == "211": - print(fns[0] + "(L, " + fns[1] + "(" + fns[2] + "(R*)))") + elif arity_pattern == "212": + # Dyad-Monad-Dyad + right_1 = Code_Token(functions.search(data[1]), + None, Relative_Argument) + + left = Code_Token(functions.search(data[0]), + Relative_Argument, right_1) - elif pattern == "212": - print(fns[2] + "(" + fns[0] + "(L, " + fns[1] + "(R*)), R&)") + ctkn = Code_Token(functions.search(data[2]), + left, Relative_Argument) - elif pattern == "220": - print(fns[1] + "(" + fns[0] + "(L, R), " + fns[2] + ")") + elif arity_pattern == "220": + # Dyad-Dyad-Nilad + left = Code_Token(functions.search(data[0]), + Relative_Argument, Relative_Argument) - elif pattern == "221": - print(fns[1] + "(" + fns[0] + "(L, R), " + fns[2] + "(R*))") + ctkn = Code_Token(functions.search(data[1]), + left, data[2].get_value()) - elif pattern == "222": - print(fns[2] + "(" + fns[1] + "(" + fns[0] + "(L, R), R*), R&)") -''' - + elif arity_pattern == "221": + # Dyad-Dyad-Monad + left = Code_Token(functions.search(data[0]), + Relative_Argument, Relative_Argument) + + right = Code_Token(functions.search(data[2]), + None, Relative_Argument) + + ctkn = Code_Token(functions.search(data[1]), + left, right) + + elif arity_pattern == "222": + # Triple Dyad + + left_1 = Code_Token(functions.search(data[0]), + Relative_Argument, Relative_Argument) + + left = Code_Token(functions.search(data[1]), + left_1, Relative_Argument) + + ctkn = Code_Token(functions.search(data[2]), + left, Relative_Argument) + + + code_tokens.append(ctkn) + + return code_tokens + +source: str = input() +parser: Parse.Parser = Parse.Parser(source) +x = code_tokenify(arities(parser.parse()[::-1])) +print(x[0].execute()) diff --git a/ekg/functions.py b/ekg/functions.py new file mode 100644 index 0000000..b34d909 --- /dev/null +++ b/ekg/functions.py @@ -0,0 +1,29 @@ +functions = { + "+" : lambda x, y: x + y, + "-" : lambda x, y: x - y, + "*" : lambda x, y: x * y, + "/" : lambda x, y: x / y, + "%" : lambda x, y: x % y, + "<" : lambda x, y: x < y, + ">" : lambda x, y: x > y, + "=" : lambda x, y: x == y, + "a" : lambda x, y: all(y), + "b" : lambda x, y: int(bin(y)[2:]), + "c" : lambda x, y: y in x, + "d" : lambda x, y: list(divmod(x, y)), + "e" : None, + "f" : None, + "g" : lambda x, y: range(y), + "h" : lambda x, y: x[y[0]:y[1]], + "i" : lambda x, y: "".join([i[0] + i[1] for i in zip(x, y)]), + "j" : None, + "k" : None, + "l" : lambda x, y: -1 if x.count(y) == 0 else x.index(y), + "H" : lambda x, y: y / 2 +} + +def search(what): + char = what.get_value() + if char in functions and functions[char]: + return functions[char] + return lambda x, y: y