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

using rules instead of atom_to_boxes #698

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
30 changes: 30 additions & 0 deletions mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from mathics.builtin.lists import _IterationFunction
from mathics.builtin.scoping import dynamic_scoping
from mathics.core.atoms import (
SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM,
Complex,
Integer,
Integer0,
Expand Down Expand Up @@ -73,6 +74,7 @@
SymbolTable,
SymbolUndefined,
)
from mathics.eval.makeboxes import _boxed_string, eval_makeboxes
from mathics.eval.nevaluator import eval_N


Expand Down Expand Up @@ -492,6 +494,14 @@ def eval(self, r, i, evaluation):
r, i = from_sympy(r), from_sympy(i)
return Complex(r, i)

def eval_makeboxes(self, c, form, evaluation):
"""MakeBoxes[c_Complex, form_]"""
from mathics.eval.makeboxes import do_format_complex

# This function can be moved to this module, or even
# added here inline.
return eval_makeboxes(do_format_complex(c, evaluation, form), evaluation, form)


class ConditionalExpression(Builtin):
"""
Expand Down Expand Up @@ -771,6 +781,13 @@ def eval(self, number, evaluation):

return from_sympy(sympy.im(number.to_sympy().expand(complex=True)))

def eval_makeboxes(self, n, form, evaluation) -> "String":
"""MakeBoxes[n_Integer, form_]"""

if form in SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM:
return _boxed_string(str(n.value), number_as_text=True)
return String(str(n._value))


class Integer_(Builtin):
"""
Expand Down Expand Up @@ -1093,6 +1110,15 @@ def eval(self, n: Integer, m: Integer, evaluation):
else:
return Rational(n.value, m.value)

def eval_makeboxes(self, r, form, evaluation):
"""MakeBoxes[r_Rational, form_]"""
from mathics.eval.makeboxes import do_format_rational

# This function can be moved to this module, or even
# added here inline.
result = do_format_rational(r, evaluation, form)
return eval_makeboxes(result, evaluation, form)


class Re(SympyFunction):
"""
Expand Down Expand Up @@ -1210,6 +1236,10 @@ class Real_(Builtin):
summary_text = "head for real numbers"
name = "Real"

def eval_makeboxes(self, r, form, evaluation):
"""MakeBoxes[r_Real, form_]"""
return r.make_boxes(form.name)


class RealNumberQ(Test):
"""
Expand Down
19 changes: 18 additions & 1 deletion mathics/builtin/atomic/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
from mathics_scanner import TranslateError

from mathics.builtin.base import Builtin, Predefined, PrefixOperator, Test
from mathics.core.atoms import Integer, Integer0, Integer1, String
from mathics.core.atoms import (
SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM,
Integer,
Integer0,
Integer1,
String,
)
from mathics.core.attributes import A_LISTABLE, A_PROTECTED
from mathics.core.convert.expression import to_mathics_list
from mathics.core.convert.python import from_bool
Expand Down Expand Up @@ -841,6 +847,17 @@ class String_(Builtin):
name = "String"
summary_text = "head for strings"

def apply_makeboxes(self, s, form, evaluation):
"""MakeBoxes[s_String,
form:(InputForm|OutputForm|StandardForm|TraditionalForm|FullForm)]"""
from mathics.eval.makeboxes import _boxed_string

inner = str(s.value)
if form in SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM:
inner = '"' + inner.replace("\\", "\\\\") + '"'
return _boxed_string(inner, **{"System`ShowStringCharacters": SymbolTrue})
return String('"' + inner + '"')


class StringContainsQ(Builtin):
"""
Expand Down
5 changes: 5 additions & 0 deletions mathics/builtin/atomic/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ def eval(self, string, evaluation):
else:
evaluation.message("Symbol", "symname", string)

def eval_symb_makeboxes(self, s, form, evaluation) -> "String":
"""MakeBoxes[s_Symbol,
form:(InputForm|OutputForm|StandardForm|TraditionalForm|FullForm)]"""
return String(evaluation.definitions.shorten_name(s.name))


class SymbolName(Builtin):
"""
Expand Down
6 changes: 3 additions & 3 deletions mathics/builtin/box/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from mathics.core.list import ListExpression
from mathics.core.symbols import Symbol, SymbolTrue
from mathics.core.systemsymbols import SymbolAutomatic, SymbolTraditionalForm
from mathics.eval.makeboxes import format_element
from mathics.eval.makeboxes import eval_makeboxes, format_element

