Added subscript parsing

master
Mark 2022-11-10 09:08:58 -08:00
parent 0c215a5df4
commit bd13b10f76
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
5 changed files with 20 additions and 8 deletions

View File

@ -77,7 +77,6 @@ The lines in a file look exactly the same as regular entries in the prompt, but
## Todo (pre-release, in this order): ## Todo (pre-release, in this order):
- Export will break with :save, fix it.
- Prevent macro-chaining recursion - Prevent macro-chaining recursion
- Full-reduce option (expand all macros) - Full-reduce option (expand all macros)
- step-by-step reduction - step-by-step reduction

View File

@ -166,11 +166,14 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> list:
if (n.input.name in bound_variables): if (n.input.name in bound_variables):
raise lbn.ReductionError(f"Bound variable name conflict: \"{n.input.name}\"") raise lbn.ReductionError(f"Bound variable name conflict: \"{n.input.name}\"")
else: else:
bound_variables[n.input.name] = lbn.Bound(n.input.name) bound_variables[n.input.name] = lbn.Bound(
lamb.utils.remove_sub(n.input.name),
macro_name = n.input.name
)
n.input = bound_variables[n.input.name] n.input = bound_variables[n.input.name]
elif s == lbn.Direction.LEFT: elif s == lbn.Direction.LEFT:
del bound_variables[n.input.name] del bound_variables[n.input.macro_name] # type: ignore
return warnings return warnings

View File

@ -333,11 +333,16 @@ class History(ExpandableEndNode):
bound_counter = 0 bound_counter = 0
class Bound(EndNode): class Bound(EndNode):
def __init__(self, name: str, *, forced_id = None, runner = None): def __init__(self, name: str, *, forced_id = None, runner = None, macro_name = None):
self.name = name self.name = name
global bound_counter global bound_counter
self.runner = runner # type: ignore self.runner = runner # type: ignore
# The name of the macro this bound came from.
# Always equal to self.name, unless the macro
# this came from had a subscript.
self.macro_name: str | None = macro_name
if forced_id is None: if forced_id is None:
self.identifier = bound_counter self.identifier = bound_counter
bound_counter += 1 bound_counter += 1

View File

@ -13,7 +13,7 @@ class LambdaParser:
# We still create macro objects from them, they are turned into # We still create macro objects from them, they are turned into
# bound variables after the expression is built. # bound variables after the expression is built.
self.pp_macro = pp.Word(pp.alphas + "_") self.pp_macro = pp.Word(pp.alphas + "_")
self.pp_bound = pp.Char(pp.srange("[a-z]")) self.pp_bound = pp.Regex("[a-z][₀₁₂₃₄₅₆₈₉]*")
self.pp_name = self.pp_bound ^ self.pp_macro self.pp_name = self.pp_bound ^ self.pp_macro
self.pp_church = pp.Word(pp.nums) self.pp_church = pp.Word(pp.nums)
self.pp_history = pp.Char("$") self.pp_history = pp.Char("$")

View File

@ -5,6 +5,8 @@ from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit import print_formatted_text as printf from prompt_toolkit import print_formatted_text as printf
from importlib.metadata import version from importlib.metadata import version
import re
style = Style.from_dict({ # type: ignore style = Style.from_dict({ # type: ignore
# Basic formatting # Basic formatting
@ -108,6 +110,9 @@ def show_greeting():
"" ""
])), style = style) ])), style = style)
def remove_sub(s: str):
return re.sub("[₀₁₂₃₄₅₆₈₉]*", "", s)
def base4(n: int): def base4(n: int):
if n == 0: if n == 0:
return [0] return [0]
@ -119,9 +124,9 @@ def base4(n: int):
def subscript(num: int): def subscript(num: int):
# unicode subscripts ₀₁₂₃ # unicode subscripts ₀₁₂₃ and ₄₅₆₈₉
# usually look different than # usually look different,
# the rest, so we'll use base 4. # so we'll use base 4.
qb = base4(num) qb = base4(num)
sub = { sub = {