|
5 | 5 | from mathics.builtin.base import Builtin, Predefined |
6 | 6 | from mathics.core.expression import (Expression, String, Symbol, Integer, |
7 | 7 | fully_qualified_symbol_name) |
8 | | - |
| 8 | +from mathics.core.rules import Rule |
9 | 9 |
|
10 | 10 | def get_scoping_vars(var_list, msg_symbol='', evaluation=None): |
11 | 11 | def message(tag, *args): |
@@ -55,6 +55,54 @@ def dynamic_scoping(func, vars, evaluation): |
55 | 55 | return result |
56 | 56 |
|
57 | 57 |
|
| 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 | + |
58 | 106 | class Block(Builtin): |
59 | 107 | """ |
60 | 108 | <dl> |
@@ -414,7 +462,7 @@ class Contexts(Builtin): |
414 | 462 | ## this assignment makes sure that a definition in Global` exists |
415 | 463 | >> x = 5; |
416 | 464 | >> 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`"} |
418 | 466 | """ |
419 | 467 |
|
420 | 468 | def apply(self, evaluation): |
@@ -590,12 +638,15 @@ class BeginPackage(Builtin): |
590 | 638 |
|
591 | 639 | rules = { |
592 | 640 | 'BeginPackage[context_String]': ''' |
593 | | - Unprotect[System`Private`$ContextPathStack]; |
| 641 | + Unprotect[System`Private`$ContextPathStack, System`$Packages]; |
594 | 642 | Begin[context]; |
595 | 643 | System`Private`$ContextPathStack = |
596 | 644 | Append[System`Private`$ContextPathStack, $ContextPath]; |
597 | 645 | $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]; |
599 | 650 | context |
600 | 651 | ''', |
601 | 652 | } |
|
0 commit comments