From 4241f5fe743766d016f354b343bea78dd8a6e3f0 Mon Sep 17 00:00:00 2001 From: mmatera Date: Fri, 28 Jul 2023 23:14:09 -0300 Subject: [PATCH 1/3] remove weird form of Infix with list of operators. --- mathics/builtin/layout.py | 3 --- mathics/builtin/makeboxes.py | 42 +++++++++++------------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/mathics/builtin/layout.py b/mathics/builtin/layout.py index 4fca006d1..fda4974e9 100644 --- a/mathics/builtin/layout.py +++ b/mathics/builtin/layout.py @@ -175,9 +175,6 @@ class Infix(Builtin): >> g[a, b] * c = c (a # b) - >> Infix[{a, b, c}, {"+", "-"}] - = a + b - c - #> Format[r[items___]] := Infix[If[Length[{items}] > 1, {items}, {ab}], "~"] #> r[1, 2, 3] = 1 ~ 2 ~ 3 diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index 2c25b84db..1647403a0 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -39,17 +39,11 @@ def int_to_s_exp(expr, n): return s, exp, nonnegative -# FIXME: op should be a string, so remove the Union. -def make_boxes_infix( - elements, op: Union[String, list], precedence: int, grouping, form: Symbol -): +def make_boxes_infix(elements, op: String, precedence: int, grouping, form: Symbol): result = [] for index, element in enumerate(elements): if index > 0: - if isinstance(op, list): - result.append(op[index - 1]) - else: - result.append(op) + result.append(op) parenthesized = False if grouping == "System`NonAssociative": parenthesized = True @@ -476,31 +470,19 @@ def format_operator(operator) -> Union[String, BaseElement]: elements = expr.elements if len(elements) > 1: - if operator.has_form("List", len(elements) - 1): - operator = [format_operator(op) for op in operator.elements] - return make_boxes_infix( - elements, operator, py_precedence, grouping, form + encoding_rule = evaluation.definitions.get_ownvalue("$CharacterEncoding") + encoding = "UTF8" if encoding_rule is None else encoding_rule.replace.value + op_str = ( + operator.value if isinstance(operator, String) else operator.short_name + ) + if encoding == "ASCII": + operator = format_operator( + String(operator_to_ascii.get(op_str, op_str)) ) else: - encoding_rule = evaluation.definitions.get_ownvalue( - "$CharacterEncoding" - ) - encoding = ( - "UTF8" if encoding_rule is None else encoding_rule.replace.value - ) - op_str = ( - operator.value - if isinstance(operator, String) - else operator.short_name + operator = format_operator( + String(operator_to_unicode.get(op_str, op_str)) ) - if encoding == "ASCII": - operator = format_operator( - String(operator_to_ascii.get(op_str, op_str)) - ) - else: - operator = format_operator( - String(operator_to_unicode.get(op_str, op_str)) - ) return make_boxes_infix(elements, operator, py_precedence, grouping, form) From 1db0228e52d10cc85f3115610cdcb00f33c1f182 Mon Sep 17 00:00:00 2001 From: mmatera Date: Fri, 28 Jul 2023 23:38:47 -0300 Subject: [PATCH 2/3] fix Infix grouping --- mathics/builtin/makeboxes.py | 40 +++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/mathics/builtin/makeboxes.py b/mathics/builtin/makeboxes.py index 1647403a0..8bbee6f74 100644 --- a/mathics/builtin/makeboxes.py +++ b/mathics/builtin/makeboxes.py @@ -18,7 +18,14 @@ from mathics.core.list import ListExpression from mathics.core.number import dps from mathics.core.symbols import Atom, Symbol -from mathics.core.systemsymbols import SymbolInputForm, SymbolOutputForm, SymbolRowBox +from mathics.core.systemsymbols import ( + SymbolInputForm, + SymbolLeft, + SymbolNone, + SymbolOutputForm, + SymbolRight, + SymbolRowBox, +) from mathics.eval.makeboxes import ( NEVER_ADD_PARENTHESIS, _boxed_string, @@ -26,6 +33,8 @@ parenthesize, ) +SymbolNonAssociative = Symbol("System`NonAssociative") + def int_to_s_exp(expr, n): n = expr.get_int_value() @@ -39,18 +48,26 @@ def int_to_s_exp(expr, n): return s, exp, nonnegative -def make_boxes_infix(elements, op: String, precedence: int, grouping, form: Symbol): +def make_boxes_infix(elements, op: String, precedence: int, form: Symbol): result = [] + last_indx = len(elements) - 1 for index, element in enumerate(elements): - if index > 0: - result.append(op) + grouping = SymbolNone + if element.has_form("Infix", 4): + grouping = element.elements[-1] + + # if grouping not in (SymbolNone, SymbolLeft,SymbolRight,SymbolNonAssociative): + # send message + parenthesized = False - if grouping == "System`NonAssociative": - parenthesized = True - elif grouping == "System`Left" and index > 0: - parenthesized = True - elif grouping == "System`Right" and index == 0: - parenthesized = True + if index == 0: + parenthesized = grouping in (SymbolRight, SymbolNonAssociative) + elif index == last_indx: + result.append(op) + parenthesized = grouping in (SymbolLeft, SymbolNonAssociative) + else: + result.append(op) + parenthesized = grouping is (SymbolLeft, SymbolRight, SymbolNonAssociative) element_boxes = MakeBoxes(element, form) element = parenthesize(precedence, element, element_boxes, parenthesized) @@ -462,7 +479,6 @@ def format_operator(operator) -> Union[String, BaseElement]: py_precedence = ( precedence.value if hasattr(precedence, "value") else NEVER_ADD_PARENTHESIS ) - grouping = grouping.get_name() if isinstance(expr, Atom): evaluation.message("Infix", "normal", Integer1) @@ -484,7 +500,7 @@ def format_operator(operator) -> Union[String, BaseElement]: String(operator_to_unicode.get(op_str, op_str)) ) - return make_boxes_infix(elements, operator, py_precedence, grouping, form) + return make_boxes_infix(elements, operator, py_precedence, form) elif len(elements) == 1: return MakeBoxes(elements[0], form) From 3a161177477902affa439ddc808885358c8e1d26 Mon Sep 17 00:00:00 2001 From: mmatera Date: Fri, 28 Jul 2023 23:53:10 -0300 Subject: [PATCH 3/3] adding doctest and explanation about the use of assoc parameter --- mathics/builtin/layout.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mathics/builtin/layout.py b/mathics/builtin/layout.py index fda4974e9..e4f3b2c51 100644 --- a/mathics/builtin/layout.py +++ b/mathics/builtin/layout.py @@ -175,6 +175,16 @@ class Infix(Builtin): >> g[a, b] * c = c (a # b) + + Notice that $assoc$ controls when an element is going to be embraced by parenthesis, according to \ + the position in an outer 'Infix' expression. For example, + + >> Infix[{a, Infix[{b,c},"#",300, Left]}, "@", 300, Right] + = a @ (b # c) + + because the inner 'Infix' is tagger as 'Left' associative, disregarding the associativity of \ + the outer 'Infix' expression. + #> Format[r[items___]] := Infix[If[Length[{items}] > 1, {items}, {ab}], "~"] #> r[1, 2, 3] = 1 ~ 2 ~ 3