Cleaned up greeting, add simple prompt, moved runner

master
Mark 2022-10-21 14:40:17 -07:00
parent 94f8963436
commit 9ed159dee9
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
2 changed files with 127 additions and 133 deletions

53
greeting.py Normal file
View File

@ -0,0 +1,53 @@
from prompt_toolkit.styles import Style
from prompt_toolkit.formatted_text import HTML, to_formatted_text
from prompt_toolkit import print_formatted_text
# | _.._ _.|_
# |_(_|| | ||_)
# 1.1.0
#
# __ __
# ,-` `` `,
# (` \ )
# (` \ `)
# (, / \ _)
# (` / \ )
# `'._.--._.'
#
# A λ calculus engine
style = Style.from_dict({
# Heading
"_h": "#FFFFFF bold",
# Version
"_v": "#B4EC85 bold",
# Lambda
"_l": "#FF6600 bold",
# Subtitle
"_s": "#B4EC85 bold"
})
html = HTML(f"""
<_h> | _.._ _.|_
|_(_|| | ||_)</_h>
<_v>1.1.0</_v>
__ __
,-` `` `,
(` <_l>\\</_l> )
(` <_l>\\</_l> `)
(, <_l>/ \\</_l> _)
(` <_l>/ \\</_l> )
`'._.--._.'
<_s> A λ calculus engine</_s>
"""[1:-1])
def show():
print_formatted_text(html, style = style)

209
main.py
View File

@ -1,146 +1,87 @@
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import FormattedText
from prompt_toolkit.formatted_text import to_plain_text
from prompt_toolkit.key_binding import KeyBindings
from pyparsing import exceptions as ppx
from parser import Parser from parser import Parser
from runner import Runner
import tokens import tokens
import colorama as cr import greeting
class lambda_runner: # Replace "\" with a pretty "λ" in the prompt
def __init__(self): bindings = KeyBindings()
self.macro_table = {} @bindings.add("\\")
self.expr = None def _(event):
event.current_buffer.insert_text("λ")
# Apply a list of definitions session = PromptSession(
def run_names(self, lines): message = FormattedText([
print("Added names:") ("#00FFFF", "~~> ")
for l in lines: ]),
if isinstance(l, str): key_bindings = bindings
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
"""
| _.._ _.|_
|_(_|| | ||_)
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])
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))
greeting.show()
r = Runner()
r.run_lines([
"T = λa.λb.a",
"F = λa.λb.b",
"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)",
#"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 )"
#"inc = n -> f -> x -> (f (n f x))",
#"zero = a -> x -> x",
#"one = f -> x -> (f x)",
])
while True:
try:
i = session.prompt()
# Catch Ctrl-C and Ctrl-D
except KeyboardInterrupt:
print("")
break
except EOFError:
print("") 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 break
if x is None: if i.strip() == "":
print("\nCannot evaluate any further.") continue
break
outs.append(s)
print(p)
print(f"Performed {i} {'operations' if i != 1 else 'operation'}.") try:
x = r.run(i)
except ppx.ParseException as e:
l = len(to_plain_text(session.message))
print_formatted_text(FormattedText([
("#FF0000", " "*(e.loc + l) + "^\n"),
("#FF0000", f"Syntax error at char {e.loc}."),
("#FFFFFF", "\n")
]))
continue
print_formatted_text(FormattedText([
("#00FF00", " = "),
("#FFFFFF", str(x))
]))
print("")