4
4
5
5
#*****************************************************************************
6
6
# Copyright (C) 2015 Jeroen Demeyer <[email protected] >
7
+ # 2017 Vincent Delecroix <[email protected] >
7
8
#
8
9
# This program is free software: you can redistribute it and/or modify
9
10
# it under the terms of the GNU General Public License as published by
16
17
import os , re , sys
17
18
18
19
from .args import PariArgumentGEN , PariInstanceArgument
19
- from .parser import ( read_pari_desc , read_decl , parse_prototype )
20
+ from .parser import read_pari_desc , parse_prototype
20
21
from .doc import get_rest_doc
21
22
22
23
42
43
"""
43
44
''' .format (__file__ )
44
45
46
+ decl_banner = '''# This file is auto-generated by {}
47
+
48
+ from .types cimport *
49
+
50
+ cdef extern from *:
51
+ ''' .format (__file__ )
52
+
45
53
46
54
function_re = re .compile (r"^[A-Za-z][A-Za-z0-9_]*$" )
47
55
function_blacklist = {"O" , # O(p^e) needs special parser support
48
56
"alias" , # Not needed and difficult documentation
49
57
"listcreate" , # "redundant and obsolete" according to PARI
50
58
"allocatemem" , # Better hand-written support in Pari class
59
+ "global" , # Invalid in Python (and obsolete)
60
+ "inline" , # Total confusion
61
+ "uninline" , # idem
62
+ "local" , # idem
63
+ "my" , # idem
64
+ "plot" , # Graphical function undeclared in pari public headers
65
+ "plotbox" , # idem
66
+ "plotclip" , # idem
67
+ "plotcursor" , # idem
68
+ "plotcolor" , # idem
69
+ "plotcopy" , # idem
70
+ "plotdraw" , # idem
71
+ "plothsizes" , # idem
72
+ "plotinit" , # idem
73
+ "plotkill" , # idem
74
+ "plotlines" , # idem
75
+ "plotlinetype" , # idem
76
+ "plotmove" , # idem
77
+ "plotpoints" , # idem
78
+ "plotpointsize" , # idem
79
+ "plotpointtype" , # idem
80
+ "plotrbox" , # idem
81
+ "plotrecth" , # idem
82
+ "plotrecthraw" , # idem
83
+ "plotrline" , # idem
84
+ "plotrmove" , # idem
85
+ "plotrpoint" , # idem
86
+ "plotscale" , # idem
87
+ "plotstring" , # idem
88
+ "ploth" , # idem
89
+ "plothraw" , # idem
90
+ "psdraw" , # idem
91
+ "psplothraw" , # idem
51
92
}
52
93
53
94
class PariFunctionGenerator (object ):
@@ -59,9 +100,9 @@ class PariFunctionGenerator(object):
59
100
:class:`Pari`.
60
101
"""
61
102
def __init__ (self ):
62
- self .declared = read_decl ()
63
103
self .gen_filename = os .path .join ('cypari2' , 'auto_gen.pxi' )
64
104
self .instance_filename = os .path .join ('cypari2' , 'auto_instance.pxi' )
105
+ self .decl_filename = os .path .join ('cypari2' , 'auto_paridecl.pxd' )
65
106
66
107
def can_handle_function (self , function , cname = "" , ** kwds ):
67
108
"""
@@ -75,8 +116,6 @@ def can_handle_function(self, function, cname="", **kwds):
75
116
True
76
117
>>> G.can_handle_function("_bnfinit", "bnfinit0", **{"class":"basic"})
77
118
False
78
- >>> G.can_handle_function("bnfinit", "BNFINIT0", **{"class":"basic"})
79
- False
80
119
>>> G.can_handle_function("bnfinit", "bnfinit0", **{"class":"hard"})
81
120
False
82
121
"""
@@ -86,9 +125,6 @@ def can_handle_function(self, function, cname="", **kwds):
86
125
if not function_re .match (function ):
87
126
# Not a legal function name, like "!_"
88
127
return False
89
- if cname not in self .declared :
90
- # PARI function not in paridecl.pxd or declinl.pxi
91
- return False
92
128
cls = kwds .get ("class" , "unknown" )
93
129
sec = kwds .get ("section" , "unknown" )
94
130
if cls not in ("basic" , "highlevel" ):
@@ -114,6 +150,7 @@ def handle_pari_function(self, function, cname="", prototype="", help="", obsole
114
150
>>> G = PariFunctionGenerator()
115
151
>>> G.gen_file = sys.stdout
116
152
>>> G.instance_file = sys.stdout
153
+ >>> G.decl_file = sys.stdout
117
154
>>> G.handle_pari_function("bnfinit",
118
155
... cname="bnfinit0", prototype="GD0,L,DGp",
119
156
... help=r"bnfinit(P,{flag=0},{tech=[]}): compute...",
@@ -135,6 +172,7 @@ def bnfinit(P, long flag=0, tech=None, long precision=0):
135
172
... cname="ellmodulareqn", prototype="LDnDn",
136
173
... help=r"ellmodulareqn(N,{x},{y}): return...",
137
174
... **{"class":"basic", "section":"elliptic_curves"})
175
+ GEN ellmodulareqn(long N, long x, long y)
138
176
def ellmodulareqn(self, long N, x=None, y=None):
139
177
...
140
178
cdef long _x = -1
@@ -171,6 +209,7 @@ def setrand(n):
171
209
... help="bernvec(x): this routine is obsolete, use bernfrac repeatedly.",
172
210
... obsolete="2007-03-30",
173
211
... **{"class":"basic", "section":"transcendental"})
212
+ GEN bernvec(long x)
174
213
def bernvec(self, long x):
175
214
r'''
176
215
This routine is obsolete, kept for backward compatibility only.
@@ -182,6 +221,8 @@ def bernvec(self, long x):
182
221
return new_gen(_ret)
183
222
<BLANKLINE>
184
223
"""
224
+ if not cname :
225
+ raise ValueError ('function {} has no associated C name' .format (function ))
185
226
try :
186
227
args , ret = parse_prototype (prototype , help )
187
228
except NotImplementedError :
@@ -195,12 +236,18 @@ def bernvec(self, long x):
195
236
self .write_method (function , cname , args , ret , args ,
196
237
self .gen_file , doc , obsolete )
197
238
198
- # In any case, write a method of the Pari class.
239
+ # In any case, write a declaration and a method of the Pari class.
240
+ self .write_header (cname , args , ret , self .decl_file )
241
+
199
242
# Parse again with an extra "self" argument.
200
243
args , ret = parse_prototype (prototype , help , [PariInstanceArgument ()])
201
244
self .write_method (function , cname , args , ret , args [1 :],
202
245
self .instance_file , doc , obsolete )
203
246
247
+ def write_header (self , cname , args , ret , file ):
248
+ args = ", " .join ('{} {}' .format (a .ctype (), a .name ) for a in args )
249
+ print (' {ret} {function}({args})' .format (ret = ret .ctype (), function = cname , args = args ), file = file )
250
+
204
251
def write_method (self , function , cname , args , ret , cargs , file , doc , obsolete ):
205
252
"""
206
253
Write Cython code with a method to call one PARI function.
@@ -264,6 +311,8 @@ def __call__(self):
264
311
self .gen_file .write (gen_banner )
265
312
self .instance_file = open (self .instance_filename + '.tmp' , 'w' )
266
313
self .instance_file .write (instance_banner )
314
+ self .decl_file = open (self .decl_filename + '.tmp' , 'w' )
315
+ self .decl_file .write (decl_banner )
267
316
268
317
for v in D :
269
318
if not self .can_handle_function (** v ):
@@ -276,7 +325,9 @@ def __call__(self):
276
325
277
326
self .gen_file .close ()
278
327
self .instance_file .close ()
328
+ self .decl_file .close ()
279
329
280
330
# All done? Let's commit.
281
331
os .rename (self .gen_filename + '.tmp' , self .gen_filename )
282
332
os .rename (self .instance_filename + '.tmp' , self .instance_filename )
333
+ os .rename (self .decl_filename + '.tmp' , self .decl_filename )
0 commit comments