Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Independent FullForm #1316

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mathics/builtin/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from mathics.eval.makeboxes import (
eval_generic_makeboxes,
eval_infix,
eval_makeboxes_fullform,
eval_postprefix,
format_element,
parenthesize,
Expand Down Expand Up @@ -107,9 +108,13 @@ class MakeBoxes(Builtin):
}
summary_text = "settable low-level translator from expression to display boxes"

def eval_fullform(self, expr, evaluation):
"""MakeBoxes[expr_, FullForm]"""
return eval_makeboxes_fullform(expr, evaluation)

def eval_general(self, expr, f, evaluation):
"""MakeBoxes[expr_,
f:TraditionalForm|StandardForm|OutputForm|InputForm|FullForm]"""
f:TraditionalForm|StandardForm|OutputForm|InputForm]"""
return eval_generic_makeboxes(self, expr, f, evaluation)

def eval_outerprecedenceform(self, expr, precedence, form, evaluation):
Expand Down
2 changes: 2 additions & 0 deletions mathics/eval/makeboxes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
_boxed_string,
eval_generic_makeboxes,
eval_makeboxes,
eval_makeboxes_fullform,
format_element,
int_to_string_shorter_repr,
to_boxes,
Expand All @@ -31,6 +32,7 @@
"eval_generic_makeboxes",
"eval_infix",
"eval_makeboxes",
"eval_makeboxes_fullform",
"eval_mathmlform",
"eval_postprefix",
"eval_tableform",
Expand Down
22 changes: 8 additions & 14 deletions mathics/eval/makeboxes/formatvalues.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,10 @@ def do_format_rational(
if not isinstance(element, Rational):
return None
if form is SymbolFullForm:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is not part of the changed code, but I have this nagging feeling that code like if form is ... is not the right way ultimately we should be approaching this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rocky, feel free to push over all the changes you find useful.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, I'd like to defer work on this kind of code until a better handle on MakeBox migration.

return do_format_expression(
Expression(
Expression(SymbolHoldForm, SymbolRational),
element.numerator(),
element.denominator(),
),
evaluation,
form,
return Expression(
SymbolRational,
element.numerator(),
element.denominator(),
)
else:
numerator = element.numerator()
Expand All @@ -211,12 +207,10 @@ def do_format_complex(
if not isinstance(element, Complex):
return None
if form is SymbolFullForm:
return do_format_expression(
Expression(
Expression(SymbolHoldForm, SymbolComplex), element.real, element.imag
),
evaluation,
form,
return Expression(
SymbolComplex,
element.real,
element.imag,
)

parts: List[Any] = []
Expand Down
80 changes: 59 additions & 21 deletions mathics/eval/makeboxes/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
from mathics.core.element import BaseElement, BoxElementMixin
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.symbols import Atom, Symbol, SymbolFullForm, SymbolMakeBoxes
from mathics.core.systemsymbols import SymbolStandardForm
from mathics.core.symbols import (
Atom,
Symbol,
SymbolFullForm,
SymbolList,
SymbolMakeBoxes,
)
from mathics.core.systemsymbols import ( # SymbolRule, SymbolRuleDelayed,
SymbolStandardForm,
)
from mathics.eval.makeboxes.formatvalues import do_format
from mathics.eval.makeboxes.precedence import parenthesize

Expand All @@ -38,7 +46,7 @@ def to_boxes(x, evaluation: Evaluation, options={}) -> BoxElementMixin:
return x_boxed
if isinstance(x_boxed, Atom):
return to_boxes(x_boxed, evaluation, options)
return eval_makeboxes(Expression(SymbolFullForm, x), evaluation)
return eval_makeboxes_fullform(x, evaluation)


# this temporarily replaces the _BoxedString class
Expand Down Expand Up @@ -126,23 +134,53 @@ def int_to_string_shorter_repr(value: int, form: Symbol, max_digits=640):
return String(value_str)


def eval_fullform_makeboxes(
self, expr, evaluation: Evaluation, form=SymbolStandardForm
) -> Optional[BaseElement]:
"""
This function takes the definitions provided by the evaluation
object, and produces a boxed form for expr.
# TODO: evaluation is needed because `atom_to_boxes` uses it. Can we remove this
# argument?
def eval_makeboxes_fullform(
expr: BaseElement, evaluation: Evaluation
) -> BoxElementMixin:
"""Same as MakeBoxes[FullForm[expr_], f_]"""
from mathics.builtin.box.layout import RowBox

