@@ -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+
646670def 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
774798class _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 )
0 commit comments