Skip to content

Commit

Permalink
autogeneration of paridecl.pxd
Browse files Browse the repository at this point in the history
  • Loading branch information
videlec authored and jdemeyer committed Jan 16, 2019
1 parent 9ea328a commit 0e8b4c0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 38 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
82 changes: 56 additions & 26 deletions autogen/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,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 @@ -82,7 +76,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 @@ -117,9 +131,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 @@ -128,8 +143,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 @@ -226,13 +241,14 @@ def polredord(self, x):
return new_gen(_ret)
<BLANKLINE>
"""
try:
args, ret = parse_prototype(prototype, help)
except NotImplementedError:
return # Skip unsupported prototype codes

if args is None or ret is None:
aargs, rret = parse_prototype(prototype, help)
if args is None:
args = aargs
if ret is None:
ret = rret
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 Down Expand Up @@ -320,29 +336,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
21 changes: 11 additions & 10 deletions cypari2/paridecl.pxd → 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 @@ -5172,12 +5173,6 @@ cdef inline int is_universal_constant(GEN x):
return _is_universal_constant(x) or (x is err_e_STACK)


# 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 *


cdef inline int is_on_stack(GEN x) except -1:
"""
Is the GEN ``x`` stored on the PARI stack?
Expand All @@ -5188,3 +5183,9 @@ cdef inline int is_on_stack(GEN x) except -1:
if pari_mainstack.vbot <= s:
raise SystemError("PARI object in unused part of PARI stack")
return 0


#########################################################
# All functions below are auto-generated from pari.desc #
#########################################################
cdef extern from *:

0 comments on commit 0e8b4c0

Please sign in to comment.