2022-10-20 11:02:49 -07:00
|
|
|
from parser import Parser
|
|
|
|
import tokens
|
2022-10-20 14:05:50 -07:00
|
|
|
import colorama as cr
|
2022-10-20 11:02:49 -07:00
|
|
|
|
|
|
|
|
|
|
|
class lambda_runner:
|
|
|
|
def __init__(self):
|
|
|
|
self.macro_table = {}
|
|
|
|
self.expr = None
|
|
|
|
|
|
|
|
# Apply a list of definitions
|
|
|
|
def run_names(self, lines):
|
|
|
|
print("Added names:")
|
|
|
|
for l in lines:
|
|
|
|
if isinstance(l, str):
|
|
|
|
e = Parser.parse_assign(l)
|
|
|
|
else:
|
|
|
|
e = l
|
|
|
|
|
|
|
|
if e.label in self.macro_table:
|
|
|
|
raise NameError(f"Label {e.label} exists!")
|
|
|
|
|
|
|
|
e.exp.bind_variables()
|
|
|
|
self.macro_table[e.label] = e.exp
|
|
|
|
print(f"\t{e}")
|
|
|
|
print("\n")
|
|
|
|
|
|
|
|
def set_expr(self, expr: str | None = None):
|
|
|
|
if expr == None:
|
|
|
|
self.expr = None
|
|
|
|
print("Removed expression.\n")
|
|
|
|
return
|
|
|
|
|
|
|
|
self.expr = Parser.parse_expression(expr)
|
|
|
|
self.expr.bind_variables()
|
|
|
|
print(f"Set expression to {self.expr}\n")
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
if isinstance(self.expr, tokens.lambda_apply):
|
|
|
|
self.expr = self.expr.expand(self.macro_table)
|
|
|
|
elif isinstance(self.expr, tokens.lambda_func):
|
|
|
|
self.expr = self.expr.expand(self.macro_table)
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
return self.expr
|
|
|
|
|
|
|
|
|
2022-10-20 14:05:50 -07:00
|
|
|
|
|
|
|
"""
|
|
|
|
| _.._ _.|_
|
|
|
|
|_(_|| | ||_)
|
|
|
|
1.1.0
|
|
|
|
|
|
|
|
__ __
|
|
|
|
,-` `` `,
|
|
|
|
(` \ )
|
|
|
|
(` \ `)
|
|
|
|
(, / \ _)
|
|
|
|
(` / \ )
|
|
|
|
`'._.--._.'
|
|
|
|
|
|
|
|
A λ calculus engine
|
|
|
|
"""
|
|
|
|
|
|
|
|
b = cr.Style.BRIGHT
|
|
|
|
v = cr.Fore.GREEN + cr.Style.BRIGHT
|
|
|
|
l = cr.Fore.RED + cr.Style.BRIGHT
|
|
|
|
n = cr.Style.RESET_ALL
|
|
|
|
t = cr.Fore.GREEN
|
|
|
|
|
|
|
|
print(f"""
|
|
|
|
|
|
|
|
{b} | _.._ _.|_
|
|
|
|
|_(_|| | ||_){n}
|
|
|
|
{v}1.1.0{n}
|
|
|
|
__ __
|
|
|
|
,-` `` `,
|
|
|
|
(` {l}\{n} )
|
|
|
|
(` {l}\{n} `)
|
|
|
|
(, {l}/ \{n} _)
|
|
|
|
(` {l}/ \{n} )
|
|
|
|
`'._.--._.'
|
|
|
|
|
|
|
|
{t} A λ calculus engine{n}
|
|
|
|
|
|
|
|
"""[1:-1])
|
|
|
|
|
|
|
|
|
2022-10-20 11:02:49 -07:00
|
|
|
r = lambda_runner()
|
|
|
|
|
|
|
|
r.run_names([
|
|
|
|
"T = a -> b -> a",
|
|
|
|
"F = a -> b -> a",
|
|
|
|
"NOT = a -> (a F T)",
|
|
|
|
"AND = a -> b -> (a F b)",
|
|
|
|
"OR = a -> b -> (a T b)",
|
|
|
|
"XOR = a -> b -> (a (NOT a b) b)"
|
|
|
|
])
|
|
|
|
|
|
|
|
r.run_names([
|
|
|
|
"w = x -> (x x)",
|
|
|
|
"W = (w w)",
|
|
|
|
"Y = f -> ( (x -> (f (x x))) (x -> (f (x x))) )",
|
|
|
|
#"l = if_true -> if_false -> which -> ( which if_true if_false )"
|
|
|
|
])
|
|
|
|
|
|
|
|
r.run_names([
|
|
|
|
"inc = n -> f -> x -> (f (n f x))",
|
|
|
|
"zero = a -> x -> x",
|
|
|
|
"one = f -> x -> (f x)",
|
|
|
|
])
|
|
|
|
|
|
|
|
print("\n")
|
|
|
|
|
|
|
|
#AND = r.run()
|
|
|
|
#OR = r.run()
|
|
|
|
#XOR = r.run()
|
|
|
|
|
|
|
|
r.set_expr(
|
|
|
|
"(" +
|
|
|
|
"inc (inc (inc (zero)))"
|
|
|
|
+ ")"
|
|
|
|
)
|
|
|
|
|
|
|
|
print(repr(r.expr))
|
|
|
|
print("")
|
|
|
|
|
|
|
|
outs = [str(r.expr)]
|
|
|
|
for i in range(300):
|
|
|
|
x = r.run()
|
|
|
|
s = str(x)
|
|
|
|
p = s if len(s) < 100 else s[:97] + "..."
|
|
|
|
|
|
|
|
if s in outs:
|
|
|
|
print(p)
|
|
|
|
print("\nLoop detected, exiting.")
|
|
|
|
break
|
|
|
|
|
|
|
|
if x is None:
|
|
|
|
print("\nCannot evaluate any further.")
|
|
|
|
break
|
|
|
|
|
|
|
|
outs.append(s)
|
|
|
|
print(p)
|
|
|
|
|
|
|
|
print(f"Performed {i} {'operations' if i != 1 else 'operation'}.")
|