Improved history & highlighting

master
Mark 2022-11-11 17:04:05 -08:00
parent 78cc118bfc
commit 48e7d405dd
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
7 changed files with 37 additions and 22 deletions

View File

@ -1,5 +1,6 @@
{
"cSpell.words": [
"appendleft",
"autochurch",
"delmac",
"Endnodes",

View File

@ -48,6 +48,8 @@ There are many useful macros in [macros.lamb](./macros.lamb). Load them with the
==> :load macros.lamb
```
You may use up/down arrows to recall history.
Have fun!
-------------------------------------------------
@ -66,7 +68,12 @@ Lamb understands many commands. Prefix them with a `:` in the prompt.
`:mdel [macro]` Delete a macro
`:step [yes | no]` Enable or disable step-by-step reduction. Toggle if no argument is given.
`:step [yes | no]` Enable or disable step-by-step reduction. Toggle if no argument is given. When reducing by steps, the prompt tells you what kind of reduction was done last:
- `M`: Macro expansion
- `C`: Church expansion
- `H`: History expansion
- `F`: Function application
`:expand [yes | no]` Enable or disable full expansion. Toggle if no argument is given. If full expansion is enabled, ALL macros will be expanded when printing output.
@ -81,7 +88,6 @@ The lines in a file look exactly the same as regular entries in the prompt, but
## Todo (pre-release, in this order):
- History queue
- Prevent macro-chaining recursion
- Update screenshot
- Update documentation
@ -91,7 +97,6 @@ The lines in a file look exactly the same as regular entries in the prompt, but
## Todo:
- Cleanup warnings
- Syntax highlight printouts
- Truncate long expressions in warnings
- History indexing
- Show history command

View File

@ -162,14 +162,13 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> list:
it = iter(root)
for s, n in it:
if isinstance(n, lbn.History):
if len(root.runner.history) == 0:
if root.runner.history[0] == None:
raise lbn.ReductionError("There isn't any history to reference.")
else:
warnings += [
("class:code", "$"),
("class:warn", " will be expanded to "),
("class:code", f"{n.expand()[1]}\n"),
]
("class:warn", " will be expanded to ")
] + lamb.utils.lex_str(str(n.expand()[1]))
# If this expression is part of a macro,
# make sure we don't reference it inside itself.

View File

@ -321,12 +321,12 @@ class History(ExpandableEndNode):
def expand(self) -> tuple[lbn.ReductionType, Node]:
# We shouldn't ever get here, prepare()
# catches empty history.
if len(self.runner.history) == 0:
if self.runner.history[0] == None:
raise Exception(f"Tried to expand empty history.")
# .left is VERY important!
# self.runner.history will contain Root nodes,
# and we don't want those *inside* our tree.
return lbn.ReductionType.HIST_EXPAND, lbn.clone(self.runner.history[-1].left)
return lbn.ReductionType.HIST_EXPAND, lbn.clone(self.runner.history[0].left)
def copy(self):
return History(runner = self.runner)

View File

@ -234,9 +234,8 @@ def cmd_load(command, runner):
printf(
FormattedText([
("class:ok", f"Loaded {x.label}: "),
("class:code", str(x.expr))
]),
("class:ok", f"Loaded {x.label}: ")
] + lamb.utils.lex_str(str(x.expr))),
style = lamb.utils.style
)

View File

@ -3,7 +3,7 @@ from prompt_toolkit.formatted_text import FormattedText
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit import prompt
from prompt_toolkit import print_formatted_text as printf
import enum
import collections
import math
import time
@ -58,7 +58,10 @@ class Runner:
# so that all digits appear to be changing.
self.iter_update = 231
self.history: list[lamb.nodes.Root] = []
self.history = collections.deque(
[None] * 10,
10)
# If true, reduce step-by-step.
self.step_reduction = False
@ -160,10 +163,9 @@ class Runner:
try:
s = prompt(
message = FormattedText([
("class:muted", lamb.nodes.reduction_text[red_type]),
("class:muted", f":{k:03} "),
("class:text", str(node)),
]),
("class:prompt", lamb.nodes.reduction_text[red_type]),
("class:prompt", f":{k:03} ")
] + lamb.utils.lex_str(str(node))),
style = lamb.utils.style,
key_bindings = step_bindings
)
@ -218,9 +220,8 @@ class Runner:
only_macro
):
out_text += [
("class:ok", "\n\n => "),
("class:text", str(node)), # type: ignore
]
("class:ok", "\n\n => ")
] + lamb.utils.lex_str(str(node))
printf(
@ -230,7 +231,12 @@ class Runner:
# Save to history
# Do this at the end so we don't always fully expand.
self.history.append(lamb.nodes.expand(node, force_all = True)[1])
self.history.appendleft(
lamb.nodes.expand( # type: ignore
node,
force_all = True
)[1]
)
def save_macro(
self,

View File

@ -4,6 +4,7 @@ from prompt_toolkit.lexers import Lexer
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit import print_formatted_text as printf
from importlib.metadata import version
from prompt_toolkit.document import Document
import re
@ -77,6 +78,10 @@ class LambdaLexer(Lexer):
return inner
def lex_str(s: str) -> list[tuple[str, str]]:
return LambdaLexer().lex_document(Document(s))(0)
def show_greeting():
# | _.._ _.|_
# |_(_|| | ||_)