Very rudimentary interpreter completed

This commit is contained in:
JonoCode9374 2020-01-04 19:18:18 +11:00 committed by GitHub
parent 39aab21a07
commit 671df531be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 358 additions and 89 deletions

35
ekg/Code_Token.py Normal file
View File

@ -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

View File

@ -19,6 +19,10 @@ class Parser():
block_level = 0 block_level = 0
temp_block = "" temp_block = ""
token_list = [] token_list = []
string_mode = False
temp_string = ""
integer_mode = False
temp_integer = ""
if optional_source: if optional_source:
code = optional_source code = optional_source
@ -26,14 +30,70 @@ class Parser():
code = self.source code = self.source
for char in code: 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)) self.token_list.append(Token(TokenLib.ESCAPE, char))
escaped = False escaped = False
continue
elif char == "\\": elif char == "\\":
escaped = True 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: if block_level >= 1:
block_level += 1 block_level += 1
temp_block += char temp_block += char
@ -57,6 +117,8 @@ class Parser():
temp_block += char temp_block += char
else: else:
if char == " ":
continue
token_list.append(Token(TokenLib.INSTRUCTION, token_list.append(Token(TokenLib.INSTRUCTION,
char)) char))
@ -64,10 +126,19 @@ class Parser():
token_list.append(Token(TokenLib.BLOCK, token_list.append(Token(TokenLib.BLOCK,
temp_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 return token_list
if __name__ == "__main__": if __name__ == "__main__":
source: str = "[P[DD+s]]S3" source: str = "384+89"
parser: Parser = Parser(source) parser: Parser = Parser(source)
tokens: [Token] = parser.parse() tokens: [Token] = parser.parse()

View File

@ -26,5 +26,5 @@ class Token():
INSTRUCTION = "instruction" INSTRUCTION = "instruction"
BLOCK = "block" BLOCK = "block"
STRING = "string" STRING = "string"
INTEGER = "integer" NUMBER = "number"
ESCAPE = "escape" ESCAPE = "escape"

View File

@ -1,12 +1,16 @@
import Parse import Parse
import TokenLib import TokenLib
import string import string
from Code_Token import *
import functions
dyads: str = string.punctuation dyads: str = string.punctuation + "i"
monads: str = string.ascii_uppercase monads: str = string.ascii_uppercase
nilads: str = "1234567890" nilads: str = "1234567890"
source: str = str(reversed(input())) self = lambda x, y: y
def balance(source: str) -> str: def balance(source: str) -> str:
@ -82,124 +86,254 @@ def arities(source: [TokenLib.Token]) -> [(int, TokenLib.Token)]:
if token.get_name() == TokenLib.BLOCK: if token.get_name() == TokenLib.BLOCK:
arity_list.append([0, arity_list.append([0,
arities(token.get_data())]) arities(token.get_data())])
''' elif str(token.get_value()) in dyads:
arities = [] arity_list.append([2, token])
for char in source:
if char in dyads:
arities.append((2, char))
elif char in monads: elif str(token.get_value()) in monads:
arities.append((1, char)) arity_list.append([1, token])
else: else:
arities.append((0, char)) arity_list.append([0, token])
exprs = [] return arity_list
expr = []
patterns = ["0", "1", "2", def code_tokenify(arity_list: [(int, TokenLib.Token)]) -> [Code_Token]:
"020", "021", "022", "02", "10", "11", "12", "20", "21", "22", code_tokens = []
"102", "110", "111", "112", "120", "121", "122", exprs = []
"202", "210", "211", "212", "220", "221", "222"] expr = []
pattern = "" patterns = ["0", "1", "2",
while len(arities): "020", "021", "022", "02", "10", "11", "12", "20", "21", "22",
if pattern in patterns and pattern + str(arities[-1][0]) not in patterns: "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]) exprs.append([pattern, expr])
expr = [] expr = []
pattern = "" 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]) elif arity_pattern == "21":
expr.append(arities[-1][1]) # Dyad-Monad
arities.pop() right = Code_Token(functions.search(data[1]),
None, Relative_Argument)
if expr and pattern in patterns: ctkn = Code_Token(functions.search(data[0]),
exprs.append([pattern, expr]) Relative_Argument, right)
expr = []
pattern = ""
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: elif arity_pattern == "102":
pattern, fns = exp # Monad-Nilad-Dyad
left = Code_Token(functions.search(data[0]),
None, data[1].get_value())
if pattern == "0": ctkn = Code_Token(functions.search(data[2]),
print(fns[0]) left, Relative_Argument)
elif pattern == "1": elif arity_pattern == "110":
print(fns[0] + "(R)") # Monad-Monad-Nilad
right = Code_Token(functions.search(data[1]),
None, data[2].get_value())
elif pattern == "2": ctkn = Code_Token(functions.search(data[0]),
print(fns[0] + "(L, R)") None, right)
elif pattern == "020": elif arity_pattern == "111":
print(fns[1] + "(" + fns[0] + ", " + fns[2] + ")") # Monad-Monad-Monad
right_1 = Code_Token(functions.search(data[2]),
None, Relative_Argument)
elif pattern == "021": right = Code_Token(functions.search(data[1]),
print(fns[1] + "(" + fns[0] + ", " + fns[2] + "(R))") None, right_1)
elif pattern == "022": ctkn = Code_Token(functions.search(data[0]),
print(fns[1] + "(" + fns[0] + ", " + fns[2] + "(L, R))") None, right)
elif pattern == "02": elif arity_pattern == "120":
print(fns[1] + "(" + fns[0] + ", R)") # Monad-Dyad-Nilad
left = Code_Token(functions.search(data[0]),
None, Relative_Argument)
elif pattern == "10": ctkn = Code_Token(functions.search(data[1]),
print(fns[0] + "(" + fns[1] + ")") left, data[2].get_value())
elif pattern == "11": elif arity_pattern == "121":
print(fns[0] + "(" + fns[1] + "(R))") # Monad-Dyad-Monad
left = Code_Token(functions.search(data[0]),
None, Relative_Argument)
elif pattern == "12": right = Code_Token(functions.search(data[2]),
print(fns[1] + "(" + fns[0] + ", " + "R)") None, Relative_Argument)
elif pattern == "20": ctkn = Code_Token(functions.search(data[1]),
print(fns[0] + "(L, " + fns[1] + ")") left, right)
elif pattern == "21": elif arity_pattern == "122":
print(fns[0] + "(L, " + fns[1] + ")") # Monad-Dyad-Dyad
left = Code_Token(functions.search(data[0]),
None, Relative_Argument)
elif pattern == "22": right = Code_Token(functions.search(data[2]),
print(fns[1] + "(" + fns[0] + "(L, R), R*)") Relative_Argument, Relative_Argument)
elif pattern == "102": ctkn = Code_Token(functions.search(data[1]),
print(fns[2] + "(" + fns[0] + "(" + fns[1] + "), R)") left, right)
elif pattern == "110": elif arity_pattern == "202":
print(fns[0] + "(" + fns[1] + "(" + fns[2] + "))") # Dyad-Nilad-Dyad
left = Code_Token(functions.search(data[0]),
Relative_Argument, data[1].get_value())
elif pattern == "111": ctkn = Code_Token(functions.search(data[2]),
print(fns[0] + "(" + fns[1] + "(" + fns[2] + "(R)))") left, Relative_Argument)
elif pattern == "120": elif arity_pattern == "210":
print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + ")") # Dyad-Monad-Nilad
right = Code_Token(functions.search(data[1]),
None, data[2].get_value())
elif pattern == "121": ctkn = Code_Token(functions.search(data[0]),
print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + "(R*))") Relative_Argument, right)
elif pattern == "122": elif arity_pattern == "211":
print(fns[1] + "(" + fns[0] + "(R), " + fns[2] + "(L*, R*))") # Dyad-Monad-Monad
right_1 = Code_Token(functions.search(data[2]),
None, Relative_Argument)
elif pattern == "202": right = Code_Token(functions.search(data[1]),
print(fns[2] + "(" + fns[0] + "(L, " + fns[1] + "), R*)") None, right_1)
elif pattern == "210": ctkn = Code_Token(functions.search(data[0]),
print(fns[0] + "(L, " + fns[1] + "(" + fns[2] + "))") Relative_Argument, right)
elif pattern == "211": elif arity_pattern == "212":
print(fns[0] + "(L, " + fns[1] + "(" + fns[2] + "(R*)))") # 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": ctkn = Code_Token(functions.search(data[2]),
print(fns[2] + "(" + fns[0] + "(L, " + fns[1] + "(R*)), R&)") left, Relative_Argument)
elif pattern == "220": elif arity_pattern == "220":
print(fns[1] + "(" + fns[0] + "(L, R), " + fns[2] + ")") # Dyad-Dyad-Nilad
left = Code_Token(functions.search(data[0]),
Relative_Argument, Relative_Argument)
elif pattern == "221": ctkn = Code_Token(functions.search(data[1]),
print(fns[1] + "(" + fns[0] + "(L, R), " + fns[2] + "(R*))") left, data[2].get_value())
elif pattern == "222": elif arity_pattern == "221":
print(fns[2] + "(" + fns[1] + "(" + fns[0] + "(L, R), R*), R&)") # 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())

29
ekg/functions.py Normal file
View File

@ -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