Skip to content
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
4 changes: 3 additions & 1 deletion mathics/builtin/compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ class CompiledCodeBox(BoxConstruct):
"""
Used internally by <i>CompileCode[]</i>.
"""

def output_cost(self):
return 12

def boxes_to_text(self, leaves=None, **options):
if leaves is None:
leaves = self._leaves
Expand Down
53 changes: 53 additions & 0 deletions mathics/builtin/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,58 @@ class Sequence(Builtin):
"""




class OutputSizeLimit(Predefined):
"""
<dl>
<dt>'$OutputSizeLimit'
<dd>specifies the maximum amount of data output that gets
displayed before the output gets truncated. The amount of
output is measured as the number of bytes of MathML XML
that has been generated to represent the output data.

To set no limit on output size, use $OutputSizeLimit = Infinity.
</dl>

>> $OutputSizeLimit = 50;

>> Table[i, {i, 1, 100}]
: Parts of this output were omitted (see <<71>>). To generate the whole output, please set $OutputSizeLimit = Infinity.
= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, <<71>>, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}

#> Take[Range[1000], 1001]
: Cannot take positions 1 through 1001 in {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, <<976>>, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000}.
: Parts of this output were omitted (see <<976>>). To generate the whole output, please set $OutputSizeLimit = Infinity.
= Take[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, <<976>>, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000}, 1001]

#> {}
= {}

#> $OutputSizeLimit = 100;

#> Table[Graphics[Table[Circle[],{10}]], {5}]
= {-Graphics-, -Graphics-, -Graphics-, -Graphics-, -Graphics-}

#> Quiet[ImageAvailable = SameQ[Head[Image[{{0, 1}, {1, 0}}] // ToBoxes], ImageBox]];
#> If[ImageAvailable, Table[Image[{{1, 0}, {0, 1}}], {5}], {"-Image-", "-Image-", "-Image-", "-Image-", "-Image-"}]
= {-Image-, -Image-, -Image-, -Image-, -Image-}

#> $OutputSizeLimit = Infinity;

"""
attributes = ("Unprotected", )
name = '$OutputSizeLimit'
value = 1000

rules = {
'$OutputSizeLimit': str(value),
}

def evaluate(self, evaluation):
return Integer(self.value)


class Quit(Builtin):
"""
<dl>
Expand Down Expand Up @@ -345,3 +397,4 @@ def apply(self, evaluation, n):
if isinstance(n, Integer):
exitcode = n.get_int_value()
raise SystemExit(exitcode)

134 changes: 80 additions & 54 deletions mathics/builtin/inout.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import re
import mpmath
from itertools import chain

import typing
from typing import Any
Expand Down Expand Up @@ -37,8 +38,10 @@
PrecisionReal,
SymbolList,
SymbolMakeBoxes,
SymbolRule
SymbolRule,
Omitted,
)