SymbolRegularPolygonBox = Symbol("RegularPolygonBox")
SymbolStandardForm = Symbol("StandardForm")
Expand Down Expand Up @@ -994,8 +994,8 @@ def init(
self.opos = opos

if isinstance(self.content, String):
self.content = self.content.atom_to_boxes(
SymbolStandardForm, evaluation=self.graphics.evaluation
self.content = eval_makeboxes(
self.content, self.graphics.evaluation, SymbolStandardForm
)
self.content_text = self.content.boxes_to_text(
evaluation=self.graphics.evaluation
Expand Down
27 changes: 15 additions & 12 deletions mathics/builtin/box/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,21 @@ def to_boxes(x, evaluation: Evaluation, options={}) -> BoxElementMixin:
if isinstance(x, BoxElementMixin):
return x
if isinstance(x, Atom):
x = x.atom_to_boxes(SymbolStandardForm, evaluation)
return to_boxes(x, evaluation, options)
if isinstance(x, Expression):
if x.has_form("MakeBoxes", None):
x_boxed = x.evaluate(evaluation)
else:
x_boxed = eval_makeboxes(x, evaluation)
if isinstance(x_boxed, BoxElementMixin):
return x_boxed
if isinstance(x_boxed, Atom):
return to_boxes(x_boxed, evaluation, options)
raise eval_makeboxes(Expression(SymbolFullForm, x), evaluation)
try:
x = x.atom_to_boxes(SymbolStandardForm, evaluation)
return to_boxes(x, evaluation, options)
except NotImplementedError:
pass

if x.has_form("MakeBoxes", None):
x_boxed = x.evaluate(evaluation)
else:
x_boxed = eval_makeboxes(x, evaluation)
if isinstance(x_boxed, BoxElementMixin):
return x_boxed
if isinstance(x_boxed, Atom):
return to_boxes(x_boxed, evaluation, options)
return eval_makeboxes(Expression(SymbolFullForm, x), evaluation)


class BoxData(Builtin):
Expand Down
1 change: 1 addition & 0 deletions mathics/builtin/drawing/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@

import numpy
import PIL
import PIL.Image
import PIL.ImageEnhance
import PIL.ImageFilter
import PIL.ImageOps
Expand Down
5 changes: 4 additions & 1 deletion mathics/builtin/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,10 @@ def eval_general(self, expr, f, evaluation):
if isinstance(expr, BoxElementMixin):
expr = expr.to_expression()
if isinstance(expr, Atom):
return expr.atom_to_boxes(f, evaluation)
try:
return expr.atom_to_boxes(f, evaluation)
except NotImplementedError:
return String(f"{str(expr)} cannot be boxed in form {f}")
else:
head = expr.head
elements = expr.elements
Expand Down
32 changes: 0 additions & 32 deletions mathics/core/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,19 +224,9 @@ def __ne__(self, other) -> bool:
def abs(self) -> "Integer":
return -self if self < Integer0 else self

def atom_to_boxes(self, f, evaluation):
return self.make_boxes(f.get_name())

def default_format(self, evaluation, form) -> str:
return str(self._value)

def make_boxes(self, form) -> "String":
from mathics.eval.makeboxes import _boxed_string

if form in ("System`InputForm", "System`FullForm"):
return _boxed_string(str(self.value), number_as_text=True)
return String(str(self._value))

def to_sympy(self, **kwargs):
return sympy.Integer(self._value)

Expand Down Expand Up @@ -341,9 +331,6 @@ def __ne__(self, other) -> bool:
# Real is a total order
return not (self == other)

def atom_to_boxes(self, f, evaluation):
return self.make_boxes(f.get_name())

def is_nan(self, d=None) -> bool:
return isinstance(self.value, sympy.core.numbers.NaN)

Expand Down Expand Up @@ -715,11 +702,6 @@ def __hash__(self):
def __str__(self) -> str:
return str(self.to_sympy())

def atom_to_boxes(self, f, evaluation):
from mathics.eval.makeboxes import format_element

return format_element(self, evaluation, f)

def to_sympy(self, **kwargs):
return self.real.to_sympy() + sympy.I * self.imag.to_sympy()

Expand Down Expand Up @@ -863,11 +845,6 @@ def __new__(cls, numerator, denominator=1) -> "Rational":
def __hash__(self):
return self.hash

def atom_to_boxes(self, f, evaluation):
from mathics.eval.makeboxes import format_element

return format_element(self, evaluation, f)

def to_sympy(self, **kwargs):
return self.value

Expand Down Expand Up @@ -945,15 +922,6 @@ def __hash__(self):
def __str__(self) -> str:
return '"%s"' % self.value

def atom_to_boxes(self, f, evaluation):
from mathics.eval.makeboxes import _boxed_string

inner = str(self.value)
if f in SYSTEM_SYMBOLS_INPUT_OR_FULL_FORM:
inner = '"' + inner.replace("\\", "\\\\") + '"'
return _boxed_string(inner, **{"System`ShowStringCharacters": SymbolTrue})
return String('"' + inner + '"')

def do_copy(self) -> "String":
return String(self.value)

Expand Down
5 changes: 0 additions & 5 deletions mathics/core/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,6 @@ def __ne__(self, other) -> bool:
def __str__(self) -> str:
return self.name

def atom_to_boxes(self, f, evaluation) -> "String":
from mathics.core.atoms import String

return String(evaluation.definitions.shorten_name(self.name))

def default_format(self, evaluation, form) -> str:
return self.name

Expand Down
1 change: 1 addition & 0 deletions mathics/eval/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import numpy
import PIL
import PIL.Image

from mathics.builtin.base import String
from mathics.core.atoms import Rational
Expand Down
5 changes: 2 additions & 3 deletions mathics/eval/makeboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _boxed_string(string: str, **options):
return StyleBox(String(string), **options)


def eval_makeboxes(self, expr, evaluation, f=SymbolStandardForm):
def eval_makeboxes(expr, evaluation, f=SymbolStandardForm):
"""
This function takes the definitions prodived by the evaluation
object, and produces a boxed form for expr.
Expand All @@ -67,8 +67,7 @@ def format_element(
Applies formats associated to the expression, and then calls Makeboxes
"""
expr = do_format(element, evaluation, form)
result = Expression(SymbolMakeBoxes, expr, form)
result_box = result.evaluate(evaluation)
result_box = eval_makeboxes(expr, evaluation, form)
if isinstance(result_box, String):
return result_box
if isinstance(result_box, BoxElementMixin):
Expand Down