Skip to content

Commit db2f479

Browse files
authored
Add Stack[] (#1259)
Start `Stack[]` builtin function. I hope more sometime after release.
1 parent d2e50ed commit db2f479

File tree

14 files changed

+270
-143
lines changed

14 files changed

+270
-143
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ New Builtins
1212
* ``FormatValues``
1313
* ``SetEnvironment``
1414
* ``SequenceForm``
15+
* ``Stack``
1516

1617
By `@davidar <https://github.com/davidar>`_:
1718

SYMBOLS_MANIFEST.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ System`SquareSupersetEqual
11201120
System`SquareUnion
11211121
System`SquaredEuclideanDistance
11221122
System`SquaresR
1123-
System`Stacktrace
1123+
System`Stack
11241124
System`StandardDeviation
11251125
System`StandardForm
11261126
System`Star

mathics/builtin/evaluation.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ class Hold(Builtin):
116116
<url>:WMA link:https://reference.wolfram.com/language/ref/Hold.html</url>
117117
118118
<dl>
119-
<dt>'Hold[$expr$]'
120-
<dd>prevents $expr$ from being evaluated.
119+
<dt>'Hold[$expr$]'
120+
<dd>prevents $expr$ from being evaluated.
121121
</dl>
122122
123123
>> Attributes[Hold]
@@ -133,9 +133,9 @@ class HoldComplete(Builtin):
133133
<url>:WMA link:https://reference.wolfram.com/language/ref/HoldComplete.html</url>
134134
135135
<dl>
136-
<dt>'HoldComplete[$expr$]'
137-
<dd>prevents $expr$ from being evaluated, and also prevents
138-
'Sequence' objects from being spliced into argument lists.
136+
<dt>'HoldComplete[$expr$]'
137+
<dd>prevents $expr$ from being evaluated, and also prevents \
138+
'Sequence' objects from being spliced into argument lists.
139139
</dl>
140140
141141
>> Attributes[HoldComplete]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""
2+
Symbolic Execution History
3+
4+
In order to debug and understand program execution, the execution history can be saved.
5+
"""
6+
sort_order = "mathics.builtin.symbolic-execution-history"
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# from mathics.core.atoms import Integer2
2+
from mathics.core.attributes import A_HOLD_ALL, A_HOLD_FIRST, A_PROTECTED
3+
from mathics.core.builtin import Builtin
4+
from mathics.core.evaluation import Evaluation
5+
from mathics.core.list import ListExpression
6+
7+
# from mathics.core.systemsymbols import SymbolTrace
8+
from mathics.eval.symbolic_history.stack import eval_Stack, eval_Trace
9+
10+
11+
class Stack(Builtin):
12+
"""
13+
<url>:WMA link:
14+
https://reference.wolfram.com/language/ref/Stack.html</url>
15+
16+
<dl>
17+
<dt>'Stack[]'
18+
<dd>Print Mathics3 stack trace of evalutations leading to this point.
19+
</dl>
20+
21+
>> f[g[1, Print[Stack[]] ; 2]]
22+
= {f[g[1, Print[Stack[]] ; 2]], g[1, Print[Stack[]] ; 2], Print[Stack[]] ; 2, CompoundExpression, Print[Stack[]]}
23+
24+
25+
The actual 'Stack[0]' call is hidden from the output; so when \
26+
run on its own, nothing appears.
27+
28+
>> Stack[]
29+
= {}
30+
"""
31+
32+
attributes = A_HOLD_FIRST | A_PROTECTED
33+
summary_text = "print Mathics3 function stacktrace"
34+
35+
def eval(self, evaluation: Evaluation) -> ListExpression:
36+
"Stack[]"
37+
38+
return eval_Stack()
39+
40+
41+
class Trace(Builtin):
42+
"""
43+
<url>:WMA link:
44+
https://reference.wolfram.com/language/ref/Trace.html</url>
45+
46+
<dl>
47+
<dt>'Trace[$expr$]'
48+
<dd>generate a list of all expressions used in the evaluation of $expr$.
49+
</dl>
50+
51+
>> Trace[1 + 2]
52+
= {1 + 2, 3}
53+
"""
54+
55+
attributes = A_HOLD_ALL | A_PROTECTED
56+
summary_text = "list intermediary expressions in an evaluation"
57+
58+
def eval(self, expr, evaluation: Evaluation) -> ListExpression:
59+
"Trace[expr__]"
60+
61+
# n = len(expr.elements)
62+
# if n > 2:
63+
# evaluation.message("Trace", "nonopt", TraceSymbol, Integer2
64+
# Expression[TraceSymbol]
65+
# return
66+
return eval_Trace(expr, evaluation)

mathics/builtin/trace.py

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from time import time
2323
from typing import Callable
2424

25-
import mathics.eval.trace
2625
import mathics.eval.tracing
2726
from mathics.core.attributes import A_HOLD_ALL, A_HOLD_ALL_COMPLETE, A_PROTECTED
2827
from mathics.core.builtin import Builtin
@@ -147,46 +146,6 @@ def eval(self, evaluation, options={}):
147146
return SymbolNull
148147

149148

150-
class Stacktrace(_TraceBase):
151-
"""
152-
## <url>:trace native symbol:</url>
153-
154-
<dl>
155-
<dt>'Stacktrace[]'
156-
<dd>Print Mathics3 stack trace of evaluations leading to this point
157-
</dl>
158-
159-
To show the Mathics3 evaluation stack at the \
160-
point where expression $expr$ is evaluated, wrap $expr$ inside '{$expr$ Stacktrace[]}[1]]' \
161-
or something similar.
162-
163-
Here is a complete example. To show the evaluation stack when computing a homegrown \
164-
factorial function:
165-
166-
>> F[0] := {1, Stacktrace[]}[[1]]; F[n_] := n * F[n-1]
167-
168-
>> F[3] (* See console log *)
169-
= 6
170-
171-
The actual 'Stacktrace[0]' call is hidden from the output; so when \
172-
run on its own, nothing appears.
173-
174-
>> Stacktrace[]
175-
176-
#> Clear[F]
177-
"""
178-
179-
summary_text = "print Mathics3 function stacktrace"
180-
181-
def eval(self, evaluation: Evaluation):
182-
"Stacktrace[]"
183-
184-
# Use longer-form resolve call
185-
# so a debugger can change this.
186-
mathics.eval.trace.eval_Stacktrace()
187-
return SymbolNull
188-
189-
190149
class TraceBuiltins(_TraceBase):
191150
"""
192151
## <url>:trace native symbol:</url>
@@ -433,8 +392,7 @@ def eval(self, expr, evaluation: Evaluation, options: dict):
433392
options["System`ShowTimeBySteps"] is SymbolTrue
434393
)
435394
try:
436-
result = expr.evaluate(evaluation)
437-
return result
395+
return expr.evaluate(evaluation)
438396
except Exception:
439397
raise
440398
finally:

