22
33from mathics .builtin .base import Builtin , BoxConstruct
44from mathics .core .expression import Atom , Expression , Symbol , String , from_python , Integer , Real
5-
5+ from mathics . core . evaluation import Evaluation
66
77class Compile (Builtin ):
88 '''
@@ -33,8 +33,7 @@ class Compile(Builtin):
3333 : Duplicate parameter x found in {{x, _Real}, {x, _Integer}}.
3434 = Compile[{{x, _Real}, {x, _Integer}}, Sin[x + y]]
3535 #> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + z]]
36- : Expression Sin[x + z] could not be compiled.
37- = Function[{Global`x, Global`y}, Sin[x + z]]
36+ = CompiledFunction[{x, y}, Sin[x + z], -CompiledCode-]
3837 #> cf = Compile[{{x, _Real}, {y, _Integer}}, Sin[x + y]]
3938 = CompiledFunction[{x, y}, Sin[x + y], -CompiledCode-]
4039 #> cf[1, 2]
@@ -50,10 +49,10 @@ class Compile(Builtin):
5049 #> cf[0, -2]
5150 = 0.5
5251
53- Loops and variable assignments are not yet supported
52+ Loops and variable assignments are supported as python (not llvmlite)
53+ functions
5454 >> Compile[{{a, _Integer}, {b, _Integer}}, While[b != 0, {a, b} = {b, Mod[a, b]}]; a] (* GCD of a, b *)
55- : Expression While[b != 0, {a, b} = {b, Mod[a, b]}] ; a could not be compiled.
56- = Function[{Global`a, Global`b}, While[b != 0, {a, b} = {b, Mod[a, b]}] ; a]
55+ = CompiledFunction[{a, b}, a, -CompiledCode-]
5756 '''
5857
5958 requires = (
@@ -110,9 +109,27 @@ def apply(self, vars, expr, evaluation):
110109 try :
111110 cfunc = _compile (expr , args )
112111 except CompileError :
112+ cfunc = None
113+
114+ if cfunc is None :
115+ try :
116+ def _pythonized_mathics_expr (* x ):
117+ inner_evaluation = Evaluation (definitions = evaluation .definitions )
118+ vars = dict (list (zip (names , x [:len (names )])))
119+ pyexpr = expr .replace_vars (vars )
120+ pyexpr = Expression ("N" , pyexpr ).evaluate (inner_evaluation )
121+ res = pyexpr .to_python (n_evaluation = inner_evaluation )
122+ return res
123+ #TODO: check if we can use numba to compile this...
124+ cfunc = _pythonized_mathics_expr
125+ except Exception as e :
126+ cfunc = None
127+
128+ if cfunc is None :
113129 evaluation .message ('Compile' , 'comperr' , expr )
114- args = Expression ("List" ,* names )
130+ args = Expression ("List" , * names )
115131 return Expression ("Function" , args , expr )
132+
116133 code = CompiledCode (cfunc , args )
117134 arg_names = Expression ('List' , * (Symbol (arg .name ) for arg in args ))
118135 return Expression ('CompiledFunction' , arg_names , expr , code )
@@ -206,5 +223,6 @@ def apply(self, argnames, expr, code, args, evaluation):
206223 try :
207224 result = code .cfunc (* py_args )
208225 except (TypeError , ctypes .ArgumentError ):
209- return evaluation .message ('CompiledFunction' , 'argerr' , args )
226+ evaluation .message ('CompiledFunction' , 'argerr' , args )
227+ return
210228 return from_python (result )
0 commit comments