From 0c215a5df4df51c4a3084cf6a9a7bde8d90e80cf Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 10 Nov 2022 08:02:28 -0800 Subject: [PATCH] Fixed print method --- README.md | 2 +- lamb/nodes/functions.py | 32 +++++++++++++++++++------------- lamb/utils.py | 17 ++++++++++++++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 3a69956..de7bd61 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ The lines in a file look exactly the same as regular entries in the prompt, but ## Todo (pre-release, in this order): - - Fix unique bound variable printer + - Export will break with :save, fix it. - Prevent macro-chaining recursion - Full-reduce option (expand all macros) - step-by-step reduction diff --git a/lamb/nodes/functions.py b/lamb/nodes/functions.py index 1d03f33..423bdb3 100644 --- a/lamb/nodes/functions.py +++ b/lamb/nodes/functions.py @@ -12,35 +12,41 @@ def print_node(node: lbn.Node, *, export: bool = False) -> str: for s, n in node: if isinstance(n, lbn.EndNode): if isinstance(n, lbn.Bound): - if n.identifier not in bound_subs.keys(): - o = n.print_value(export = export) - if o in bound_subs.items(): - i = 1 - while o in bound_subs.items(): - o = lamb.utils.subscript(i := i + 1) - bound_subs[n.identifier] = o - else: - bound_subs[n.identifier] = n.print_value() - - out += bound_subs[n.identifier] else: out += n.print_value(export = export) elif isinstance(n, lbn.Func): + # This should never be true, but + # keep this here to silence type checker. + if not isinstance(n.input, lbn.Bound): + raise Exception("input is macro, something is wrong.") + if s == lbn.Direction.UP: + o = n.input.print_value(export = export) + if o in bound_subs.values(): + i = -1 + p = o + while o in bound_subs.values(): + o = p + lamb.utils.subscript(i := i + 1) + bound_subs[n.input.identifier] = o + else: + bound_subs[n.input.identifier] = n.input.print_value() + if isinstance(n.parent, lbn.Call): out += "(" if isinstance(n.parent, lbn.Func): - out += n.input.name + out += bound_subs[n.input.identifier] else: - out += "λ" + n.input.name + out += "λ" + bound_subs[n.input.identifier] if not isinstance(n.left, lbn.Func): out += "." + elif s == lbn.Direction.LEFT: if isinstance(n.parent, lbn.Call): out += ")" + del bound_subs[n.input.identifier] elif isinstance(n, lbn.Call): if s == lbn.Direction.UP: diff --git a/lamb/utils.py b/lamb/utils.py index cfe151b..22a8a09 100644 --- a/lamb/utils.py +++ b/lamb/utils.py @@ -108,7 +108,22 @@ def show_greeting(): "" ])), style = style) +def base4(n: int): + if n == 0: + return [0] + digits = [] + while n: + digits.append(n % 4) + n //= 4 + return digits[::-1] + def subscript(num: int): + + # unicode subscripts ₀₁₂₃ + # usually look different than + # the rest, so we'll use base 4. + qb = base4(num) + sub = { "0": "₀", "1": "₁", @@ -136,5 +151,5 @@ def subscript(num: int): } return "".join( - [sup[x] for x in str(num)] + [sub[str(x)] for x in qb] ) \ No newline at end of file