Basically: MakeBoxes[expr // FullForm]
"""
# This is going to be reimplemented.
expr = Expression(SymbolFullForm, expr)
return Expression(SymbolMakeBoxes, expr, form).evaluate(evaluation)
if isinstance(expr, BoxElementMixin):
expr = expr.to_expression()
if isinstance(expr, Atom):
return expr.atom_to_boxes(SymbolFullForm, evaluation)
head, elements = expr.head, expr.elements
boxed_elements = tuple(
(eval_makeboxes_fullform(element, evaluation) for element in elements)
)
# In some places it would be less verbose to use special outputs for
# `List`, `Rule` and `RuleDelayed`. WMA does not that, but we do it for
# `List`.
#
# if head is SymbolRule and len(elements) == 2:
# return RowBox(boxed_elements[0], String("->"), boxed_elements[1])
# if head is SymbolRuleDelayed and len(elements) == 2:
# return RowBox(boxed_elements[0], String(":>"), boxed_elements[1])
if head is SymbolList:
left, right, sep = (String(ch) for ch in ("{", "}", ","))
result_elements = [left]
else:
left, right, sep = (String(ch) for ch in ("[", "]", ", "))
result_elements = [eval_makeboxes_fullform(head, evaluation), left]

if len(boxed_elements) > 1:
arguments = []
for b_elem in boxed_elements:
if len(arguments) > 0:
arguments.append(sep)
arguments.append(b_elem)
result_elements.append(RowBox(*arguments))
elif len(boxed_elements) == 1:
result_elements.append(boxed_elements[0])
result_elements.append(right)
return RowBox(*result_elements)


def eval_generic_makeboxes(self, expr, f, evaluation):
"""MakeBoxes[expr_,
f:TraditionalForm|StandardForm|OutputForm|InputForm|FullForm]"""
f:TraditionalForm|StandardForm|OutputForm|InputForm]"""
from mathics.builtin.box.layout import RowBox

if isinstance(expr, BoxElementMixin):
Expand Down Expand Up @@ -174,7 +212,6 @@ def eval_generic_makeboxes(self, expr, f, evaluation):
if f_name in (
"System`InputForm",
"System`OutputForm",
"System`FullForm",
):
sep = ", "
else:
Expand Down Expand Up @@ -210,6 +247,8 @@ def eval_makeboxes(
Basically: MakeBoxes[expr // form]
"""
# This is going to be reimplemented.
if form is SymbolFullForm:
return eval_makeboxes_fullform(expr, evaluation)
return Expression(SymbolMakeBoxes, expr, form).evaluate(evaluation)


Expand All @@ -220,14 +259,13 @@ def format_element(
Applies formats associated to the expression, and then calls Makeboxes
"""
evaluation.is_boxing = True
expr = do_format(element, evaluation, form)
if expr is None:
formatted_expr = do_format(element, evaluation, form)
if formatted_expr is None:
return None
result = Expression(SymbolMakeBoxes, expr, form)
result_box = result.evaluate(evaluation)
result_box = eval_makeboxes(formatted_expr, evaluation, form)
if isinstance(result_box, String):
return result_box
if isinstance(result_box, BoxElementMixin):
return result_box
else:
return format_element(element, evaluation, SymbolFullForm, **kwargs)
return eval_makeboxes_fullform(element, evaluation)