Skip to content

Commit

Permalink
autogeneration of paridecl.pxd
Browse files Browse the repository at this point in the history
  • Loading branch information
videlec committed Jan 22, 2018
1 parent 83ea7d2 commit 9c18256
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 35 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ cypari2/auto_gen.pxi.tmp
cypari2/auto_gen.pxi
cypari2/auto_instance.pxi.tmp
cypari2/auto_instance.pxi
cypari2/auto_paridecl.pxd.tmp
cypari2/auto_paridecl.pxd
cypari2/paridecl.pxd.tmp
cypari2/paridecl.pxd
cypari2/closure.c
cypari2/convert.c
cypari2/gen.c
Expand Down
78 changes: 53 additions & 25 deletions autogen/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@
"""
'''

decl_banner = autogen_top + '''
from .types cimport *
cdef extern from *:
'''


function_re = re.compile(r"^[A-Za-z][A-Za-z0-9_]*$")
function_blacklist = {"O", # O(p^e) needs special parser support
Expand All @@ -75,7 +69,27 @@ class PariFunctionGenerator(object):
def __init__(self):
self.gen_filename = os.path.join('cypari2', 'auto_gen.pxi')
self.instance_filename = os.path.join('cypari2', 'auto_instance.pxi')
self.decl_filename = os.path.join('cypari2', 'auto_paridecl.pxd')
self.decl_filename = os.path.join('cypari2', 'paridecl.pxd')

def write_paridecl_no_desc(self, D):
r"""
Write the template ``template_paridecl.pxd`` into the declaration file
after removing all functions from ``D`` (that are obtained from
``pari.desc``).
"""
fnc = re.compile(" (int|long|void|GEN) +([A-Za-z][0-9A-Za-z_]*)\(.*\)")

functions = set(f.get('cname') for f in D)

with open('autogen/template_paridecl.pxd') as template:
for line in template.read().split('\n'):
match = fnc.match(line)
if match:
out_type, fname = match.groups()
if fname in functions:
continue
self.decl_file.write(line)
self.decl_file.write("\n")

def can_handle_function(self, function, cname="", **kwds):
"""
Expand Down Expand Up @@ -107,9 +121,10 @@ def can_handle_function(self, function, cname="", **kwds):
if sec == "programming/control":
# Skip if, return, break, ...
return False

return True

def handle_pari_function(self, function, cname, prototype="", help="", obsolete=None, **kwds):
def handle_pari_function(self, function, cname, prototype, help, args=None, ret=None, obsolete=None, **kwds):
r"""
Handle one PARI function: decide whether or not to add the
function, in which file (as method of :class:`Gen` or
Expand All @@ -118,8 +133,8 @@ def handle_pari_function(self, function, cname, prototype="", help="", obsolete=
EXAMPLES::
>>> from autogen.parser import read_pari_desc
>>> from autogen.generator import PariFunctionGenerator
>>> import sys
>>> G = PariFunctionGenerator()
>>> G.gen_file = sys.stdout
>>> G.instance_file = sys.stdout
Expand Down Expand Up @@ -201,13 +216,10 @@ def bernvec(self, long x):
return new_gen(_ret)
<BLANKLINE>
"""
try:
if args is None or ret is None:
args, ret = parse_prototype(prototype, help)
except NotImplementedError:
return # Skip unsupported prototype codes

sys.stdout.flush()
doc = get_rest_doc(function)

self.write_declaration(cname, args, ret, self.decl_file)

if len(args) > 0 and isinstance(args[0], PariArgumentGEN):
Expand All @@ -222,6 +234,8 @@ def bernvec(self, long x):
self.write_method(function, cname, args, ret, args[1:],
self.instance_file, doc, obsolete)

return 0

def write_declaration(self, cname, args, ret, file):
"""
Write a .pxd declaration of a PARI library function.
Expand Down Expand Up @@ -293,29 +307,43 @@ def __call__(self):
"""
D = read_pari_desc()
D = sorted(D.values(), key=lambda d: d['function'])
sys.stdout.write("Generating PARI functions:")

self.gen_file = io.open(self.gen_filename + '.tmp', 'w', encoding='utf-8')
self.gen_file.write(gen_banner)
self.instance_file = io.open(self.instance_filename + '.tmp', 'w', encoding='utf-8')
self.instance_file.write(instance_banner)
self.decl_file = io.open(self.decl_filename + '.tmp', 'w', encoding='utf-8')
self.decl_file.write(decl_banner)

DD = []
sys.stdout.write("Unhandled PARI function:\n")
for v in D:
func = v["function"]
if not self.can_handle_function(**v):
sys.stdout.write(" (%s)" % func)
else:
try:
args, ret = parse_prototype(v["prototype"], v["help"])
v["args"] = args
v["ret"] = ret
DD.append(v)
except NotImplementedError:
sys.stdout.write(" ((%s))" % func)
sys.stdout.write("\n")

self.write_paridecl_no_desc(DD)

# Check for availability of hi-res SVG plotting. This requires
# PARI-2.10 or later.
have_plot_svg = False

for v in D:
sys.stdout.write("Generating PARI functions:\n")
for v in DD:
func = v["function"]
if self.can_handle_function(**v):
sys.stdout.write(" %s" % func)
sys.stdout.flush()
self.handle_pari_function(**v)
if func == "plothraw":
have_plot_svg = True
else:
sys.stdout.write(" (%s)" % func)
sys.stdout.write(" %s" % func)
self.handle_pari_function(**v)
sys.stdout.flush()
if func == "plothraw":
have_plot_svg = True
sys.stdout.write("\n")

self.instance_file.write("DEF HAVE_PLOT_SVG = {}".format(have_plot_svg))
Expand Down
16 changes: 8 additions & 8 deletions autogen/template_paridecl.pxd
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# distutils: libraries = gmp pari
"""
Declarations for non-inline functions from PARI.
Declarations of PARI functions.
This file contains all declarations from headers/paridecl.h from
the PARI distribution, except the inline functions which are in
declinl.pxi (that file is automatically included by this file).
the PARI distribution.
AUTHORS:
Expand All @@ -20,6 +18,9 @@ AUTHORS:
- Jeroen Demeyer (2014-09-19): upgrade to PARI 2.8 (:trac:`16997`)
- Vincent Delecroix (2017-2018): auto-generate part of the declarations
from ``pari.desc``
"""

#*****************************************************************************
Expand Down Expand Up @@ -5168,7 +5169,6 @@ cdef extern from *: # PARI headers already included by types.pxd
void pari_err_VAR(const char *f, GEN x, GEN y)
void pari_err_ROOTS0(const char *f)

# Auto-generated declarations. There are taken from the PARI version
# on the system, so they more up-to-date than the above. In case of
# conflicting declarations, auto_paridecl should have priority.
from .auto_paridecl cimport *
#########################################################
# All functions below are auto-generated from pari.desc #
#########################################################

0 comments on commit 9c18256

Please sign in to comment.