1010
1111
1212from mathics .builtin .base import Predefined , Builtin
13- from mathics .core .expression import Symbol , Expression
13+ from mathics .builtin .evaluation import Sequence
14+ from mathics .core .expression import Expression , Symbol , String
1415from mathics .builtin .assignment import get_symbol_list
1516
1617
@@ -140,8 +141,11 @@ def apply(self, symbols, attributes, evaluation):
140141class Protect (Builtin ):
141142 """
142143 <dl>
143- <dt>'Protect'[$s1$, $s2$, ...]
144- <dd>sets the attribute 'Protected' for the symbols $si$.
144+ <dt>'Protect'[$s1$, $s2$, ...]
145+ <dd>sets the attribute 'Protected' for the symbols $si$.
146+
147+ <dt>'Protect'[$str1$, $str2$, ...]
148+ <dd>protects all symbols whose names textually match $stri$.
145149 </dl>
146150
147151 >> A = {1, 2, 3};
@@ -153,11 +157,46 @@ class Protect(Builtin):
153157 """
154158
155159 attributes = ('HoldAll' ,)
156-
157- rules = {
158- 'Protect[symbols__]' : 'SetAttributes[{symbols}, Protected]' ,
160+ messages = {
161+ 'ssym' : "`1` is not a symbol or a string." ,
159162 }
160163
164+ def apply (self , symbols , evaluation ):
165+ "Protect[symbols___]"
166+ protected = Symbol ("System`Protected" )
167+ items = []
168+
169+ if isinstance (symbols ,Symbol ):
170+ symbols = [symbols ]
171+ elif isinstance (symbols , String ):
172+ symbols = [symbols ]
173+ elif isinstance (symbols , Expression ):
174+ if symbols .get_head_name () in ("System`Sequence" , "System`List" ):
175+ symbols = symbols .get_leaves ()
176+ else :
177+ evaluation .message ('Protect' , 'ssym' , symbol )
178+ return Symbol ("Null" )
179+
180+ for symbol in symbols :
181+ if isinstance (symbol , Symbol ):
182+ items .append (symbol )
183+ else :
184+ pattern = symbol .get_string_value ()
185+ if not pattern or pattern == "" :
186+ evaluation .message ('Protect' , 'ssym' , symbol )
187+ continue
188+
189+ if pattern [0 ] == "`" :
190+ pattern = evaluation .definitions .get_current_context () + pattern [1 :]
191+ names = evaluation .definitions .get_matching_names (pattern )
192+ for defn in names :
193+ symbol = Symbol (defn )
194+ if not 'System`Locked' in evaluation .definitions .get_attributes (defn ):
195+ items .append (symbol )
196+
197+ Expression ("SetAttributes" , Expression ("List" , * items ), protected ).evaluate (evaluation )
198+ return Symbol ('Null' )
199+
161200
162201class Unprotect (Builtin ):
163202 """
0 commit comments