2022-10-21 14:40:17 -07:00
|
|
|
from prompt_toolkit import PromptSession
|
|
|
|
from prompt_toolkit.completion import WordCompleter
|
2022-10-21 17:05:25 -07:00
|
|
|
from prompt_toolkit import print_formatted_text as printf
|
2022-10-21 14:40:17 -07:00
|
|
|
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
|
|
|
|
|
2022-10-20 11:02:49 -07:00
|
|
|
from parser import Parser
|
2022-10-21 17:05:25 -07:00
|
|
|
import runner
|
2022-10-20 11:02:49 -07:00
|
|
|
import tokens
|
2022-10-21 14:40:17 -07:00
|
|
|
import greeting
|
2022-10-20 11:02:49 -07:00
|
|
|
|
|
|
|
|
2022-10-21 14:40:17 -07:00
|
|
|
# Replace "\" with a pretty "λ" in the prompt
|
|
|
|
bindings = KeyBindings()
|
|
|
|
@bindings.add("\\")
|
|
|
|
def _(event):
|
|
|
|
event.current_buffer.insert_text("λ")
|
2022-10-20 11:02:49 -07:00
|
|
|
|
2022-10-21 14:40:17 -07:00
|
|
|
session = PromptSession(
|
|
|
|
message = FormattedText([
|
|
|
|
("#00FFFF", "~~> ")
|
|
|
|
]),
|
|
|
|
key_bindings = bindings
|
|
|
|
)
|
2022-10-20 11:02:49 -07:00
|
|
|
|
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
printf("\n")
|
2022-10-21 14:40:17 -07:00
|
|
|
greeting.show()
|
2022-10-20 11:02:49 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
r = runner.Runner()
|
2022-10-21 14:40:17 -07:00
|
|
|
|
|
|
|
r.run_lines([
|
2022-10-21 19:13:07 -07:00
|
|
|
"T = λab.a",
|
|
|
|
"F = λab.b",
|
|
|
|
"NOT = λa.(a F T)",
|
|
|
|
"AND = λab.(a F b)",
|
|
|
|
"OR = λab.(a T b)",
|
|
|
|
"XOR = λab.(a (NOT a b) b)",
|
|
|
|
"w = λx.(x x)",
|
|
|
|
"W = (w w)",
|
|
|
|
"Y = λf.( (λx.(f (x x))) (λx.(f (x x))) )",
|
|
|
|
"PAIR = λabi.( i a b )",
|
|
|
|
"inc = λnfa.(f (n f a))",
|
|
|
|
"zero = λax.x",
|
|
|
|
"one = λfx.(f x)"
|
2022-10-21 14:40:17 -07:00
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
i = session.prompt()
|
|
|
|
|
|
|
|
# Catch Ctrl-C and Ctrl-D
|
|
|
|
except KeyboardInterrupt:
|
2022-10-21 17:05:25 -07:00
|
|
|
printf("\n\nGoodbye.\n")
|
2022-10-20 11:02:49 -07:00
|
|
|
break
|
2022-10-21 14:40:17 -07:00
|
|
|
except EOFError:
|
2022-10-21 17:05:25 -07:00
|
|
|
printf("\n\nGoodbye.\n")
|
2022-10-21 14:40:17 -07:00
|
|
|
break
|
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
# Skip empty lines
|
2022-10-21 14:40:17 -07:00
|
|
|
if i.strip() == "":
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
# Try to run an input line.
|
|
|
|
# Catch parse errors and point them out.
|
2022-10-21 14:40:17 -07:00
|
|
|
try:
|
|
|
|
x = r.run(i)
|
|
|
|
except ppx.ParseException as e:
|
|
|
|
l = len(to_plain_text(session.message))
|
2022-10-21 17:05:25 -07:00
|
|
|
printf(FormattedText([
|
2022-10-21 14:40:17 -07:00
|
|
|
("#FF0000", " "*(e.loc + l) + "^\n"),
|
|
|
|
("#FF0000", f"Syntax error at char {e.loc}."),
|
|
|
|
("#FFFFFF", "\n")
|
|
|
|
]))
|
|
|
|
continue
|
2022-10-21 19:24:47 -07:00
|
|
|
except tokens.ReductionError as e:
|
|
|
|
printf(FormattedText([
|
|
|
|
("#FF0000", f"{e.msg}"),
|
|
|
|
("#FFFFFF", "\n")
|
|
|
|
]))
|
|
|
|
continue
|
2022-10-21 14:40:17 -07:00
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
# If this line defined a macro, print nothing.
|
|
|
|
if isinstance(x, runner.MacroStatus):
|
|
|
|
pass
|
2022-10-20 11:02:49 -07:00
|
|
|
|
2022-10-21 17:55:31 -07:00
|
|
|
if isinstance(x, runner.CommandStatus):
|
|
|
|
printf(x.formatted_text)
|
|
|
|
|
2022-10-21 17:05:25 -07:00
|
|
|
# If this line was an expression, print reduction status
|
|
|
|
elif isinstance(x, runner.ReduceStatus):
|
|
|
|
printf(FormattedText([
|
|
|
|
|
|
|
|
("#00FF00 bold", f"\nExit reason: "),
|
|
|
|
x.stop_reason.value,
|
|
|
|
|
|
|
|
("#00FF00 bold", f"\nReduction count: "),
|
|
|
|
("#FFFFFF", str(x.reduction_count)),
|
|
|
|
|
|
|
|
|
|
|
|
("#00FF00 bold", "\n\n => "),
|
|
|
|
("#FFFFFF", str(x.result)),
|
|
|
|
]))
|
2022-10-20 11:02:49 -07:00
|
|
|
|
2022-10-21 14:40:17 -07:00
|
|
|
print("")
|