Skip to content

Commit a728701

Browse files
mmaterarocky
authored andcommitted
more on modularize assignment. assign_elementary->assign
1 parent e92da0f commit a728701

File tree

4 files changed

+52
-44
lines changed

4 files changed

+52
-44
lines changed

CHANGES.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. contents::
1+
.. contents::
22

33
CHANGES
44
=======
@@ -41,6 +41,8 @@ Internals
4141
#. Operator name to unicode or ASCII comes from Mathics scanner character tables.
4242
#. ``eval*`` methods in `Builtin` classes are considerer as synonyms of ``apply*`` methods.
4343
#. Modularize and improve the way in which `Builtin` classes are selected to have an associated `Definition`.
44+
#. `_SetOperator.assign_elementary` was renamed as `_SetOperator.assign`. All the special cases are not handled by the `_SetOperator.special_cases` dict.
45+
4446

4547

4648
Bugs

mathics/builtin/assignments/assignment.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def apply(self, f, lhs, rhs, evaluation):
225225
return
226226

227227
rhs = rhs.evaluate(evaluation)
228-
self.assign_elementary(lhs, rhs, evaluation, tags=[name])
228+
self.assign(lhs, rhs, evaluation, tags=[name])
229229
return rhs
230230

231231

@@ -250,7 +250,7 @@ def apply(self, f, lhs, rhs, evaluation):
250250
evaluation.message(self.get_name(), "sym", f, 1)
251251
return
252252

253-
if self.assign_elementary(lhs, rhs, evaluation, tags=[name]):
253+
if self.assign(lhs, rhs, evaluation, tags=[name]):
254254
return SymbolNull
255255
else:
256256
return SymbolFailed

mathics/builtin/assignments/internals.py

+45-39
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def repl_pattern_by_symbol(expr):
144144
return expr
145145

146146

147-
# Here are the functions related to assign_elementary
147+
# Here are the functions related to assign
148148

149149
# Auxiliary routines
150150

@@ -232,7 +232,7 @@ def unroll_conditions(lhs) -> Tuple[BaseElement, Optional[Expression]]:
232232
return lhs, condition
233233

234234

235-
# Here starts the functions that implement `assign_elementary` for different
235+
# Here starts the functions that implement `assign` for different
236236
# kind of expressions. Maybe they should be put in a separated module, or
237237
# maybe they should be member functions of _SetOperator.
238238

@@ -643,6 +643,30 @@ def process_assign_makeboxes(self, lhs, rhs, evaluation, tags, upset):
643643
return True
644644

645645

646+
def process_assing_part(self, lhs, rhs, evaluation, tags, upset):
647+
"""
648+
Special case `A[[i,j,...]]=....`
649+
"""
650+
defs = evaluation.definitions
651+
if len(lhs.elements) < 1:
652+
evaluation.message(self.get_name(), "setp", lhs)
653+
return False
654+
symbol = lhs.elements[0]
655+
name = symbol.get_name()
656+
if not name:
657+
evaluation.message(self.get_name(), "setps", symbol)
658+
return False
659+
if is_protected(name, defs):
660+
evaluation.message(self.get_name(), "wrsym", symbol)
661+
return False
662+
rule = defs.get_ownvalue(name)
663+
if rule is None:
664+
evaluation.message(self.get_name(), "noval", symbol)
665+
return False
666+
indices = lhs.elements[1:]
667+
return walk_parts([rule.replace], indices, evaluation, rhs)
668+
669+
646670
def process_assign_messagename(self, lhs, rhs, evaluation, tags, upset):
647671
lhs, condition = unroll_conditions(lhs)
648672
lhs, rhs = unroll_patterns(lhs, rhs, evaluation)
@@ -772,6 +796,23 @@ def process_tags_and_upset_allow_custom(tags, upset, self, lhs, evaluation):
772796

773797

774798
class _SetOperator:
799+
"""
800+
This is the base class for assignment Builtin operators.
801+
802+
Special cases are determined by the head of the expression. Then
803+
they are processed by specific routines, which are poke from
804+
the `special_cases` dict.
805+
"""
806+
807+
# There are several idea about how to reimplement this. One possibility
808+
# would be to use a Symbol instead of a name as the key of this dictionary.
809+
#
810+
# Another possibility would be to move the specific function to be a
811+
# class method associated to the corresponding builtins. In any case,
812+
# the present implementation should be clear enough to understand the
813+
# logic.
814+
#
815+
775816
special_cases = {
776817
"System`$Context": process_assign_context,
777818
"System`$ContextPath": process_assign_context_path,
@@ -790,11 +831,12 @@ class _SetOperator:
790831
"System`NumericQ": process_assign_numericq,
791832
"System`Options": process_assign_options,
792833
"System`OwnValues": process_assign_definition_values,
834+
"System`Part": process_assing_part,
793835
"System`SubValues": process_assign_definition_values,
794836
"System`UpValues": process_assign_definition_values,
795837
}
796838

797-
def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
839+
def assign(self, lhs, rhs, evaluation, tags=None, upset=False):
798840
if isinstance(lhs, Symbol):
799841
name = lhs.name
800842
else:
@@ -810,39 +852,3 @@ def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
810852
return assign_store_rules_by_tag(self, lhs, rhs, evaluation, tags, upset)
811853
except AssignmentException:
812854
return False
813-
814-
def assign(self, lhs, rhs, evaluation):
815-
# lhs._format_cache = None
816-
defs = evaluation.definitions
817-
if False and lhs.get_head_name() == "System`List":
818-
if not (rhs.get_head_name() == "System`List") or len(lhs.elements) != len(
819-
rhs.elements
820-
): # nopep8
821-
evaluation.message(self.get_name(), "shape", lhs, rhs)
822-
return False
823-
else:
824-
result = True
825-
for left, right in zip(lhs.elements, rhs.elements):
826-
if not self.assign(left, right, evaluation):
827-
result = False
828-
return result
829-
elif lhs.get_head_name() == "System`Part":
830-
if len(lhs.elements) < 1:
831-
evaluation.message(self.get_name(), "setp", lhs)
832-
return False
833-
symbol = lhs.elements[0]
834-
name = symbol.get_name()
835-
if not name:
836-
evaluation.message(self.get_name(), "setps", symbol)
837-
return False
838-
if is_protected(name, defs):
839-
evaluation.message(self.get_name(), "wrsym", symbol)
840-
return False
841-
rule = defs.get_ownvalue(name)
842-
if rule is None:
843-
evaluation.message(self.get_name(), "noval", symbol)
844-
return False
845-
indices = lhs.elements[1:]
846-
return walk_parts([rule.replace], indices, evaluation, rhs)
847-
else:
848-
return self.assign_elementary(lhs, rhs, evaluation)

mathics/builtin/assignments/upvalues.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class UpSet(BinaryOperator, _SetOperator):
5858
def apply(self, lhs, rhs, evaluation):
5959
"lhs_ ^= rhs_"
6060

61-
self.assign_elementary(lhs, rhs, evaluation, upset=True)
61+
self.assign(lhs, rhs, evaluation, upset=True)
6262
return rhs
6363

6464

@@ -92,7 +92,7 @@ class UpSetDelayed(UpSet):
9292
def apply(self, lhs, rhs, evaluation):
9393
"lhs_ ^:= rhs_"
9494

95-
if self.assign_elementary(lhs, rhs, evaluation, upset=True):
95+
if self.assign(lhs, rhs, evaluation, upset=True):
9696
return SymbolNull
9797
else:
9898
return SymbolFailed

0 commit comments

Comments
 (0)