Skip to content

Commit abe1bbd

Browse files
committed
improve doctest. use a fresh evaluation object for the compiled function
1 parent 969a232 commit abe1bbd

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

mathics/builtin/compilation.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212

1313
from mathics.builtin.box.compilation import CompiledCodeBox
1414
from mathics.core.atoms import Integer, String
15-
from mathics.core.attributes import A_HOLD_ALL, A_PROTECTED
15+
from mathics.core.attributes import (
16+
A_HOLD_ALL,
17+
A_N_HOLD_ALL,
18+
A_PROTECTED,
19+
A_READ_PROTECTED,
20+
)
1621
from mathics.core.builtin import Builtin
1722
from mathics.core.convert.expression import to_mathics_list
1823
from mathics.core.convert.function import (
@@ -66,8 +71,10 @@ class Compile(Builtin):
6671
= 2.18888
6772
6873
Loops and variable assignments are supported using Python builtin "compile" function:
69-
>> Compile[{{a, _Integer}, {b, _Integer}}, While[b != 0, {a, b} = {b, Mod[a, b]}]; a] (* GCD of a, b *)
70-
= CompiledFunction[{a, b}, While[b != 0, {a, b} = {b, Mod[a, b]}] ; a, -PythonizedCode-]
74+
>> gdc = Compile[{{a, _Integer}, {b, _Integer}}, Module[{x=a, y=b}, While[y != 0, {x, y} = {y, Mod[x, y]}]; x]] (* GCD of a, b *)
75+
= CompiledFunction[{a, b}, Module[{x = a, y = b}, While[y != 0, {x, y} = {y, Mod[x, y]}] ; x], -PythonizedCode-]
76+
>> gdc[18, 81]
77+
= 9.
7178
"""
7279

7380
attributes = A_HOLD_ALL | A_PROTECTED
@@ -167,7 +174,23 @@ def to_sympy(self, *args, **kwargs):
167174
raise NotImplementedError
168175

169176
def __hash__(self):
170-
return hash(("CompiledCode", ctypes.addressof(self.cfunc))) # XXX hack
177+
cfunc = self.cfunc
178+
if cfunc is None:
179+
hash(
180+
(
181+
"CompiledCode",
182+
None,
183+
)
184+
) # XXX hack
185+
try:
186+
return hash(("CompiledCode", ctypes.addressof(cfunc))) # XXX hack
187+
except TypeError:
188+
return hash(
189+
(
190+
"Pythonized-function",
191+
cfunc,
192+
)
193+
)
171194

172195
def atom_to_boxes(self, f, evaluation: Evaluation):
173196
return CompiledCodeBox(String(self.__str__()), evaluation=evaluation)
@@ -191,6 +214,7 @@ class CompiledFunction(Builtin):
191214
192215
"""
193216

217+
attributes = A_HOLD_ALL | A_PROTECTED | A_N_HOLD_ALL | A_READ_PROTECTED
194218
messages = {"argerr": "Invalid argument `1` should be Integer, Real or boolean."}
195219
summary_text = "A CompiledFunction object."
196220

mathics/core/convert/function.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,12 @@ def expression_to_callable(
101101
def _pythonized_mathics_expr(*x):
102102
from mathics.eval.scoping import dynamic_scoping
103103

104+
inner_evaluation = Evaluation(definitions=evaluation.definitions)
104105
vars = {a.name: from_python(u) for a, u in zip(args, x[: len(args)])}
105-
pyexpr = dynamic_scoping(lambda ev: expr.evaluate(ev), vars, evaluation)
106-
pyexpr = eval_N(pyexpr, evaluation)
106+
pyexpr = dynamic_scoping(
107+
lambda ev: expr.evaluate(ev), vars, inner_evaluation
108+
)
109+
pyexpr = eval_N(pyexpr, inner_evaluation)
107110
res = pyexpr.to_python()
108111
return res
109112

mathics/eval/scoping.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def dynamic_scoping(func, vars, evaluation: Evaluation):
1616
and evaluates func(evaluation)
1717
"""
1818
original_definitions = {}
19+
1920
for var_name, new_def in vars.items():
2021
assert fully_qualified_symbol_name(var_name)
2122
original_definitions[var_name] = evaluation.definitions.get_user_definition(

0 commit comments

Comments
 (0)