from mathics.core.numbers import (
dps,
convert_base,
Expand Down Expand Up @@ -130,11 +133,14 @@ def parenthesize(precedence, leaf, leaf_boxes, when_equal):
return leaf_boxes


def make_boxes_infix(leaves, ops, precedence, grouping, form):
result = []
for index, leaf in enumerate(leaves):
if index > 0:
result.append(ops[index - 1])
def make_boxes_infix(leaves, ops, precedence, grouping, form, evaluation):
def materialize(prefix, inner, suffix):
return Expression('RowBox', Expression('List', *list(chain(prefix, inner, suffix))))

def make_leaf(index):
leaf = leaves[index]
box = Expression('MakeBoxes', leaf, form)

parenthesized = False
if grouping == "System`NonAssociative":
parenthesized = True
Expand All @@ -143,11 +149,12 @@ def make_boxes_infix(leaves, ops, precedence, grouping, form):
elif grouping == "System`Right" and index == 0:
parenthesized = True

leaf_boxes = MakeBoxes(leaf, form)
leaf = parenthesize(precedence, leaf, leaf_boxes, parenthesized)
return parenthesize(precedence, leaf, box, parenthesized)

result.append(leaf)
return Expression("RowBox", Expression(SymbolList, *result))
return evaluation.make_boxes(
None, make_leaf, len(leaves),
None, None, ops,
materialize, form)


def real_to_s_exp(expr, n):
Expand Down Expand Up @@ -520,29 +527,24 @@ def apply_general(self, expr, f, evaluation):

# Parenthesize infix operators at the head of expressions,
# like (a + b)[x], but not f[a] in f[a][b].
#
head_boxes = parenthesize(670, head, MakeBoxes(head, f), False)
result = [head_boxes, String(left)]

if len(leaves) > 1:
row = []
if f_name in (
"System`InputForm",
"System`OutputForm",
"System`FullForm",
):
sep = ", "
else:
sep = ","
for index, leaf in enumerate(leaves):
if index > 0:
row.append(String(sep))
row.append(MakeBoxes(leaf, f))
result.append(RowBox(Expression(SymbolList, *row)))
elif len(leaves) == 1:
result.append(MakeBoxes(leaves[0], f))
result.append(String(right))
return RowBox(Expression(SymbolList, *result))
prefix = parenthesize(670, head, Expression('MakeBoxes', head, f), False)

def make_leaf(i):
return Expression('MakeBoxes', leaves[i], f)

if f_name in ('System`InputForm', 'System`OutputForm',
'System`FullForm'):
sep = ', '
else:
sep = ','

def materialize(prefix, inner, suffix):
if len(inner) > 1:
inner = [Expression('RowBox', Expression('List', *inner))]
return Expression('RowBox', Expression('List', *list(chain(prefix, inner, suffix))))

return evaluation.make_boxes(
prefix, make_leaf, len(leaves), String(left), String(right), String(sep), materialize, f)

def _apply_atom(self, x, f, evaluation):
"""MakeBoxes[x_?AtomQ,
Expand Down Expand Up @@ -609,7 +611,7 @@ def get_op(op):
ops = [get_op(op) for op in h.leaves]
else:
ops = [get_op(h)] * (len(leaves) - 1)
return make_boxes_infix(leaves, ops, precedence, grouping, f)
return make_boxes_infix(leaves, ops, precedence, grouping, f, evaluation)
elif len(leaves) == 1:
return MakeBoxes(leaves[0], f)
else:
Expand Down Expand Up @@ -942,22 +944,37 @@ class Grid(Builtin):
options = GridBox.options

def apply_makeboxes(self, array, f, evaluation, options) -> Expression:
"""MakeBoxes[Grid[array_?MatrixQ, OptionsPattern[Grid]],
f:StandardForm|TraditionalForm|OutputForm]"""
return GridBox(
Expression(
"List",
*(
Expression(
"List",
*(Expression(SymbolMakeBoxes, item, f) for item in row.leaves)
)
for row in array.leaves
)
),
*options_to_rules(options)
)

'''MakeBoxes[Grid[array_?MatrixQ, OptionsPattern[Grid]],
f:StandardForm|TraditionalForm|OutputForm]'''

lengths = [len(row._leaves) for row in array._leaves]
n_leaves = sum(lengths)

#def materialize(boxes):
def materialize(prefix, inner, suffix):
boxes = inner
if len(boxes) == n_leaves:
rows = []
i = 0
for l in lengths:
rows.append(Expression('List', *boxes[i:i + l]))
i += l
return Expression(
'GridBox',
Expression('List', *rows),
*options_to_rules(options))
else: # too long
return Omitted('<<%d>>' % n_leaves)

flat = [item for row in array.leaves for item in row.leaves]

def make_leaf(i):
return Expression('MakeBoxes', flat[i], f)

return evaluation.make_boxes(
None, make_leaf, n_leaves,
None, None, None,
materialize, f)

# return Expression('GridBox',Expression('List', *(Expression('List', *(Expression('MakeBoxes', item, f) for item in row.leaves)) for row in array.leaves)), *options_to_rules(options))

Expand Down Expand Up @@ -1128,10 +1145,11 @@ class Subscript(Builtin):
def apply_makeboxes(self, x, y, f, evaluation) -> Expression:
"MakeBoxes[Subscript[x_, y__], f:StandardForm|TraditionalForm]"

y = y.get_sequence()
return Expression(
"SubscriptBox", Expression(SymbolMakeBoxes, x, f), *list_boxes(y, f)
)
def materialize(prefix, inner, suffix):
return Expression('SubscriptBox', *list(chain(prefix, inner, suffix)))

return list_boxes(
Expression('MakeBoxes', x, f), y.get_sequence(), materialize, f, evaluation)


class SubscriptBox(Builtin):
Expand Down Expand Up @@ -1308,6 +1326,12 @@ def apply_makeboxes(self, s, args, f, evaluation):
"""MakeBoxes[StringForm[s_String, args___],
f:StandardForm|TraditionalForm|OutputForm]"""

# StringForm does not call evaluation.make_boxes
# since we use it for messages and we never want
# to omit parts of the message. args are subject
# to MakeBoxes (see below) and thus can get parts
# omitted.

s = s.value
args = args.get_sequence()
result = []
Expand Down Expand Up @@ -1960,6 +1984,8 @@ class General(Builtin):
"syntax": "`1`",
"invalidargs": "Invalid arguments.",
"notboxes": "`1` is not a valid box structure.",
"omit": "Parts of this output were omitted (see `1`). " +
"To generate the whole output, please set $OutputSizeLimit = Infinity.",
"pyimport": '`1`[] is not available. Your Python installation misses the "`2`" module.',
}

Expand Down
61 changes: 36 additions & 25 deletions mathics/builtin/lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,13 @@ def apply_makeboxes(self, items, f, evaluation):
f:StandardForm|TraditionalForm|OutputForm|InputForm]"""

items = items.get_sequence()
return Expression(
"RowBox", Expression(SymbolList, *list_boxes(items, f, "{", "}"))
)

def materialize(prefix, inner, suffix):
return Expression(
"RowBox", Expression("List", *list(chain(prefix, inner, suffix)))
)

return list_boxes(None, items, materialize, f, evaluation, "{", "}")


class ListQ(Test):
Expand Down Expand Up @@ -317,25 +321,25 @@ def test(self, expr):
return expr.get_head_name() != "System`List"


def list_boxes(items, f, open=None, close=None):
result = [Expression(SymbolMakeBoxes, item, f) for item in items]
if f.get_name() in ("System`OutputForm", "System`InputForm"):
def list_boxes(prefix, items, materialize, f, evaluation, open=None, close=None):
if open is not None:
open = String(open)
if close is not None:
close = String(close)

if f in ("System`OutputForm", "System`InputForm"):
sep = ", "
else:
sep = ","
result = riffle(result, String(sep))
if len(items) > 1:
result = Expression("RowBox", Expression(SymbolList, *result))
elif items:
result = result[0]
if result:
result = [result]
else:
result = []
if open is not None and close is not None:
return [String(open)] + result + [String(close)]
else:
return result
sep = ", " # in the original, this was ",", but
# this broke several doctests...
# Let's restore it when we finish

def make_leaf(i):
return Expression("MakeBoxes", items[i], f)

return evaluation.make_boxes(
prefix, make_leaf, len(items), open, close, sep, materialize, f
)


class Length(Builtin):
Expand Down Expand Up @@ -1105,14 +1109,20 @@ def apply_makeboxes(self, list, i, f, evaluation):
f:StandardForm|TraditionalForm|OutputForm|InputForm]"""

i = i.get_sequence()

list = Expression(SymbolMakeBoxes, list, f)

if f.get_name() in ("System`OutputForm", "System`InputForm"):
open, close = "[[", "]]"
else:
open, close = "\u301a", "\u301b"
indices = list_boxes(i, f, open, close)
result = Expression("RowBox", Expression(SymbolList, list, *indices))
return result

def materialize(prefix, inner, suffix):
return Expression(
"RowBox", Expression("List", *list(chain(prefix, inner, suffix)))
)

return list_boxes(list, i, materialize, f, evaluation, open, close)

def apply(self, list, i, evaluation):
"Part[list_, i___]"
Expand Down Expand Up @@ -5898,14 +5908,15 @@ def validate(exprs):
rules = rules.get_sequence()
if self.error_idx == 0 and validate(rules) is True:
expr = Expression(
"RowBox", Expression(SymbolList, *list_boxes(rules, f, "<|", "|>"))
"RowBox",
Expression(SymbolList, *list_boxes(rules, f, "<|", "|>", evaluation)),
)
else:
self.error_idx += 1
symbol = Expression(SymbolMakeBoxes, SymbolAssociation, f)
expr = Expression(
"RowBox",
Expression(SymbolList, symbol, *list_boxes(rules, f, "[", "]")),
Expression(SymbolList, symbol, *list_boxes(rules, f, "[", "]", evaluation)),
)

expr = expr.evaluate(evaluation)
Expand Down
Loading