Skip to content

Commit dce8c1d

Browse files
committed
adding support for With
1 parent c2457d5 commit dce8c1d

1 file changed

Lines changed: 55 additions & 4 deletions

File tree

mathics/builtin/scoping.py

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from mathics.builtin.base import Builtin, Predefined
66
from mathics.core.expression import (Expression, String, Symbol, Integer,
77
fully_qualified_symbol_name)
8-
8+
from mathics.core.rules import Rule
99

1010
def get_scoping_vars(var_list, msg_symbol='', evaluation=None):
1111
def message(tag, *args):
@@ -55,6 +55,54 @@ def dynamic_scoping(func, vars, evaluation):
5555
return result
5656

5757

58+
class With(Builtin):
59+
"""
60+
<dl>
61+
62+
<dt>'With[{$x$=$x0$, $y$=$y0$, ...}, $expr$]'
63+
<dd>specifies that all occurrences of the symbols $x$, $y$, ... in $expr$ should be replaced by $x0$, $y0$, ...
64+
</dl>
65+
66+
>> n = 10
67+
= 10
68+
>> With[{n = 5}, n ^ 2]
69+
= 25
70+
>> n
71+
= 10
72+
>> With[{x=y}, Hold[x]]
73+
= Hold[y]
74+
>> Table[With[{i=j}, Hold[i]],{j,1,4}]
75+
= {Hold[1], Hold[2], Hold[3], Hold[4]}
76+
>> x=5; With[{x=x}, Hold[x]]
77+
= Hold[5]
78+
>> {Block[{x = 3}, Hold[x]], With[{x = 3}, Hold[x]]}
79+
= {Hold[x], Hold[3]}
80+
>> x=.; ReleaseHold /@ %
81+
= {x, 3}
82+
>> With[{e = y}, Function[{x,y}, e*x*y]]
83+
= Function[{x$, y$}, y x$ y$]
84+
85+
"""
86+
87+
attributes = ('HoldAll',)
88+
89+
messages = {
90+
'lvsym': ("Local variable specification contains `1`, "
91+
"which is not a symbol or an assignment to a symbol."),
92+
'dup': ("Duplicate local variable `1` found in local variable "
93+
"specification."),
94+
'lvlist': "Local variable specification `1` is not a List.",
95+
}
96+
97+
def apply(self, vars, expr, evaluation):
98+
'With[vars_, expr_]'
99+
100+
vars = dict(get_scoping_vars(vars, 'With', evaluation))
101+
result = expr.replace_vars(vars)
102+
result.evaluate(evaluation)
103+
return result
104+
105+
58106
class Block(Builtin):
59107
"""
60108
<dl>
@@ -414,7 +462,7 @@ class Contexts(Builtin):
414462
## this assignment makes sure that a definition in Global` exists
415463
>> x = 5;
416464
>> Contexts[] // InputForm
417-
= {"CombinatoricaOld`", "Global`", "ImportExport`", "Internal`", "System`", "System`Convert`B64Dump`", "System`Convert`Image`", "System`Convert`JSONDump`", "System`Convert`TableDump`", "System`Convert`TextDump`", "System`Private`", "XML`", "XML`Parser`"}
465+
= {"Global`", "ImportExport`", "Internal`", "System`", "System`Convert`B64Dump`", "System`Convert`Image`", "System`Convert`JSONDump`", "System`Convert`TableDump`", "System`Convert`TextDump`", "System`Private`", "XML`", "XML`Parser`"}
418466
"""
419467

420468
def apply(self, evaluation):
@@ -590,12 +638,15 @@ class BeginPackage(Builtin):
590638

591639
rules = {
592640
'BeginPackage[context_String]': '''
593-
Unprotect[System`Private`$ContextPathStack];
641+
Unprotect[System`Private`$ContextPathStack, System`$Packages];
594642
Begin[context];
595643
System`Private`$ContextPathStack =
596644
Append[System`Private`$ContextPathStack, $ContextPath];
597645
$ContextPath = {context, "System`"};
598-
Protect[System`Private`$ContextPathStack];
646+
$Packages = If[MemberQ[System`$Packages,$Context],
647+
None,
648+
System`$Packages=Join[{$Context}, System`$Packages]];
649+
Protect[System`Private`$ContextPathStack, System`$Packages];
599650
context
600651
''',
601652
}

0 commit comments

Comments
 (0)