From 89bc4bd2c03f97bd7ce7c142a8982cb3b1262a33 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 9 Nov 2022 21:47:55 -0800 Subject: [PATCH] Minor warning cleanup --- README.md | 4 ++-- lamb/nodes/functions.py | 24 ++++++++++++++++-------- lamb/nodes/nodes.py | 4 +++- lamb/runner/runner.py | 38 ++++++++++---------------------------- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 26a0d9e..f77dbc9 100644 --- a/README.md +++ b/README.md @@ -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): - - Cleanup warnings - Truncate long expressions in warnings - Prevent macro-chaining recursion - Full-reduce option (expand all macros) @@ -89,6 +88,8 @@ The lines in a file look exactly the same as regular entries in the prompt, but ## Todo: + - Cleanup warnings + - Syntax highlight printouts - History queue + indexing - Show history command - Loop detection @@ -97,6 +98,5 @@ The lines in a file look exactly the same as regular entries in the prompt, but - Command-line options (load a file) - Unchurch command: make church numerals human-readable - Better Syntax highlighting - - Syntax highlight printouts - Complete file names and commands - Tests \ No newline at end of file diff --git a/lamb/nodes/functions.py b/lamb/nodes/functions.py index 79b13a8..1d03f33 100644 --- a/lamb/nodes/functions.py +++ b/lamb/nodes/functions.py @@ -95,7 +95,7 @@ def clone(node: lbn.Node): break return out -def prepare(root: lbn.Root, *, ban_macro_name = None) -> dict: +def prepare(root: lbn.Root, *, ban_macro_name = None) -> list: """ Prepare an expression for expansion. This will does the following: @@ -109,15 +109,19 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> dict: bound_variables = {} - output = { - "has_history": False, - "free_variables": set() - } + warnings = [] it = iter(root) for s, n in it: if isinstance(n, lbn.History): - output["has_history"] = True + if len(root.runner.history) == 0: + 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"), + ] # If this expression is part of a macro, # make sure we don't reference it inside itself. @@ -135,7 +139,11 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> dict: # Turn undefined macros into free variables elif n.name not in root.runner.macro_table: - output["free_variables"].add(n.name) + warnings += [ + ("class:warn", "Name "), + ("class:code", n.name), + ("class:warn", " is a free variable\n"), + ] n.parent.set_side( n.parent_side, n.to_freevar() @@ -158,7 +166,7 @@ def prepare(root: lbn.Root, *, ban_macro_name = None) -> dict: elif s == lbn.Direction.LEFT: del bound_variables[n.input.name] - return output + return warnings # Apply a function. # Returns the function's output. diff --git a/lamb/nodes/nodes.py b/lamb/nodes/nodes.py index a1ba50e..70f877e 100644 --- a/lamb/nodes/nodes.py +++ b/lamb/nodes/nodes.py @@ -319,8 +319,10 @@ class History(ExpandableEndNode): return "$" def expand(self) -> tuple[lbn.ReductionType, Node]: + # We shouldn't ever get here, prepare() + # catches empty history. if len(self.runner.history) == 0: - raise lbn.ReductionError(f"There isn't any history to reference.") + 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. diff --git a/lamb/runner/runner.py b/lamb/runner/runner.py index 2e4acda..9a7804d 100644 --- a/lamb/runner/runner.py +++ b/lamb/runner/runner.py @@ -56,25 +56,23 @@ class Runner: message = self.prompt_message ) - def parse(self, line) -> tuple[lamb.nodes.Root | MacroDef | Command, dict]: + def parse(self, line) -> tuple[lamb.nodes.Root | MacroDef | Command, list]: e = self.parser.parse_line(line) - o = {} + w = [] if isinstance(e, MacroDef): e.expr = lamb.nodes.Root(e.expr) e.set_runner(self) - o = lamb.nodes.prepare(e.expr, ban_macro_name = e.label) + w = lamb.nodes.prepare(e.expr, ban_macro_name = e.label) elif isinstance(e, lamb.nodes.Node): e = lamb.nodes.Root(e) e.set_runner(self) - o = lamb.nodes.prepare(e) + w = lamb.nodes.prepare(e) - return e, o + return e, w - def reduce(self, node: lamb.nodes.Root, *, status = {}) -> None: - - warning_text = [] + def reduce(self, node: lamb.nodes.Root, *, warnings = []) -> None: # Reduction Counter. # We also count macro (and church) expansions, @@ -86,14 +84,6 @@ class Runner: start_time = time.time() out_text = [] - if status["has_history"] and len(self.history) != 0: - warning_text += [ - ("class:code", "$"), - ("class:warn", " will be expanded to "), - ("class:code", str(self.history[-1])), - ("class:warn", "\n") - ] - only_macro = ( isinstance(node.left, lamb.nodes.Macro) or isinstance(node.left, lamb.nodes.Church) @@ -103,16 +93,8 @@ class Runner: m, node = lamb.nodes.expand(node, force_all = only_macro) macro_expansions += m - - for i in status["free_variables"]: - warning_text += [ - ("class:warn", "Name "), - ("class:code", i), - ("class:warn", " is a free variable\n"), - ] - - if len(warning_text) != 0: - printf(FormattedText(warning_text), style = lamb.utils.style) + if len(warnings) != 0: + printf(FormattedText(warnings), style = lamb.utils.style) while ( @@ -210,7 +192,7 @@ class Runner: *, silent = False ) -> None: - e, o = self.parse(line) + e, w = self.parse(line) # If this line is a macro definition, save the macro. if isinstance(e, MacroDef): @@ -230,7 +212,7 @@ class Runner: # If this line is a plain expression, reduce it. elif isinstance(e, lamb.nodes.Node): - self.reduce(e, status = o) + self.reduce(e, warnings = w) # We shouldn't ever get here. else: