88
99from typing import Optional , Union
1010
11- from mathics .core .atoms import String
11+ from mathics .core .atoms import Complex , Integer , Rational , String
1212from mathics .core .element import BaseElement , BoxElementMixin
1313from mathics .core .evaluation import Evaluation
1414from mathics .core .expression import Expression
15- from mathics .core .symbols import Atom , Symbol , SymbolFullForm , SymbolMakeBoxes
16- from mathics .core .systemsymbols import SymbolStandardForm
15+ from mathics .core .symbols import (
16+ Atom ,
17+ Symbol ,
18+ SymbolFullForm ,
19+ SymbolList ,
20+ SymbolMakeBoxes ,
21+ )
22+ from mathics .core .systemsymbols import ( # SymbolRule, SymbolRuleDelayed,
23+ SymbolComplex ,
24+ SymbolRational ,
25+ SymbolStandardForm ,
26+ )
1727from mathics .eval .makeboxes .formatvalues import do_format
1828from mathics .eval .makeboxes .precedence import parenthesize
1929
@@ -38,7 +48,7 @@ def to_boxes(x, evaluation: Evaluation, options={}) -> BoxElementMixin:
3848 return x_boxed
3949 if isinstance (x_boxed , Atom ):
4050 return to_boxes (x_boxed , evaluation , options )
41- return eval_makeboxes ( Expression ( SymbolFullForm , x ) , evaluation )
51+ return eval_makeboxes_fullform ( x , evaluation )
4252
4353
4454# this temporarily replaces the _BoxedString class
@@ -126,23 +136,58 @@ def int_to_string_shorter_repr(value: int, form: Symbol, max_digits=640):
126136 return String (value_str )
127137
128138
129- def eval_fullform_makeboxes (
130- self , expr , evaluation : Evaluation , form = SymbolStandardForm
131- ) -> Optional [BaseElement ]:
132- """
133- This function takes the definitions provided by the evaluation
134- object, and produces a boxed form for expr.
139+ # TODO: evaluation is needed because `atom_to_boxes` uses it. Can we remove this
140+ # argument?
141+ def eval_makeboxes_fullform (
142+ expr : BaseElement , evaluation : Evaluation
143+ ) -> BoxElementMixin :
144+ """Same as MakeBoxes[FullForm[expr_], f_]"""
145+ from mathics .builtin .box .layout import RowBox
135146
136- Basically: MakeBoxes[expr // FullForm]
137- """
138- # This is going to be reimplemented.
139- expr = Expression (SymbolFullForm , expr )
140- return Expression (SymbolMakeBoxes , expr , form ).evaluate (evaluation )
147+ if isinstance (expr , BoxElementMixin ):
148+ expr = expr .to_expression ()
149+ if isinstance (expr , Atom ):
150+ if isinstance (expr , Rational ):
151+ expr = Expression (SymbolRational , expr .numerator (), expr .denominator ())
152+ elif isinstance (expr , Complex ):
153+ expr = Expression (SymbolComplex , expr .real , expr .imag )
154+ else :
155+ return expr .atom_to_boxes (SymbolFullForm , evaluation )
156+ head , elements = expr .head , expr .elements
157+ boxed_elements = tuple (
158+ (eval_makeboxes_fullform (element , evaluation ) for element in elements )
159+ )
160+ # In some places it would be less verbose to use special outputs for
161+ # `List`, `Rule` and `RuleDelayed`. WMA does not that, but we do it for
162+ # `List`.
163+ #
164+ # if head is SymbolRule and len(elements) == 2:
165+ # return RowBox(boxed_elements[0], String("->"), boxed_elements[1])
166+ # if head is SymbolRuleDelayed and len(elements) == 2:
167+ # return RowBox(boxed_elements[0], String(":>"), boxed_elements[1])
168+ if head is SymbolList :
169+ left , right , sep = (String (ch ) for ch in ("{" , "}" , "," ))
170+ result_elements = [left ]
171+ else :
172+ left , right , sep = (String (ch ) for ch in ("[" , "]" , ", " ))
173+ result_elements = [eval_makeboxes_fullform (head , evaluation ), left ]
174+
175+ if len (boxed_elements ) > 1 :
176+ arguments = []
177+ for b_elem in boxed_elements :
178+ if len (arguments ) > 0 :
179+ arguments .append (sep )
180+ arguments .append (b_elem )
181+ result_elements .append (RowBox (* arguments ))
182+ elif len (boxed_elements ) == 1 :
183+ result_elements .append (boxed_elements [0 ])
184+ result_elements .append (right )
185+ return RowBox (* result_elements )
141186
142187
143188def eval_generic_makeboxes (self , expr , f , evaluation ):
144189 """MakeBoxes[expr_,
145- f:TraditionalForm|StandardForm|OutputForm|InputForm|FullForm ]"""
190+ f:TraditionalForm|StandardForm|OutputForm|InputForm]"""
146191 from mathics .builtin .box .layout import RowBox
147192
148193 if isinstance (expr , BoxElementMixin ):
@@ -174,7 +219,6 @@ def eval_generic_makeboxes(self, expr, f, evaluation):
174219 if f_name in (
175220 "System`InputForm" ,
176221 "System`OutputForm" ,
177- "System`FullForm" ,
178222 ):
179223 sep = ", "
180224 else :
@@ -210,6 +254,8 @@ def eval_makeboxes(
210254 Basically: MakeBoxes[expr // form]
211255 """
212256 # This is going to be reimplemented.
257+ if form is SymbolFullForm :
258+ return eval_makeboxes_fullform (expr , evaluation )
213259 return Expression (SymbolMakeBoxes , expr , form ).evaluate (evaluation )
214260
215261
@@ -220,14 +266,13 @@ def format_element(
220266 Applies formats associated to the expression, and then calls Makeboxes
221267 """
222268 evaluation .is_boxing = True
223- expr = do_format (element , evaluation , form )
224- if expr is None :
269+ formatted_expr = do_format (element , evaluation , form )
270+ if formatted_expr is None :
225271 return None
226- result = Expression (SymbolMakeBoxes , expr , form )
227- result_box = result .evaluate (evaluation )
272+ result_box = eval_makeboxes (formatted_expr , evaluation , form )
228273 if isinstance (result_box , String ):
229274 return result_box
230275 if isinstance (result_box , BoxElementMixin ):
231276 return result_box
232277 else :
233- return format_element (element , evaluation , SymbolFullForm , ** kwargs )
278+ return eval_makeboxes_fullform (element , evaluation )
0 commit comments