mathics/core/evaluation.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ def __init__(
124124
# status of last evaluate
125125
self.exc_result: Optional[Symbol] = self.SymbolNull
126126
self.last_eval = None
127+
128+
# A place for Trace and friend to store information about the
129+
# last evaluation
130+
self.trace_info: Optional[Any] = None
131+
127132
# Used in ``mathics.builtin.numbers.constants.get_constant`` and
128133
# ``mathics.builtin.numeric.N``.
129134
self._preferred_n_method: List[str] = []

mathics/core/expression.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,13 +1416,8 @@ def rules():
14161416
if not isinstance(result, EvalMixin):
14171417
return result, False
14181418
if result.sameQ(new):
1419-
# Even though result and new may be the same,
1420-
# new can be a Expression[SymbolConstant: System`List...]
1421-
# while "result' might be ListExpression!?
1422-
# So make sure to use "result", not "new".
1423-
if isinstance(result, Expression):
1424-
result._timestamp_cache(evaluation)
1425-
return result, False
1419+
new._timestamp_cache(evaluation)
1420+
return new, False
14261421
else:
14271422
return result, True
14281423

mathics/eval/numbers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# -*- coding: utf-8 -*-
22
"""
3-
Implementation of mathics.builtin.numbers
3+
Evaluation functions in support of builtin functions under mathics.builtin.numbers
44
"""
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Evaluation functions in support of builtin functions under mathics.builtin.symbolic_history
4+
"""

0 commit comments

Comments
 (0)