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

An example of defining MakeBoxes in Mathics code #590

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
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
24 changes: 24 additions & 0 deletions mathics/autoload/forms/StandardForm.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(* This implements StandardForm boxing rules in Mathics *)


Begin["System`"]

(******************************************************************************************)
(* Common Boxing routines that are used by many forms. FIXME: place this in another file. *)
(******************************************************************************************)

(* Change RadBox to RadicalBox. We use RadBox to make it clear that
the below code was a read-in from a file and not some pre-existing
code. *)
Attributes[CubeRootRadicalBox] = HoldAll;
Attributes[RadBox] = HoldAll;
CubeRootRadicalBox[expr_, form_]:= RadBox[MakeBoxes[expr, form], 3];

(******************************************************************************************)
(* StandardForm Boxing Rules *)
(******************************************************************************************)

MakeBoxes[CubeRoot[expr_], StandardForm] := CubeRootRadicalBox[expr, StandardForm];
(*All the other StandardForm boxing routines... *)

End[]
3 changes: 0 additions & 3 deletions mathics/builtin/arithfns/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ class CubeRoot(Builtin):
rules = {
"CubeRoot[n_?NumberQ]": "If[n > 0, Power[n, Divide[1, 3]], Times[-1, Power[Times[-1, n], Divide[1, 3]]]]",
"CubeRoot[n_]": "Power[n, Divide[1, 3]]",
"MakeBoxes[CubeRoot[x_], f:StandardForm|TraditionalForm]": (
"RadicalBox[MakeBoxes[x, f], 3]"
),
}

summary_text = "cubed root"
Expand Down
1 change: 0 additions & 1 deletion mathics/builtin/assignments/clear.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ class Remove(Builtin):
"""

attributes = A_HOLD_ALL | A_LOCKED | A_PROTECTED

precedence = 670
summary_text = "remove the definition of a symbol"

Expand Down
45 changes: 32 additions & 13 deletions mathics/builtin/assignments/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,24 @@ def process_assign_format(self, lhs, rhs, evaluation, tags, upset):
return count > 0


def process_assign_makeboxes(self, lhs, rhs, evaluation, tags, upset):
# FIXME: the below is a big hack.
# Currently MakeBoxes boxing is implemented as a bunch of rules.
# See mathics.builtin.base contribute().
# I think we want to change this so it works like normal SetDelayed
# That is:
# MakeBoxes[CubeRoot, StandardForm] := RadicalBox[3, StandardForm]
# rather than:
# MakeBoxes[CubeRoot, StandardForm] -> RadicalBox[3, StandardForm]

makeboxes_rule = Rule(lhs, rhs, system=False)
definitions = evaluation.definitions
definitions.add_rule("System`MakeBoxes", makeboxes_rule, "down")
# makeboxes_defs = evaluation.definitions.builtin["System`MakeBoxes"]
# makeboxes_defs.add_rule(makeboxes_rule)
return True


def process_assign_messagename(self, lhs, rhs, evaluation, tags, upset):
lhs, condition = unroll_conditions(lhs)
lhs, rhs = unroll_patterns(lhs, rhs, evaluation)
Expand Down Expand Up @@ -685,23 +703,24 @@ def process_tags_and_upset_allow_custom(tags, upset, self, lhs, evaluation):

class _SetOperator:
special_cases = {
"System`OwnValues": process_assign_definition_values,
"System`DownValues": process_assign_definition_values,
"System`SubValues": process_assign_definition_values,
"System`UpValues": process_assign_definition_values,
"System`NValues": process_assign_definition_values,
"System`DefaultValues": process_assign_definition_values,
"System`Messages": process_assign_definition_values,
"System`Attributes": process_assign_attributes,
"System`Options": process_assign_options,
"System`$RandomState": process_assign_random_state,
"System`$Context": process_assign_context,
"System`$ContextPath": process_assign_context_path,
"System`N": process_assign_n,
"System`NumericQ": process_assign_numericq,
"System`MessageName": process_assign_messagename,
"System`$RandomState": process_assign_random_state,
"System`Attributes": process_assign_attributes,
"System`Default": process_assign_default,
"System`DefaultValues": process_assign_definition_values,
"System`DownValues": process_assign_definition_values,
"System`Format": process_assign_format,
"System`MakeBoxes": process_assign_makeboxes,
"System`MessageName": process_assign_messagename,
"System`Messages": process_assign_definition_values,
"System`N": process_assign_n,
"System`NValues": process_assign_definition_values,
"System`NumericQ": process_assign_numericq,
"System`Options": process_assign_options,
"System`OwnValues": process_assign_definition_values,
"System`SubValues": process_assign_definition_values,
"System`UpValues": process_assign_definition_values,
}

def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
Expand Down
15 changes: 8 additions & 7 deletions mathics/builtin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,16 @@ def check_options(options_to_check, evaluation):
rules.append(
BuiltinRule(name, pattern, function, check_options, system=True)
)
for pattern, replace in self.rules.items():
if not isinstance(pattern, BaseElement):
pattern = pattern % {"name": name}
pattern = parse_builtin_rule(pattern, definition_class)
replace = replace % {"name": name}
# FIXME: Should system=True be system=not is_pymodule ?
rules.append(Rule(pattern, parse_builtin_rule(replace), system=True))
for pattern_str, replace_str in self.rules.items():
pattern_str = pattern_str % {"name": name}
pattern = parse_builtin_rule(pattern_str, definition_class)
replace_str = replace_str % {"name": name}
rules.append(
Rule(pattern, parse_builtin_rule(replace_str), system=not is_pymodule)
)

box_rules = []
# FIXME: Why a special case for System`MakeBoxes? Remove this
if name != "System`MakeBoxes":
new_rules = []
for rule in rules:
Expand Down
9 changes: 8 additions & 1 deletion mathics/core/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,14 @@ def __init__(
if name.startswith("Global`"):
raise ValueError("autoload defined %s." % name)

self.builtin.update(self.user)
# The idea here is that all the symbols loaded in
# autoload become converted in builtin.
# For some reason, if we do not do this here,
# `Export` and `Import` fails.
# TODO: investigate why.
for name in self.user:
self.builtin[name] = self.get_definition(name)

self.user = {}
self.clear_cache()

Expand Down