summaryrefslogtreecommitdiffstats
path: root/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler
diff options
context:
space:
mode:
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Pyrex/Compiler')
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py276
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py94
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py546
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py4
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py77
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py3954
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py9
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.picklebin19254 -> 0 bytes
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py145
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py564
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py1678
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py69
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py3249
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py5
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py2142
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py974
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py390
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py1342
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py629
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py0
21 files changed, 0 insertions, 16148 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py
deleted file mode 100644
index 62dbfbef..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py
+++ /dev/null
@@ -1,276 +0,0 @@
-#
-# Pyrex - Builtin Definitions
-#
-
-from Symtab import BuiltinScope
-from TypeSlots import Signature
-from PyrexTypes import py_type_type, c_size_t_type, c_py_ssize_t_type
-
-builtin_constant_table = [
- # name, type/ctype, C API name
- ("buffer", "t", "(&PyBuffer_Type)"),
- ("enumerate", "t", "(&PyEnum_Type)"),
- ("file", "t", "(&PyFile_Type)"),
- ("float", "t", "(&PyFloat_Type)"),
- ("int", "t", "(&PyInt_Type)"),
- ("long", "t", "(&PyLong_Type)"),
- ("open", "t", "(&PyFile_Type)"),
- ("property", "t", "(&PyProperty_Type)"),
- ("str", "t", "(&PyString_Type)"),
- ("tuple", "t", "(&PyTuple_Type)"),
- ("xrange", "t", "(&PyRange_Type)"),
-
- ("True", "O", "Py_True"),
- ("False", "O", "Py_False"),
- ("Ellipsis", "O", "Py_Ellipsis"),
-
- ("Exception", "t/O", "PyExc_Exception"),
- ("StopIteration", "t/O", "PyExc_StopIteration"),
- ("StandardError", "t/O", "PyExc_StandardError"),
- ("ArithmeticError", "t/O", "PyExc_ArithmeticError"),
- ("LookupError", "t/O", "PyExc_LookupError"),
-
- ("AssertionError", "t/O", "PyExc_AssertionError"),
- ("EOFError", "t/O", "PyExc_EOFError"),
- ("FloatingPointError", "t/O", "PyExc_FloatingPointError"),
- ("EnvironmentError", "t/O", "PyExc_EnvironmentError"),
- ("IOError", "t/O", "PyExc_IOError"),
- ("OSError", "t/O", "PyExc_OSError"),
- ("ImportError", "t/O", "PyExc_ImportError"),
- ("IndexError", "t/O", "PyExc_IndexError"),
- ("KeyError", "t/O", "PyExc_KeyError"),
- ("KeyboardInterrupt", "t/O", "PyExc_KeyboardInterrupt"),
- ("MemoryError", "t/O", "PyExc_MemoryError"),
- ("NameError", "t/O", "PyExc_NameError"),
- ("OverflowError", "t/O", "PyExc_OverflowError"),
- ("RuntimeError", "t/O", "PyExc_RuntimeError"),
- ("NotImplementedError", "t/O", "PyExc_NotImplementedError"),
- ("SyntaxError", "t/O", "PyExc_SyntaxError"),
- ("IndentationError", "t/O", "PyExc_IndentationError"),
- ("TabError", "t/O", "PyExc_TabError"),
- ("ReferenceError", "t/O", "PyExc_ReferenceError"),
- ("SystemError", "t/O", "PyExc_SystemError"),
- ("SystemExit", "t/O", "PyExc_SystemExit"),
- ("TypeError", "t/O", "PyExc_TypeError"),
- ("UnboundLocalError", "t/O", "PyExc_UnboundLocalError"),
- ("UnicodeError", "t/O", "PyExc_UnicodeError"),
- ("UnicodeEncodeError", "t/O", "PyExc_UnicodeEncodeError"),
- ("UnicodeDecodeError", "t/O", "PyExc_UnicodeDecodeError"),
- ("UnicodeTranslateError", "t/O", "PyExc_UnicodeTranslateError"),
- ("ValueError", "t/O", "PyExc_ValueError"),
- ("ZeroDivisionError", "t/O", "PyExc_ZeroDivisionError"),
- # Not including these by default because they are platform-specific
- #("WindowsError", "t/O", "PyExc_WindowsError"),
- #("VMSError", "t/O", "PyExc_VMSError"),
-
- ("MemoryErrorInst", "t/O", "PyExc_MemoryErrorInst"),
-
- ("Warning", "t/O", "PyExc_Warning"),
- ("UserWarning", "t/O", "PyExc_UserWarning"),
- ("DeprecationWarning", "t/O", "PyExc_DeprecationWarning"),
- ("PendingDeprecationWarning", "t/O", "PyExc_PendingDeprecationWarning"),
- ("SyntaxWarning", "t/O", "PyExc_SyntaxWarning"),
- ("OverflowWarning", "t/O", "PyExc_OverflowWarning"),
- ("RuntimeWarning", "t/O", "PyExc_RuntimeWarning"),
- ("FutureWarning", "t/O", "PyExc_FutureWarning"),
-
-]
-
-builtin_function_table = [
- # name, args, return, C API func, py equiv = "*"
- ('abs', "O", "O", "PyNumber_Absolute"),
- ('bool', "O", "i", "PyObject_IsTrue"),
- #('chr', "", "", ""),
- #('cmp', "", "", "", ""), # int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
- #('compile', "", "", ""), # PyObject* Py_CompileString( char *str, char *filename, int start)
- ('delattr', "OO", "r", "PyObject_DelAttr"),
- ('dir', "O", "O", "PyObject_Dir"),
- ('divmod', "OO", "O", "PyNumber_Divmod"),
- #('eval', "", "", ""),
- #('execfile', "", "", ""),
- #('filter', "", "", ""),
- ('getattr', "OO", "O", "PyObject_GetAttr"),
- ('getattr3', "OOO", "O", "__Pyx_GetAttr3", "getattr"),
- ('hasattr', "OO", "i", "PyObject_HasAttr"),
- ('hash', "O", "l", "PyObject_Hash"),
- #('hex', "", "", ""),
- #('id', "", "", ""),
- #('input', "", "", ""),
- ('cintern', "s", "O", "PyString_InternFromString"), # different name because doesn't handle null bytes
- ('isinstance', "OO", "i", "PyObject_IsInstance"),
- ('issubclass', "OO", "i", "PyObject_IsSubclass"),
- ('iter', "O", "O", "PyObject_GetIter"),
- ('iter2', "OO", "O", "PyCallIter_New"),
- ('len', "O", "Z", "PyObject_Length"),
- #('map', "", "", ""),
- #('max', "", "", ""),
- #('min', "", "", ""),
- #('oct', "", "", ""),
- # Not worth doing open, when second argument would become mandatory
- #('open', "ss", "O", "PyFile_FromString"),
- #('ord', "", "", ""),
- ('pow', "OOO", "O", "PyNumber_Power"),
- #('range', "", "", ""),
- #('raw_input', "", "", ""),
- #('reduce', "", "", ""),
- ('reload', "O", "O", "PyImport_ReloadModule"),
- ('repr', "O", "O", "PyObject_Repr"),
- #('round', "", "", ""),
- ('setattr', "OOO", "r", "PyObject_SetAttr"),
- #('sum', "", "", ""),
- #('unichr', "", "", ""),
- #('unicode', "", "", ""),
- #('vars', "", "", ""),
- #('zip', "", "", ""),
- ('typecheck', "Ot", "b", "PyObject_TypeCheck", False),
- ('issubtype', "tt", "b", "PyType_IsSubtype", False),
-]
-
-dict_methods = [
- # name, args, return, C API func
- ("clear", "O", "v", "PyDict_Clear"),
- ("copy", "O", "O", "PyDict_Copy"),
- ("items", "O", "O", "PyDict_Items"),
- ("keys", "O", "O", "PyDict_Keys"),
- ("values", "O", "O", "PyDict_Values"),
- ("merge", "OOi", "r", "PyDict_Merge"),
- ("update", "OO", "r", "PyDict_Update"),
- ("merge_pairs", "OOi", "r", "PyDict_MergeFromSeq2"),
-]
-
-list_methods = [
- # name, args, return, C API func
- ("insert", "OiO", "r", "PyList_Insert"),
- ("append", "OO", "r", "PyList_Append"),
- ("iappend", "OO", "i", "PyList_Append"),
- ("sort", "O", "r", "PyList_Sort"),
- ("reverse", "O", "r", "PyList_Reverse"),
- ("as_tuple", "O", "O", "PyList_AsTuple"),
-]
-
-slice_methods = [
- # name, args, return, C API func
- ("indices", "O", "O", "PySlice_Indices"),
-]
-
-slice_members = [
- # name, type
- ("start", "O"),
- ("stop", "O"),
- ("step", "O"),
-]
-
-builtin_c_type_table = [
- ("size_t", c_size_t_type),
- ("Py_ssize_t", c_py_ssize_t_type),
-]
-
-builtin_type_table = [
- # name, objstruct, typeobj, methods, members, flags
-# bool - function
-# buffer - constant
-# classmethod
- ("dict", "PyDictObject", "PyDict_Type", dict_methods),
-# enumerate - constant
-# file - constant
-# float - constant
-# int - constant
- ("list", "PyListObject", "PyList_Type", list_methods, [], ['is_sequence']),
-# long - constant
-# object
-# property - constant
- ("slice", "PySliceObject", "PySlice_Type", slice_methods, slice_members),
-# staticmethod
-# super
-# str - constant
-# tuple - constant
- ("type", "PyTypeObject", "PyType_Type", []),
-# xrange - constant
-]
-
-getattr3_utility_code = ["""
-static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
-""","""
-static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
- PyObject *r = PyObject_GetAttr(o, n);
- if (!r) {
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))
- goto bad;
- PyErr_Clear();
- r = d;
- Py_INCREF(d);
- }
- return r;
-bad:
- return 0;
-}
-"""]
-
-builtin_utility_code = {
- 'getattr3': getattr3_utility_code,
-}
-
-builtin_scope = BuiltinScope()
-
-def type_and_ctype(typecode, c_typecode = None):
- type = Signature.format_map[typecode]
- if c_typecode:
- ctype = Signature.format_map[c_typecode]
- else:
- ctype = None
- return type, ctype
-
-def declare_builtin_constant(name, typecode, cname):
- type, ctype = type_and_ctype(*typecode.split("/"))
- builtin_scope.declare_builtin_constant(name, type, cname, ctype)
-
-def declare_builtin_func(name, args, ret, cname, py_equiv = "*"):
- sig = Signature(args, ret)
- type = sig.function_type()
- utility = builtin_utility_code.get(name)
- builtin_scope.declare_builtin_cfunction(name, type, cname, py_equiv, utility)
-
-def declare_builtin_method(self_type, name, args, ret, cname):
- sig = Signature(args, ret)
- meth_type = sig.function_type(self_type)
- self_type.scope.declare_builtin_method(name, meth_type, cname)
-
-def declare_builtin_member(self_type, name, typecode, cname = None):
- member_type = Signature.format_map[typecode]
- self_type.scope.declare_builtin_var(name, member_type, cname)
-
-def declare_builtin_c_type(name, type):
- builtin_scope.declare_builtin_c_type(name, type)
-
-def declare_builtin_type(name, objstruct, typeobj, methods, members = [],
- flags = []):
- entry = builtin_scope.declare_builtin_class(name, objstruct, typeobj)
- type = entry.type
- for desc in methods:
- declare_builtin_method(type, *desc)
- for desc in members:
- declare_builtin_member(type, *desc)
- for flag in flags:
- setattr(type, flag, 1)
-
-def init_builtin_constants():
- for desc in builtin_constant_table:
- declare_builtin_constant(*desc)
-
-def init_builtin_funcs():
- for desc in builtin_function_table:
- declare_builtin_func(*desc)
-
-def init_builtin_types():
- for desc in builtin_c_type_table:
- declare_builtin_c_type(*desc)
- for desc in builtin_type_table:
- declare_builtin_type(*desc)
- py_type_type.define(builtin_scope.find_type("type"))
-
-def init_builtins():
- init_builtin_constants()
- init_builtin_funcs()
- init_builtin_types()
-
-init_builtins()
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py
deleted file mode 100644
index bf546d6e..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# Pyrex - Command Line Parsing
-#
-
-import sys
-from Filenames import pyx_suffixes
-from Pyrex.Utils import has_suffix
-
-usage = """\
-Usage: pyrexc [options] sourcefile...
-Options:
- -v, --version Display version number of pyrex compiler
- -l, --create-listing Write error messages to a listing file
- -I, --include-dir <directory> Search for include files in named directory
- -o, --output-file <filename> Specify name of generated C file
- -r, --recursive Recursively find and compile dependencies
- -t, --timestamps Only compile newer source files (implied with -r)
- -f, --force Compile all source files (overrides implied -t)
- -q, --quiet Don't print module names in recursive mode
-The following experimental options are supported only on MacOSX:
- -C, --compile Compile generated .c file to .o file
- -X, --link Link .o file to produce extension module (implies -C)
- -+, --cplus Use C++ compiler for compiling and linking
- Additional .o files to link may be supplied when using -X."""
-
-def bad_usage():
- print >>sys.stderr, usage
- sys.exit(1)
-
-def parse_command_line(args):
- from Pyrex.Compiler.Main import \
- CompilationOptions, default_options
-
- def pop_arg():
- if args:
- return args.pop(0)
- else:
- bad_usage()
-
- def get_param(option):
- tail = option[2:]
- if tail:
- return tail
- else:
- return pop_arg()
-
- options = CompilationOptions(default_options)
- sources = []
- while args:
- if args[0].startswith("-"):
- option = pop_arg()
- if option in ("-v", "--version"):
- options.show_version = 1
- elif option in ("-l", "--create-listing"):
- options.use_listing_file = 1
- elif option in ("-C", "--compile"):
- options.c_only = 0
- elif option in ("-X", "--link"):
- options.c_only = 0
- options.obj_only = 0
- elif option in ("-+", "--cplus"):
- options.cplus = 1
- elif option.startswith("-I"):
- options.include_path.append(get_param(option))
- elif option == "--include-dir":
- options.include_path.append(pop_arg())
- elif option in ("-o", "--output-file"):
- options.output_file = pop_arg()
- elif option in ("-r", "--recursive"):
- options.recursive = 1
- elif option in ("-t", "--timestamps"):
- options.timestamps = 1
- elif option in ("-f", "--force"):
- options.timestamps = 0
- else:
- bad_usage()
- else:
- arg = pop_arg()
- if has_suffix(arg, pyx_suffixes):
- sources.append(arg)
- elif arg.endswith(".o"):
- options.objects.append(arg)
- else:
- print >>sys.stderr, \
- "pyrexc: %s: Unknown filename suffix" % arg
- if options.objects and len(sources) > 1:
- print >>sys.stderr, \
- "pyrexc: Only one source file allowed together with .o files"
- if options.use_listing_file and len(sources) > 1:
- print >>sys.stderr, \
- "pyrexc: Only one source file allowed when using -o"
- sys.exit(1)
- return options, sources
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
deleted file mode 100644
index a47692bb..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
+++ /dev/null
@@ -1,546 +0,0 @@
-##########################################################################
-#
-# Pyrex - Code output module
-#
-##########################################################################
-
-import os, re
-import Naming
-from Pyrex.Utils import open_new_file
-from PyrexTypes import py_object_type, c_char_array_type, typecast
-
-identifier_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*$")
-max_intern_length = 30
-
-class CCodeWriter:
- # f file output file
- # level int indentation level
- # bol bool beginning of line?
- # marker string comment to emit before next line
-
- def __init__(self, f):
- #self.f = open_new_file(outfile_name)
- self.f = f
- self.level = 0
- self.bol = 1
- self.marker = None
-
- def putln(self, code = ""):
- if self.marker and self.bol:
- self.emit_marker()
- if code:
- self.put(code)
- self.f.write("\n");
- self.bol = 1
-
- def emit_marker(self):
- self.f.write("\n");
- self.indent()
- self.f.write("/* %s */\n" % self.marker)
- self.marker = None
-
- def put(self, code):
- dl = code.count("{") - code.count("}")
- if dl < 0:
- self.level += dl
- if self.bol:
- self.indent()
- self.f.write(code)
- self.bol = 0
- if dl > 0:
- self.level += dl
-
- def increase_indent(self):
- self.level = self.level + 1
-
- def decrease_indent(self):
- self.level = self.level - 1
-
- def begin_block(self):
- self.putln("{")
- self.increase_indent()
-
- def end_block(self):
- self.decrease_indent()
- self.putln("}")
-
- def indent(self):
- self.f.write(" " * self.level)
-
- def mark_pos(self, pos):
- file, line, col = pos
- self.marker = '"%s":%s' % (file, line)
-
- def put_var_declarations(self, entries, static = 0, dll_linkage = None,
- definition = True):
- for entry in entries:
- if not entry.in_cinclude:
- self.put_var_declaration(entry, static, dll_linkage, definition)
-
- def put_var_declaration(self, entry, static = 0, dll_linkage = None,
- definition = True):
- #print "Code.put_var_declaration:", entry.name, repr(entry.type) ###
- visibility = entry.visibility
- if visibility == 'private' and not definition:
- #print "...private and not definition, skipping" ###
- return
- if not entry.used and visibility == "private":
- #print "not used and private, skipping" ###
- return
- storage_class = ""
- if visibility == 'extern':
- storage_class = Naming.extern_c_macro
- elif visibility == 'public':
- if not definition:
- storage_class = Naming.extern_c_macro
- elif visibility == 'private':
- if static:
- storage_class = "static"
- if storage_class:
- self.put("%s " % storage_class)
- if visibility <> 'public':
- dll_linkage = None
- self.put(entry.type.declaration_code(entry.cname,
- dll_linkage = dll_linkage))
- if entry.init is not None:
- self.put(" = %s" % entry.type.literal_code(entry.init))
- self.putln(";")
-
- def entry_as_pyobject(self, entry):
- type = entry.type
- if (not entry.is_self_arg and not entry.type.is_complete()) \
- or (entry.type.is_extension_type and entry.type.base_type):
- return "(PyObject *)" + entry.cname
- else:
- return entry.cname
-
- def as_pyobject(self, cname, type):
- if type:
- return typecast(py_object_type, type, cname)
- else:
- return cname
-
- def put_incref(self, cname, type = None):
- self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
-
- def put_decref(self, cname, type = None):
- self.putln("Py_DECREF(%s);" % self.as_pyobject(cname, type))
-
- def put_var_incref(self, entry):
- if entry.type.is_pyobject:
- self.putln("Py_INCREF(%s);" % self.entry_as_pyobject(entry))
-
- def put_decref_clear(self, cname, type = None):
- self.putln("Py_DECREF(%s); %s = 0;" % (
- self.as_pyobject(cname, type), cname)) # What was wrong with this?
- #typecast(py_object_type, type, cname), cname))
-
- def put_xdecref(self, cname, type):
- self.putln("Py_XDECREF(%s);" % self.as_pyobject(cname, type))
-
- def put_xdecref_clear(self, cname, type):
- self.putln("Py_XDECREF(%s); %s = 0;" % (
- self.as_pyobject(cname, type), cname))
-
- def put_var_decref(self, entry):
- if entry.type.is_pyobject:
- self.putln("Py_DECREF(%s);" % self.entry_as_pyobject(entry))
-
- def put_var_decref_clear(self, entry):
- if entry.type.is_pyobject:
- self.putln("Py_DECREF(%s); %s = 0;" % (
- self.entry_as_pyobject(entry), entry.cname))
-
- def put_var_xdecref(self, entry):
- if entry.type.is_pyobject:
- self.putln("Py_XDECREF(%s);" % self.entry_as_pyobject(entry))
-
- def put_var_xdecref_clear(self, entry):
- if entry.type.is_pyobject:
- self.putln("Py_XDECREF(%s); %s = 0;" % (
- self.entry_as_pyobject(entry), entry.cname))
-
- def put_var_decrefs(self, entries, used_only = 0):
- for entry in entries:
- if not used_only or entry.used:
- if entry.xdecref_cleanup:
- self.put_var_xdecref(entry)
- else:
- self.put_var_decref(entry)
-
- def put_var_xdecrefs(self, entries):
- for entry in entries:
- self.put_var_xdecref(entry)
-
- def put_var_xdecrefs_clear(self, entries):
- for entry in entries:
- self.put_var_xdecref_clear(entry)
-
- def put_init_to_py_none(self, cname, type):
- py_none = typecast(type, py_object_type, "Py_None")
- self.putln("%s = %s; Py_INCREF(Py_None);" % (cname, py_none))
-
- def put_init_var_to_py_none(self, entry, template = "%s"):
- code = template % entry.cname
- self.put_init_to_py_none(code, entry.type)
-
- def put_pymethoddef(self, entry, term):
- if entry.doc:
- doc_code = entry.doc_cname
- else:
- doc_code = 0
- self.putln(
- '{"%s", (PyCFunction)%s, METH_VARARGS|METH_KEYWORDS, %s}%s' % (
- entry.name,
- entry.func_cname,
- doc_code,
- term))
-
- def put_h_guard(self, guard):
- self.putln("#ifndef %s" % guard)
- self.putln("#define %s" % guard)
-
-#--------------------------------------------------------------------------
-
-class MainCCodeWriter(CCodeWriter):
- # Code writer for executable C code.
- #
- # global_state GlobalCodeState module-wide state
- # return_label string function return point label
- # error_label string error catch point label
- # continue_label string loop continue point label
- # break_label string loop break point label
- # label_counter integer counter for naming labels
- # in_try_finally boolean inside try of try...finally
- # exc_vars (string * 3) exception vars for reraise, or None
-
- in_try_finally = 0
-
- def __init__(self, f, base = None):
- CCodeWriter.__init__(self, f)
- if base:
- self.global_state = base.global_state
- else:
- self.global_state = GlobalCodeState()
- self.label_counter = 1
- self.error_label = None
- self.exc_vars = None
-
- def init_labels(self):
- self.label_counter = 0
- self.labels_used = {}
- self.return_label = self.new_label()
- self.new_error_label()
- self.continue_label = None
- self.break_label = None
-
- def new_label(self):
- n = self.label_counter
- self.label_counter = n + 1
- return "%s%d" % (Naming.label_prefix, n)
-
- def new_error_label(self):
- old_err_lbl = self.error_label
- self.error_label = self.new_label()
- return old_err_lbl
-
- def get_loop_labels(self):
- return (
- self.continue_label,
- self.break_label)
-
- def set_loop_labels(self, labels):
- (self.continue_label,
- self.break_label) = labels
-
- def new_loop_labels(self):
- old_labels = self.get_loop_labels()
- self.set_loop_labels(
- (self.new_label(),
- self.new_label()))
- return old_labels
-
- def get_all_labels(self):
- return (
- self.continue_label,
- self.break_label,
- self.return_label,
- self.error_label)
-
- def set_all_labels(self, labels):
- (self.continue_label,
- self.break_label,
- self.return_label,
- self.error_label) = labels
-
- def all_new_labels(self):
- old_labels = self.get_all_labels()
- new_labels = []
- for old_label in old_labels:
- if old_label:
- new_labels.append(self.new_label())
- else:
- new_labels.append(old_label)
- self.set_all_labels(new_labels)
- return old_labels
-
- def use_label(self, lbl):
- self.labels_used[lbl] = 1
-
- def put_label(self, lbl):
- if lbl in self.labels_used:
- self.putln("%s:;" % lbl)
-
- def put_goto(self, lbl):
- self.use_label(lbl)
- self.putln("goto %s;" % lbl)
-
- def error_goto(self, pos):
- lbl = self.error_label
- self.use_label(lbl)
- return "{%s; goto %s;}" % (
- self.error_setup(pos),
- lbl)
-
- def error_setup(self, pos):
- return "%s = %s[%s]; %s = %s" % (
- Naming.filename_cname,
- Naming.filetable_cname,
- self.lookup_filename(pos[0]),
- Naming.lineno_cname,
- pos[1])
-
- def lookup_filename(self, filename):
- return self.global_state.lookup_filename(filename)
-
- def use_utility_code(self, uc):
- self.global_state.use_utility_code(uc)
-
- def get_string_const(self, text):
- # Get C name for a string constant, adding a new one
- # if necessary.
- return self.global_state.get_string_const(text).cname
-
- def new_const(self, type):
- # Get C name for a new precalculated value.
- return self.global_state.new_const(type).cname
-
- def get_py_string_const(self, text):
- # Get C name for a Python string constant, adding a new one
- # if necessary. If the string is name-like, it will be interned.
- return self.global_state.get_py_string_const(text).cname
-
- def intern(self, name):
- return self.get_py_string_const(name)
-
-#--------------------------------------------------------------------------
-
-class StringConst:
- # Info held by GlobalCodeState about a string constant.
- #
- # cname string
- # text string
- # py_const Const Corresponding Python string
-
- py_const = None
-
- def __init__(self, cname, text):
- self.cname = cname
- self.text = text
-
-#--------------------------------------------------------------------------
-
-class Const:
- # Info held by GlobalCodeState about a precalculated value.
- #
- # cname string
- # type PyrexType
- # intern boolean for Python strings
-
- intern = 0
-
- def __init__(self, cname, type):
- self.cname = cname
- self.type = type
-
-#--------------------------------------------------------------------------
-
-class GlobalCodeState:
- # State pertaining to code generation for a whole module.
- #
- # filename_table {string : int} for finding filename table indexes
- # filename_list [string] filenames in filename table order
- # utility_code {int : int} id to utility_list index
- # utility_list list utility code used
- # const_counter int for generating const names
- # string_index {string : String} string constant index
- # string_consts [StringConst] all string constants
- # other_consts [Const] other precalculated values
-
- def __init__(self):
- self.filename_table = {}
- self.filename_list = []
- self.utility_code = {}
- self.utility_list = []
- self.const_counter = 1
- self.string_index = {}
- self.string_consts = []
- self.other_consts = []
-
- def lookup_filename(self, filename):
- try:
- index = self.filename_table[filename]
- except KeyError:
- index = len(self.filename_list)
- self.filename_list.append(filename)
- self.filename_table[filename] = index
- return index
-
- def generate_filename_table(self, code):
- code.putln("")
- code.putln("static char *%s[] = {" % Naming.filenames_cname)
- if self.filename_list:
- for filename in self.filename_list:
- filename = os.path.basename(filename)
- escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
- code.putln('"%s",' %
- escaped_filename)
- else:
- # Some C compilers don't like an empty array
- code.putln("0")
- code.putln("};")
-
- def use_utility_code(self, uc):
- i = id(uc)
- if i not in self.utility_code:
- self.utility_code[i] = len(self.utility_list)
- self.utility_list.append(uc)
-
- def generate_utility_functions(self, code):
- code.putln("")
- code.putln("/* Runtime support code */")
- code.putln("")
- code.putln("static void %s(void) {" % Naming.fileinit_cname)
- code.putln("%s = %s;" %
- (Naming.filetable_cname, Naming.filenames_cname))
- code.putln("}")
- for utility_code in self.utility_list:
- code.h.put(utility_code[0])
- code.put(utility_code[1])
-
- def new_const_name(self):
- # Create a new globally-unique name for a constant.
- name = "%s%s" % (Naming.const_prefix, self.const_counter)
- self.const_counter += 1
- return name
-
- def new_string_const(self, text):
- # Add a new C string constant.
- c = StringConst(self.new_const_name(), text)
- self.string_consts.append(c)
- self.string_index[text] = c
- return c
-
- def new_const(self, type, cname = None):
- if not cname:
- cname = self.new_const_name()
- c = Const(cname, type)
- self.other_consts.append(c)
- return c
-
- def new_py_const(self, cname = None, intern = 0):
- # Add a new Python constant.
- c = self.new_const(py_object_type, cname)
- if intern:
- c.intern = 1
- return c
-
- def get_string_const(self, text):
- # Get a C string constant, adding a new one if necessary.
- c = self.string_index.get(text)
- if not c:
- c = self.new_string_const(text)
- return c
-
- def get_py_string_const(self, text):
- # Get a Python string constant, adding a new one if necessary.
- # If the string is name-like, it will be interned.
- s = self.get_string_const(text)
- if not s.py_const:
- intern = len(text) <= max_intern_length and identifier_pattern.match(text)
- if intern:
- cname = Naming.interned_prefix + text
- else:
- cname = s.cname + "p"
- s.py_const = self.new_py_const(cname, intern)
- return s.py_const
-
- def generate_const_declarations(self, code):
- self.generate_string_const_declarations(code)
- self.generate_other_const_declarations(code)
- self.generate_stringtab(code)
-
- def generate_string_const_declarations(self, code):
- code.putln("")
- for c in self.string_consts:
- code.putln('static char %s[] = "%s";' % (c.cname, c.text))
-
- def generate_other_const_declarations(self, code):
- interned = []
- uninterned = []
- for c in self.other_consts:
- if c.intern:
- interned.append(c)
- else:
- uninterned.append(c)
- interned.sort(lambda c1, c2: cmp(c1.cname, c2.cname))
- def put_consts(consts):
- code.putln("")
- for c in consts:
- decl = c.type.declaration_code(c.cname)
- code.putln("static %s;" % decl)
- put_consts(interned)
- put_consts(uninterned)
-
- def generate_stringtab(self, code):
- interned = []
- uninterned = []
- for s in self.string_consts:
- p = s.py_const
- if p:
- if p.intern:
- interned.append(s)
- else:
- uninterned.append(s)
- interned.sort(lambda c1, c2: cmp(c1.py_const.cname, c2.py_const.cname))
- def put_stringtab(consts, intern):
- for c in consts:
- cname = c.cname
- code.putln("{&%s, %d, %s, sizeof(%s)}," % (
- c.py_const.cname, intern, cname, cname))
- code.putln("")
- code.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
- put_stringtab(interned, 1)
- put_stringtab(uninterned, 0)
- code.putln("{0, 0, 0, 0}")
- code.putln("};")
-
-#--------------------------------------------------------------------------
-
-class PyrexCodeWriter:
- # f file output file
- # level int indentation level
-
- def __init__(self, outfile_name):
- self.f = open_new_file(outfile_name)
- self.level = 0
-
- def putln(self, code):
- self.f.write("%s%s\n" % (" " * self.level, code))
-
- def indent(self):
- self.level += 1
-
- def dedent(self):
- self.level -= 1
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py
deleted file mode 100644
index e36e0bd2..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py
+++ /dev/null
@@ -1,4 +0,0 @@
-debug_disposal_code = 0
-debug_temp_alloc = 0
-debug_coercion = 0
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py
deleted file mode 100644
index 1eef3a33..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# Pyrex - Errors
-#
-
-import sys
-from Pyrex.Utils import open_new_file
-
-warnings_issued = {}
-
-class PyrexError(EnvironmentError):
- pass
-
-
-class CompileError(PyrexError):
-
- def __init__(self, position = None, message = ""):
- self.position = position
- if position:
- pos_str = "%s:%d:%d: " % position
- else:
- pos_str = ""
- PyrexError.__init__(self, pos_str + message)
-
-
-class InternalError(Exception):
- # If this is ever raised, there is a bug in the compiler.
-
- def __init__(self, message):
- Exception.__init__(self, "Internal compiler error: %s"
- % message)
-
-
-listing_file = None
-num_errors = 0
-echo_file = None
-
-def open_listing_file(path, echo_to_stderr = 1):
- # Begin a new error listing. If path is None, no file
- # is opened, the error counter is just reset.
- global listing_file, num_errors, echo_file
- if path is not None:
- listing_file = open_new_file(path)
- else:
- listing_file = None
- if echo_to_stderr:
- echo_file = sys.stderr
- else:
- echo_file = None
- num_errors = 0
-
-def close_listing_file():
- global listing_file
- if listing_file:
- listing_file.close()
- listing_file = None
-
-def report(position, message):
- err = CompileError(position, message)
- line = "%s\n" % err
- if listing_file:
- listing_file.write(line)
- if echo_file:
- echo_file.write(line)
- return err
-
-def warning(position, message):
- return report(position, "Warning: %s" % message)
-
-def one_time_warning(position, key, message):
- if key not in warnings_issued:
- warnings_issued[key] = 1
- warning(position, message)
-
-def error(position, message):
- global num_errors
- num_errors = num_errors + 1
- return report(position, message)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py
deleted file mode 100644
index c2848286..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py
+++ /dev/null
@@ -1,3954 +0,0 @@
-#
-# Pyrex - Parse tree nodes for expressions
-#
-
-import operator
-from string import join
-
-from Errors import error, InternalError
-import Naming
-from Nodes import Node
-import PyrexTypes
-from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
- CPtrType, CFuncType, COverloadedFuncType
-import Symtab
-import Options
-
-from Pyrex.Debugging import print_call_chain
-from DebugFlags import debug_disposal_code, debug_temp_alloc, \
- debug_coercion
-
-class ExprNode(Node):
- # subexprs [string] Class var holding names of subexpr node attrs
- # type PyrexType Type of the result
- # result_code string Code fragment
- # result_ctype string C type of result_code if different from type
- # inplace_result string Temp var holding in-place operation result
- # is_temp boolean Result is in a temporary variable
- # is_sequence_constructor
- # boolean Is a list or tuple constructor expression
- # saved_subexpr_nodes
- # [ExprNode or [ExprNode or None] or None]
- # Cached result of subexpr_nodes()
-
- result_ctype = None
-
- # The Analyse Expressions phase for expressions is split
- # into two sub-phases:
- #
- # Analyse Types
- # Determines the result type of the expression based
- # on the types of its sub-expressions, and inserts
- # coercion nodes into the expression tree where needed.
- # Marks nodes which will need to have temporary variables
- # allocated.
- #
- # Allocate Temps
- # Allocates temporary variables where needed, and fills
- # in the result_code field of each node.
- #
- # ExprNode provides some convenience routines which
- # perform both of the above phases. These should only
- # be called from statement nodes, and only when no
- # coercion nodes need to be added around the expression
- # being analysed. If coercion is needed, the above two phases
- # should be invoked separately.
- #
- # Framework code in ExprNode provides much of the common
- # processing for the various phases. It makes use of the
- # 'subexprs' class attribute of ExprNodes, which should
- # contain a list of the names of attributes which can
- # hold sub-nodes or sequences of sub-nodes.
- #
- # The framework makes use of a number of abstract methods.
- # Their responsibilities are as follows.
- #
- # Declaration Analysis phase
- #
- # analyse_target_declaration
- # Called during the Analyse Declarations phase to analyse
- # the LHS of an assignment or argument of a del statement.
- # Nodes which cannot be the LHS of an assignment need not
- # implement it.
- #
- # Expression Analysis phase
- #
- # analyse_types
- # - Call analyse_types on all sub-expressions.
- # - Check operand types, and wrap coercion nodes around
- # sub-expressions where needed.
- # - Set the type of this node.
- # - If a temporary variable will be required for the
- # result, set the is_temp flag of this node.
- #
- # analyse_target_types
- # Called during the Analyse Types phase to analyse
- # the LHS of an assignment or argument of a del
- # statement. Similar responsibilities to analyse_types.
- #
- # allocate_temps
- # - Call allocate_temps for all sub-nodes.
- # - Call allocate_temp for this node.
- # - If a temporary was allocated, call release_temp on
- # all sub-expressions.
- #
- # allocate_target_temps
- # - Call allocate_temps on sub-nodes and allocate any other
- # temps used during assignment.
- # - Fill in result_code with a C lvalue if needed.
- # - If a rhs node is supplied, call release_temp on it.
- # - Call release_temp on sub-nodes and release any other
- # temps used during assignment.
- #
- # #calculate_result_code
- # # - Called during the Allocate Temps phase. Should return a
- # # C code fragment evaluating to the result. This is only
- # # called when the result is not a temporary.
- #
- # target_code
- # Called by the default implementation of allocate_target_temps.
- # Should return a C lvalue for assigning to the node. The default
- # implementation calls calculate_result_code.
- #
- # check_const
- # - Check that this node and its subnodes form a
- # legal constant expression. If so, do nothing,
- # otherwise call not_const.
- #
- # The default implementation of check_const
- # assumes that the expression is not constant.
- #
- # check_const_addr
- # - Same as check_const, except check that the
- # expression is a C lvalue whose address is
- # constant. Otherwise, call addr_not_const.
- #
- # The default implementation of calc_const_addr
- # assumes that the expression is not a constant
- # lvalue.
- #
- # Code Generation phase
- #
- # generate_evaluation_code
- # 1. Call generate_evaluation_code for sub-expressions.
- # 2. Generate any C statements necessary to calculate
- # the result of this node from the results of its
- # sub-expressions. If result is not in a temporary, record
- # any information that will be needed by this node's
- # implementation of calculate_result_code().
- # 4. If result is in a temporary, call generate_disposal_code
- # on all sub-expressions.
- #
- # A default implementation of generate_evaluation_code
- # is provided which uses the folling abstract methods:
- # generate_result_code (for no. 2)
- #
- # generate_assignment_code
- # Called on the LHS of an assignment.
- # - Call generate_evaluation_code for sub-expressions.
- # - Generate code to perform the assignment.
- # - If the assignment absorbed a reference, call
- # generate_post_assignment_code on the RHS,
- # otherwise call generate_disposal_code on it.
- #
- # generate_deletion_code
- # Called on an argument of a del statement.
- # - Call generate_evaluation_code for sub-expressions.
- # - Generate code to perform the deletion.
- # - Call generate_disposal_code on all sub-expressions.
- #
- # calculate_result_code
- # Return a C code fragment representing the result of this node.
- # This is only called if the result is not in a temporary.
- #
-
- is_sequence_constructor = 0
- is_attribute = 0
-
- saved_subexpr_nodes = None
- is_temp = 0
-
- def not_implemented(self, method_name):
- print_call_chain(method_name, "not implemented") ###
- raise InternalError(
- "%s.%s not implemented" %
- (self.__class__.__name__, method_name))
-
- def is_lvalue(self):
- return 0
-
- def is_inplace_lvalue(self):
- return 0
-
- def is_ephemeral(self):
- # An ephemeral node is one whose result is in
- # a Python temporary and we suspect there are no
- # other references to it. Certain operations are
- # disallowed on such values, since they are
- # likely to result in a dangling pointer.
- return self.type.is_pyobject and self.is_temp
-
- def subexpr_nodes(self):
- # Extract a list of subexpression nodes based
- # on the contents of the subexprs class attribute.
- if self.saved_subexpr_nodes is None:
- nodes = []
- for name in self.subexprs:
- item = getattr(self, name)
- if item:
- if isinstance(item, ExprNode):
- nodes.append(item)
- else:
- nodes.extend(item)
- self.saved_subexpr_nodes = nodes
- return self.saved_subexpr_nodes
-
- def result(self):
- # Return a C code fragment for the result of this node.
- if self.is_temp:
- result_code = self.result_code
- else:
- result_code = self.calculate_result_code()
- return result_code
-
- def result_as(self, type = None):
- # Return the result code cast to the specified C type.
- return typecast(type, self.ctype(), self.result())
-
- def py_result(self):
- # Return the result code cast to PyObject *.
- return self.result_as(py_object_type)
-
- def ctype(self):
- # Return the native C type of the result.
- return self.result_ctype or self.type
-
- def compile_time_value(self, denv):
- # Return value of compile-time expression, or report error.
- error(self.pos, "Invalid compile-time expression")
-
- def compile_time_value_error(self, e):
- error(self.pos, "Error in compile-time expression: %s: %s" % (
- e.__class__.__name__, e))
-
- # ------------- Declaration Analysis ----------------
-
- def analyse_target_declaration(self, env):
- error(self.pos, "Cannot assign to or delete this")
-
- # ------------- Expression Analysis ----------------
-
- def analyse_const_expression(self, env):
- # Called during the analyse_declarations phase of a
- # constant expression. Analyses the expression's type,
- # checks whether it is a legal const expression,
- # and determines its value.
- self.analyse_types(env)
- self.allocate_temps(env)
- self.check_const()
-
- def analyse_expressions(self, env):
- # Convenience routine performing both the Type
- # Analysis and Temp Allocation phases for a whole
- # expression.
- self.analyse_types(env)
- self.allocate_temps(env)
-
- def analyse_target_expression(self, env, rhs):
- # Convenience routine performing both the Type
- # Analysis and Temp Allocation phases for the LHS of
- # an assignment.
- self.analyse_target_types(env)
- self.allocate_target_temps(env, rhs)
-
- def analyse_boolean_expression(self, env):
- # Analyse expression and coerce to a boolean.
- self.analyse_types(env)
- bool = self.coerce_to_boolean(env)
- bool.allocate_temps(env)
- return bool
-
- def analyse_temp_boolean_expression(self, env):
- # Analyse boolean expression and coerce result into
- # a temporary. This is used when a branch is to be
- # performed on the result and we won't have an
- # opportunity to ensure disposal code is executed
- # afterwards. By forcing the result into a temporary,
- # we ensure that all disposal has been done by the
- # time we get the result.
- self.analyse_types(env)
- bool = self.coerce_to_boolean(env)
- temp_bool = bool.coerce_to_temp(env)
- temp_bool.allocate_temps(env)
- return temp_bool
-
- # --------------- Type Analysis ------------------
-
- def analyse_as_function(self, env):
- # Analyse types for an expression that is to be called.
- self.analyse_types(env)
-
- def analyse_as_module(self, env):
- # If this node can be interpreted as a reference to a
- # cimported module, return its scope, else None.
- return None
-
- def analyse_as_extension_type(self, env):
- # If this node can be interpreted as a reference to an
- # extension type, return its type, else None.
- return None
-
- def analyse_as_cimported_attribute(self, env, *args, **kwds):
- # If this node can be interpreted as a cimported name,
- # finish type analysis and return true, else return false.
- return 0
-
- def analyse_types(self, env):
- self.not_implemented("analyse_types")
-
- def analyse_target_types(self, env):
- self.analyse_types(env)
-
- def analyse_inplace_types(self, env):
- if self.is_inplace_lvalue():
- self.analyse_types(env)
- else:
- error(self.pos, "Invalid target for in-place operation")
- self.type = error_type
-
- def gil_assignment_check(self, env):
- if env.nogil and self.type.is_pyobject:
- error(self.pos, "Assignment of Python object not allowed without gil")
-
- def check_const(self):
- self.not_const()
-
- def not_const(self):
- error(self.pos, "Not allowed in a constant expression")
-
- def check_const_addr(self):
- self.addr_not_const()
-
- def addr_not_const(self):
- error(self.pos, "Address is not constant")
-
- def gil_check(self, env):
- if env.nogil and self.type.is_pyobject:
- self.gil_error()
-
- # ----------------- Result Allocation -----------------
-
- def result_in_temp(self):
- # Return true if result is in a temporary owned by
- # this node or one of its subexpressions. Overridden
- # by certain nodes which can share the result of
- # a subnode.
- return self.is_temp
-
- def allocate_target_temps(self, env, rhs, inplace = 0):
- # Perform temp allocation for the LHS of an assignment.
- if debug_temp_alloc:
- print self, "Allocating target temps"
- self.allocate_subexpr_temps(env)
- #self.result_code = self.target_code()
- if rhs:
- rhs.release_temp(env)
- self.release_subexpr_temps(env)
-
- def allocate_inplace_target_temps(self, env, rhs):
- if debug_temp_alloc:
- print self, "Allocating inplace target temps"
- self.allocate_subexpr_temps(env)
- #self.result_code = self.target_code()
- py_inplace = self.type.is_pyobject
- if py_inplace:
- self.allocate_temp(env)
- self.inplace_result = env.allocate_temp(py_object_type)
- self.release_temp(env)
- rhs.release_temp(env)
- if py_inplace:
- env.release_temp(self.inplace_result)
- self.release_subexpr_temps(env)
-
- def allocate_temps(self, env, result = None):
- # Allocate temporary variables for this node and
- # all its sub-expressions. If a result is specified,
- # this must be a temp node and the specified variable
- # is used as the result instead of allocating a new
- # one.
- if debug_temp_alloc:
- print self, "Allocating temps"
- self.allocate_subexpr_temps(env)
- self.allocate_temp(env, result)
- if self.is_temp:
- self.release_subexpr_temps(env)
-
- def allocate_subexpr_temps(self, env):
- # Allocate temporary variables for all sub-expressions
- # of this node.
- if debug_temp_alloc:
- print self, "Allocating temps for:", self.subexprs
- for node in self.subexpr_nodes():
- if node:
- if debug_temp_alloc:
- print self, "Allocating temps for", node
- node.allocate_temps(env)
-
- def allocate_temp(self, env, result = None):
- # If this node requires a temporary variable for its
- # result, allocate one. If a result is specified,
- # this must be a temp node and the specified variable
- # is used as the result instead of allocating a new
- # one.
- if debug_temp_alloc:
- print self, "Allocating temp"
- if result:
- if not self.is_temp:
- raise InternalError("Result forced on non-temp node")
- self.result_code = result
- elif self.is_temp:
- type = self.type
- if not type.is_void:
- if type.is_pyobject:
- type = PyrexTypes.py_object_type
- self.result_code = env.allocate_temp(type)
- else:
- self.result_code = None
- if debug_temp_alloc:
- print self, "Allocated result", self.result_code
- #else:
- # self.result_code = self.calculate_result_code()
-
- def target_code(self):
- # Return code fragment for use as LHS of a C assignment.
- return self.calculate_result_code()
-
- def calculate_result_code(self):
- self.not_implemented("calculate_result_code")
-
- def release_temp(self, env):
- # If this node owns a temporary result, release it,
- # otherwise release results of its sub-expressions.
- if self.is_temp:
- if debug_temp_alloc:
- print self, "Releasing result", self.result_code
- env.release_temp(self.result_code)
- else:
- self.release_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- # Release the results of all sub-expressions of
- # this node.
- for node in self.subexpr_nodes():
- if node:
- node.release_temp(env)
-
- # ---------------- Code Generation -----------------
-
- def mark_vars_used(self):
- for node in self.subexpr_nodes():
- node.mark_vars_used()
-
- def make_owned_reference(self, code):
- # If result is a pyobject, make sure we own
- # a reference to it.
- if self.type.is_pyobject and not self.result_in_temp():
- code.put_incref(self.py_result())
-
- def generate_evaluation_code(self, code):
- # Generate code to evaluate this node and
- # its sub-expressions, and dispose of any
- # temporary results of its sub-expressions.
- self.generate_subexpr_evaluation_code(code)
- self.generate_result_code(code)
- if self.is_temp:
- self.generate_subexpr_disposal_code(code)
-
- def generate_subexpr_evaluation_code(self, code):
- for node in self.subexpr_nodes():
- node.generate_evaluation_code(code)
-
- def generate_result_code(self, code):
- self.not_implemented("generate_result_code")
-
- inplace_functions = {
- "+=": "PyNumber_InPlaceAdd",
- "-=": "PyNumber_InPlaceSubtract",
- "*=": "PyNumber_InPlaceMultiply",
- "/=": "PyNumber_InPlaceDivide",
- "%=": "PyNumber_InPlaceRemainder",
- "**=": "PyNumber_InPlacePower",
- "<<=": "PyNumber_InPlaceLshift",
- ">>=": "PyNumber_InPlaceRshift",
- "&=": "PyNumber_InPlaceAnd",
- "^=": "PyNumber_InPlaceXor",
- "|=": "PyNumber_InPlaceOr",
- }
-
- def generate_inplace_operation_code(self, operator, rhs, code):
- args = (self.py_result(), rhs.py_result())
- if operator == "**=":
- arg_code = "%s, %s, Py_None" % args
- else:
- arg_code = "%s, %s" % args
- code.putln("%s = %s(%s); if (!%s) %s" % (
- self.inplace_result,
- self.inplace_functions[operator],
- arg_code,
- self.inplace_result,
- code.error_goto(self.pos)))
- if self.is_temp:
- code.put_decref_clear(self.py_result())
- rhs.generate_disposal_code(code)
- if self.type.is_extension_type:
- code.putln(
- "if (!__Pyx_TypeTest(%s, %s)) %s" % (
- self.inplace_result,
- self.type.typeptr_cname,
- code.error_goto(self.pos)))
-
- def generate_disposal_code(self, code):
- # If necessary, generate code to dispose of
- # temporary Python reference.
- if self.is_temp:
- if self.type.is_pyobject:
- code.put_decref_clear(self.py_result(), self.ctype())
- else:
- self.generate_subexpr_disposal_code(code)
-
- def generate_subexpr_disposal_code(self, code):
- # Generate code to dispose of temporary results
- # of all sub-expressions.
- for node in self.subexpr_nodes():
- node.generate_disposal_code(code)
-
- def generate_post_assignment_code(self, code):
- # Same as generate_disposal_code except that
- # assignment will have absorbed a reference to
- # the result if it is a Python object.
- if self.is_temp:
- if self.type.is_pyobject:
- code.putln("%s = 0;" % self.result())
- else:
- self.generate_subexpr_disposal_code(code)
-
- def generate_inplace_result_disposal_code(self, code):
- code.put_decref_clear(self.inplace_result, py_object_type)
-
- def generate_assignment_code(self, rhs, code):
- # Stub method for nodes which are not legal as
- # the LHS of an assignment. An error will have
- # been reported earlier.
- pass
-
- def generate_deletion_code(self, code):
- # Stub method for nodes that are not legal as
- # the argument of a del statement. An error
- # will have been reported earlier.
- pass
-
- # ----------------- Coercion ----------------------
-
- def coerce_to(self, dst_type, env):
- # Coerce the result so that it can be assigned to
- # something of type dst_type. If processing is necessary,
- # wraps this node in a coercion node and returns that.
- # Otherwise, returns this node unchanged.
- #
- # This method is called during the analyse_expressions
- # phase of the src_node's processing.
- src = self
- src_type = self.type
- src_is_py_type = src_type.is_pyobject
- dst_is_py_type = dst_type.is_pyobject
-
- if dst_type.is_pyobject:
- if not src.type.is_pyobject:
- src = CoerceToPyTypeNode(src, env)
- if not src.type.subtype_of(dst_type):
- if not isinstance(src, NoneNode):
- src = PyTypeTestNode(src, dst_type, env)
- elif src.type.is_pyobject:
- src = CoerceFromPyTypeNode(dst_type, src, env)
- else: # neither src nor dst are py types
- if not dst_type.assignable_from(src_type):
- error(self.pos, "Cannot assign type '%s' to '%s'" %
- (src.type, dst_type))
- return src
-
- def coerce_to_pyobject(self, env):
- return self.coerce_to(PyrexTypes.py_object_type, env)
-
- def coerce_to_boolean(self, env):
- # Coerce result to something acceptable as
- # a boolean value.
- type = self.type
- if type.is_pyobject or type.is_ptr or type.is_float:
- return CoerceToBooleanNode(self, env)
- else:
- if not type.is_int and not type.is_error:
- error(self.pos,
- "Type '%s' not acceptable as a boolean" % type)
- return self
-
- def coerce_to_integer(self, env):
- # If not already some C integer type, coerce to longint.
- if self.type.is_int:
- return self
- else:
- return self.coerce_to(PyrexTypes.c_long_type, env)
-
- def coerce_to_temp(self, env):
- # Ensure that the result is in a temporary.
- if self.result_in_temp():
- return self
- else:
- return CoerceToTempNode(self, env)
-
- def coerce_to_simple(self, env):
- # Ensure that the result is simple (see is_simple).
- if self.is_simple():
- return self
- else:
- return self.coerce_to_temp(env)
-
- def is_simple(self):
- # A node is simple if its result is something that can
- # be referred to without performing any operations, e.g.
- # a constant, local var, C global var, struct member
- # reference, or temporary.
- return self.result_in_temp()
-
-
-class AtomicExprNode(ExprNode):
- # Abstract base class for expression nodes which have
- # no sub-expressions.
-
- subexprs = []
-
-
-class PyConstNode(AtomicExprNode):
- # Abstract base class for constant Python values.
-
- def is_simple(self):
- return 1
-
- def analyse_types(self, env):
- self.type = py_object_type
-
- def calculate_result_code(self):
- return self.value
-
- def generate_result_code(self, code):
- pass
-
-
-class NoneNode(PyConstNode):
- # The constant value None
-
- value = "Py_None"
-
- def compile_time_value(self, denv):
- return None
-
-
-class EllipsisNode(PyConstNode):
- # '...' in a subscript list.
-
- value = "Py_Ellipsis"
-
- def compile_time_value(self, denv):
- return Ellipsis
-
-
-class ConstNode(AtomicExprNode):
- # Abstract base type for literal constant nodes.
- #
- # value string C code fragment
-
- is_literal = 1
-
- def is_simple(self):
- return 1
-
- def analyse_types(self, env):
- pass # Types are held in class variables
-
- def check_const(self):
- pass
-
- def calculate_result_code(self):
- return str(self.value)
-
- def generate_result_code(self, code):
- pass
-
-
-class NullNode(ConstNode):
- type = PyrexTypes.c_null_ptr_type
- value = "NULL"
-
-
-class CharNode(ConstNode):
- type = PyrexTypes.c_char_type
-
- def compile_time_value(self, denv):
- return ord(self.value)
-
- def calculate_result_code(self):
- return "'%s'" % self.value
-
-
-class IntNode(ConstNode):
- type = PyrexTypes.c_long_type
-
- def compile_time_value(self, denv):
- return int(self.value, 0)
-
-
-class FloatNode(ConstNode):
- type = PyrexTypes.c_double_type
-
- def compile_time_value(self, denv):
- return float(self.value)
-
- def calculate_result_code(self):
- strval = str(self.value)
- if strval == 'nan':
- return "NAN"
- elif strval == 'inf':
- return "INFINITY"
- elif strval == '-inf':
- return "(-INFINITY)"
- else:
- return strval
-
-
-class StringNode(ConstNode):
- # #entry Symtab.Entry
-
- type = PyrexTypes.c_char_ptr_type
-
- def compile_time_value(self, denv):
- return eval('"%s"' % self.value)
-
-# def analyse_types(self, env):
-# self.entry = env.add_string_const(self.value)
-
- def coerce_to(self, dst_type, env):
- # Arrange for a Python version of the string to be pre-allocated
- # when coercing to a Python type.
- if dst_type.is_pyobject and not self.type.is_pyobject:
- node = self.as_py_string_node(env)
- else:
- node = self
- # We still need to perform normal coerce_to processing on the
- # result, because we might be coercing to an extension type,
- # in which case a type test node will be needed.
- return ConstNode.coerce_to(node, dst_type, env)
-
- def as_py_string_node(self, env):
- # Return a new StringNode with the same value as this node
- # but whose type is a Python type instead of a C type.
- #entry = self.entry
- #env.add_py_string(entry)
- return StringNode(self.pos, type = py_object_type, value = self.value)
-
- def generate_evaluation_code(self, code):
- if self.type.is_pyobject:
- self.result_code = code.get_py_string_const(self.value)
- else:
- self.result_code = code.get_string_const(self.value)
-
- def calculate_result_code(self):
- return self.result_code
-
-
-class LongNode(AtomicExprNode):
- # Python long integer literal
- #
- # value string
-
- def compile_time_value(self, denv):
- return long(self.value)
-
- gil_message = "Constructing Python long int"
-
- def analyse_types(self, env):
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- def generate_evaluation_code(self, code):
- result = self.result()
- code.putln(
- '%s = PyLong_FromString("%s", 0, 0); if (!%s) %s' % (
- self.result(),
- self.value,
- self.result(),
- code.error_goto(self.pos)))
-
-
-class ImagNode(AtomicExprNode):
- # Imaginary number literal
- #
- # value float imaginary part
-
- def compile_time_value(self, denv):
- return complex(0.0, self.value)
-
- gil_message = "Constructing complex number"
-
- def analyse_types(self, env):
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- def generate_evaluation_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyComplex_FromDoubles(0.0, %s); if (!%s) %s" % (
- self.result(),
- self.value,
- self.result(),
- code.error_goto(self.pos)))
-
-
-class NameNode(AtomicExprNode):
- # Reference to a local or global variable name.
- #
- # name string Python name of the variable
- #
- # entry Entry Symbol table entry
- # type_entry Entry For extension type names, the original type entry
- # interned_cname string
-
- is_name = 1
- entry = None
- type_entry = None
-
- def compile_time_value(self, denv):
- try:
- return denv.lookup(self.name)
- except KeyError:
- error(self.pos, "Compile-time name '%s' not defined" % self.name)
-
- def coerce_to(self, dst_type, env):
- # If coercing to a generic pyobject and this is a builtin
- # C function with a Python equivalent, manufacture a NameNode
- # referring to the Python builtin.
- #print "NameNode.coerce_to:", self.name, dst_type ###
- if dst_type is py_object_type:
- entry = self.entry
- if entry.is_cfunction:
- var_entry = entry.as_variable
- if var_entry:
- node = NameNode(self.pos, name = self.name)
- node.entry = var_entry
- node.analyse_rvalue_entry(env)
- return node
- return AtomicExprNode.coerce_to(self, dst_type, env)
-
- def analyse_as_module(self, env):
- # Try to interpret this as a reference to a cimported module.
- # Returns the module scope, or None.
- entry = env.lookup(self.name)
- if entry and entry.as_module:
- return entry.as_module
- return None
-
- def analyse_as_extension_type(self, env):
- # Try to interpret this as a reference to an extension type.
- # Returns the extension type, or None.
- entry = env.lookup(self.name)
- if entry and entry.is_type and entry.type.is_extension_type:
- return entry.type
- else:
- return None
-
- def analyse_target_declaration(self, env):
- self.entry = env.lookup_here(self.name)
- if not self.entry:
- self.entry = env.declare_var(self.name, py_object_type, self.pos)
-
- def analyse_types(self, env):
- self.lookup_entry(env)
- self.analyse_rvalue_entry(env)
-
- def lookup_entry(self, env):
- self.entry = env.lookup(self.name)
- if not self.entry:
- self.entry = env.declare_builtin(self.name, self.pos)
-
- def analyse_target_types(self, env):
- self.analyse_entry(env)
- self.finish_analysing_lvalue()
-
- def analyse_inplace_types(self, env):
- self.analyse_rvalue_entry(env)
- self.finish_analysing_lvalue()
-
- def finish_analysing_lvalue(self):
- if self.entry.is_readonly:
- error(self.pos, "Assignment to read-only name '%s'"
- % self.name)
- elif not self.is_lvalue():
- error(self.pos, "Assignment to non-lvalue '%s'"
- % self.name)
- self.type = PyrexTypes.error_type
- self.entry.used = 1
-
- def analyse_as_function(self, env):
- self.lookup_entry(env)
- if self.entry.is_type:
- self.analyse_constructor_entry(env)
- else:
- self.analyse_rvalue_entry(env)
-
- def analyse_constructor_entry(self, env):
- entry = self.entry
- type = entry.type
- if type.is_struct_or_union:
- self.type = entry.type.cplus_constructor_type
- elif type.is_pyobject:
- self.analyse_rvalue_entry(env)
- else:
- error(self.pos, "Type '%s' not callable as a C++ constructor" % type)
- self.type = error_type
-
- def analyse_rvalue_entry(self, env):
- #print "NameNode.analyse_rvalue_entry:", self.name ###
- #print "Entry:", self.entry.__dict__ ###
- self.analyse_entry(env)
- entry = self.entry
- if entry.is_declared_generic:
- self.result_ctype = py_object_type
- if entry.is_pyglobal or entry.is_builtin:
- self.is_temp = 1
- self.gil_check(env)
-
- gil_message = "Accessing Python global or builtin"
-
- def analyse_entry(self, env):
- #print "NameNode.analyse_entry:", self.name ###
- self.check_identifier_kind()
- entry = self.entry
- type = entry.type
- ctype = entry.ctype
- self.type = type
- if ctype:
- self.result_ctype = ctype
- if entry.is_pyglobal or entry.is_builtin:
- assert type.is_pyobject, "Python global or builtin not a Python object"
- #self.interned_cname = env.intern(self.entry.name)
-
- def check_identifier_kind(self):
- # Check that this is an appropriate kind of name for use in an expression.
- # Also finds the variable entry associated with an extension type.
- entry = self.entry
- if entry.is_type and entry.type.is_extension_type:
- self.type_entry = entry
- if not (entry.is_const or entry.is_variable
- or entry.is_builtin or entry.is_cfunction):
- if self.entry.as_variable:
- self.entry = self.entry.as_variable
- else:
- error(self.pos,
- "'%s' is not a constant, variable or function identifier" % self.name)
-
- def is_simple(self):
- # If it's not a C variable, it'll be in a temp.
- return 1
-
- def calculate_target_results(self, env):
- pass
-
- def check_const(self):
- entry = self.entry
- if not (entry.is_const or entry.is_cfunction):
- self.not_const()
-
- def check_const_addr(self):
- entry = self.entry
- if not (entry.is_cglobal or entry.is_cfunction):
- self.addr_not_const()
-
- def is_lvalue(self):
- entry = self.entry
- return entry.is_variable and \
- not entry.type.is_array and \
- not entry.is_readonly
-
- def is_inplace_lvalue(self):
- return self.is_lvalue()
-
- def is_ephemeral(self):
- # Name nodes are never ephemeral, even if the
- # result is in a temporary.
- return 0
-
- def allocate_temp(self, env, result = None):
- AtomicExprNode.allocate_temp(self, env, result)
- entry = self.entry
- if entry:
- entry.used = 1
-
- def calculate_result_code(self):
- entry = self.entry
- if not entry:
- return "<error>" # There was an error earlier
- return entry.cname
-
- def generate_result_code(self, code):
- assert hasattr(self, 'entry')
- entry = self.entry
- if entry is None:
- return # There was an error earlier
- if entry.utility_code:
- code.use_utility_code(entry.utility_code)
- if entry.is_pyglobal or entry.is_builtin:
- if entry.is_builtin:
- namespace = Naming.builtins_cname
- else: # entry.is_pyglobal
- namespace = entry.namespace_cname
- result = self.result()
- cname = code.intern(self.entry.name)
- code.use_utility_code(get_name_interned_utility_code)
- code.putln(
- '%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
- result,
- namespace,
- cname,
- result,
- code.error_goto(self.pos)))
-
- def generate_setattr_code(self, value_code, code):
- entry = self.entry
- namespace = self.entry.namespace_cname
- cname = code.intern(self.entry.name)
- code.putln(
- 'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
- namespace,
- cname,
- value_code,
- code.error_goto(self.pos)))
-
- def generate_assignment_code(self, rhs, code):
- #print "NameNode.generate_assignment_code:", self.name ###
- entry = self.entry
- if entry is None:
- return # There was an error earlier
- if entry.is_pyglobal:
- self.generate_setattr_code(rhs.py_result(), code)
- if debug_disposal_code:
- print "NameNode.generate_assignment_code:"
- print "...generating disposal code for", rhs
- rhs.generate_disposal_code(code)
- else:
- if self.type.is_pyobject:
- rhs.make_owned_reference(code)
- code.put_decref(self.py_result())
- code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
- if debug_disposal_code:
- print "NameNode.generate_assignment_code:"
- print "...generating post-assignment code for", rhs
- rhs.generate_post_assignment_code(code)
-
- def generate_inplace_assignment_code(self, operator, rhs, code):
- entry = self.entry
- if entry is None:
- return # There was an error earlier
- if self.type.is_pyobject:
- self.generate_result_code(code)
- self.generate_inplace_operation_code(operator, rhs, code)
- if entry.is_pyglobal:
- self.generate_setattr_code(self.inplace_result, code)
- self.generate_inplace_result_disposal_code(code)
- else:
- code.put_decref(self.py_result())
- cast_inplace_result = typecast(self.ctype(), py_object_type, self.inplace_result)
- code.putln('%s = %s;' % (self.result(), cast_inplace_result))
- else:
- code.putln("%s %s %s;" % (self.result(), operator, rhs.result()))
- rhs.generate_disposal_code(code)
-
- def generate_deletion_code(self, code):
- if self.entry is None:
- return # There was an error earlier
- if not self.entry.is_pyglobal:
- error(self.pos, "Deletion of local or C global name not supported")
- return
- cname = code.intern(self.entry.name)
- code.putln(
- 'if (PyObject_DelAttr(%s, %s) < 0) %s' % (
- Naming.module_cname,
- cname,
- code.error_goto(self.pos)))
-
- def mark_vars_used(self):
- if self.entry:
- self.entry.used = 1
-
-
-class BackquoteNode(ExprNode):
- # `expr`
- #
- # arg ExprNode
-
- subexprs = ['arg']
-
- def analyse_types(self, env):
- self.arg.analyse_types(env)
- self.arg = self.arg.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Backquote expression"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyObject_Repr(%s); if (!%s) %s" % (
- self.result(),
- self.arg.py_result(),
- self.result(),
- code.error_goto(self.pos)))
-
-
-class ImportNode(ExprNode):
- # Used as part of import statement implementation.
- # Implements result =
- # __import__(module_name, globals(), None, name_list)
- #
- # module_name StringNode dotted name of module
- # name_list ListNode or None list of names to be imported
-
- subexprs = ['module_name', 'name_list']
-
- def analyse_types(self, env):
- self.module_name.analyse_types(env)
- self.module_name = self.module_name.coerce_to_pyobject(env)
- if self.name_list:
- self.name_list.analyse_types(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-# env.use_utility_code(import_utility_code)
-
- gil_message = "Python import"
-
- def generate_result_code(self, code):
- if self.name_list:
- name_list_code = self.name_list.py_result()
- else:
- name_list_code = "0"
- code.use_utility_code(import_utility_code)
- result = self.result()
- code.putln(
- "%s = __Pyx_Import(%s, %s); if (!%s) %s" % (
- result,
- self.module_name.py_result(),
- name_list_code,
- result,
- code.error_goto(self.pos)))
-
-
-class IteratorNode(ExprNode):
- # Used as part of for statement implementation.
- # Implements result = iter(sequence)
- #
- # sequence ExprNode
-
- subexprs = ['sequence']
-
- def analyse_types(self, env):
- self.sequence.analyse_types(env)
- self.sequence = self.sequence.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Iterating over Python object"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyObject_GetIter(%s); if (!%s) %s" % (
- result,
- self.sequence.py_result(),
- result,
- code.error_goto(self.pos)))
-
-
-class NextNode(AtomicExprNode):
- # Used as part of for statement implementation.
- # Implements result = iterator.next()
- # Created during analyse_types phase.
- # The iterator is not owned by this node.
- #
- # iterator ExprNode
-
- def __init__(self, iterator, env):
- self.pos = iterator.pos
- self.iterator = iterator
- self.type = py_object_type
- self.is_temp = 1
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyIter_Next(%s);" % (
- result,
- self.iterator.py_result()))
- code.putln(
- "if (!%s) {" %
- result)
- code.putln(
- "if (PyErr_Occurred()) %s" %
- code.error_goto(self.pos))
- code.putln(
- "break;")
- code.putln(
- "}")
-
-
-class ExcValueNode(AtomicExprNode):
- # Node created during analyse_types phase
- # of an ExceptClauseNode to fetch the current
- # exception or traceback value.
-
- def __init__(self, pos, env, var):
- ExprNode.__init__(self, pos)
- self.type = py_object_type
- self.var = var
-
- def calculate_result_code(self):
- return self.var
-
- def generate_result_code(self, code):
- pass
-
-
-class TempNode(AtomicExprNode):
- # Node created during analyse_types phase
- # of some nodes to hold a temporary value.
-
- def __init__(self, pos, type, env):
- ExprNode.__init__(self, pos)
- self.type = type
- if type.is_pyobject:
- self.result_ctype = py_object_type
- self.is_temp = 1
-
- def generate_result_code(self, code):
- pass
-
-
-class PyTempNode(TempNode):
- # TempNode holding a Python value.
-
- def __init__(self, pos, env):
- TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
-
-
-#-------------------------------------------------------------------
-#
-# Trailer nodes
-#
-#-------------------------------------------------------------------
-
-class IndexNode(ExprNode):
- # Sequence indexing.
- #
- # base ExprNode
- # index ExprNode
-
- subexprs = ['base', 'index']
-
- def compile_time_value(self, denv):
- base = self.base.compile_time_value(denv)
- index = self.index.compile_time_value(denv)
- try:
- return base[index]
- except Exception, e:
- self.compile_time_value_error(e)
-
- def is_ephemeral(self):
- return self.base.is_ephemeral()
-
- def analyse_target_declaration(self, env):
- pass
-
- def analyse_types(self, env):
- self.analyse_base_and_index_types(env, getting = 1)
-
- def analyse_target_types(self, env):
- self.analyse_base_and_index_types(env, setting = 1)
-
- def analyse_inplace_types(self, env):
- self.analyse_base_and_index_types(env, getting = 1, setting = 1)
-
- def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
- self.base.analyse_types(env)
- self.index.analyse_types(env)
- btype = self.base.type
- if btype.is_pyobject:
- itype = self.index.type
- if not (btype.is_sequence and itype.is_int and itype.signed):
- self.index = self.index.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
- else:
- if self.base.type.is_ptr or self.base.type.is_array:
- self.type = self.base.type.base_type
- else:
- error(self.pos,
- "Attempting to index non-array type '%s'" %
- self.base.type)
- self.type = PyrexTypes.error_type
- if self.index.type.is_pyobject:
- self.index = self.index.coerce_to(
- PyrexTypes.c_py_ssize_t_type, env)
- if not self.index.type.is_int:
- error(self.pos,
- "Invalid index type '%s'" %
- self.index.type)
-
- gil_message = "Indexing Python object"
-
- def check_const_addr(self):
- self.base.check_const_addr()
- self.index.check_const()
-
- def is_lvalue(self):
- return 1
-
- def is_inplace_lvalue(self):
- return 1
-
- def calculate_result_code(self):
- return "(%s[%s])" % (
- self.base.result(), self.index.result())
-
- def generate_result_code(self, code):
- if self.type.is_pyobject:
- itype = self.index.type
- if itype.is_int and itype.signed:
- code.use_utility_code(getitem_int_utility_code)
- function = "__Pyx_GetItemInt"
- index_code = self.index.result()
- else:
- function = "PyObject_GetItem"
- index_code = self.index.py_result()
- result = self.result()
- code.putln(
- "%s = %s(%s, %s); if (!%s) %s" % (
- result,
- function,
- self.base.py_result(),
- index_code,
- result,
- code.error_goto(self.pos)))
-
- def generate_setitem_code(self, value_code, code):
- itype = self.index.type
- if itype.is_int and itype.signed:
- code.use_utility_code(setitem_int_utility_code)
- function = "__Pyx_SetItemInt"
- index_code = self.index.result()
- else:
- function = "PyObject_SetItem"
- index_code = self.index.py_result()
- code.putln(
- "if (%s(%s, %s, %s) < 0) %s" % (
- function,
- self.base.py_result(),
- index_code,
- value_code,
- code.error_goto(self.pos)))
-
- def generate_assignment_code(self, rhs, code):
- self.generate_subexpr_evaluation_code(code)
- if self.type.is_pyobject:
- self.generate_setitem_code(rhs.py_result(), code)
- else:
- code.putln(
- "%s = %s;" % (
- self.result(), rhs.result()))
- self.generate_subexpr_disposal_code(code)
- rhs.generate_disposal_code(code)
-
- def generate_inplace_assignment_code(self, operator, rhs, code):
- self.generate_subexpr_evaluation_code(code)
- if self.type.is_pyobject:
- self.generate_result_code(code)
- self.generate_inplace_operation_code(operator, rhs, code)
- self.generate_setitem_code(self.inplace_result, code)
- self.generate_inplace_result_disposal_code(code)
- else:
- code.putln("%s %s %s;" % (self.result(), operator, rhs.result()))
- rhs.generate_disposal_code(code)
- self.generate_subexpr_disposal_code(code)
-
- def generate_deletion_code(self, code):
- self.generate_subexpr_evaluation_code(code)
- if self.base.type.is_sequence and self.index.type.is_int:
- function = "PySequence_DelItem"
- index_code = self.index.result()
- else:
- function = "PyObject_DelItem"
- index_code = self.index.py_result()
- code.putln(
- "if (%s(%s, %s) < 0) %s" % (
- function,
- self.base.py_result(),
- index_code,
- code.error_goto(self.pos)))
- #else:
- # error(self.pos, "Cannot delete non-Python variable")
- self.generate_subexpr_disposal_code(code)
-
-
-class SliceIndexNode(ExprNode):
- # 2-element slice indexing
- #
- # base ExprNode
- # start ExprNode or None
- # stop ExprNode or None
-
- subexprs = ['base', 'start', 'stop']
-
- def is_inplace_lvalue(self):
- return 1
-
- def compile_time_value(self, denv):
- base = self.base.compile_time_value(denv)
- start = self.start.compile_time_value(denv)
- stop = self.stop.compile_time_value(denv)
- try:
- return base[start:stop]
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_target_declaration(self, env):
- pass
-
- def analyse_types(self, env):
- self.base.analyse_types(env)
- if self.start:
- self.start.analyse_types(env)
- if self.stop:
- self.stop.analyse_types(env)
- self.base = self.base.coerce_to_pyobject(env)
- c_int = PyrexTypes.c_py_ssize_t_type
- if self.start:
- self.start = self.start.coerce_to(c_int, env)
- if self.stop:
- self.stop = self.stop.coerce_to(c_int, env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Slicing Python object"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PySequence_GetSlice(%s, %s, %s); if (!%s) %s" % (
- result,
- self.base.py_result(),
- self.start_code(),
- self.stop_code(),
- result,
- code.error_goto(self.pos)))
-
- def generate_setslice_code(self, value_code, code):
- code.putln(
- "if (PySequence_SetSlice(%s, %s, %s, %s) < 0) %s" % (
- self.base.py_result(),
- self.start_code(),
- self.stop_code(),
- value_code,
- code.error_goto(self.pos)))
-
- def generate_assignment_code(self, rhs, code):
- self.generate_subexpr_evaluation_code(code)
- self.generate_setslice_code(rhs.result(), code)
- self.generate_subexpr_disposal_code(code)
- rhs.generate_disposal_code(code)
-
- def generate_inplace_assignment_code(self, operator, rhs, code):
- self.generate_subexpr_evaluation_code(code)
- self.generate_result_code(code)
- self.generate_inplace_operation_code(operator, rhs, code)
- self.generate_setslice_code(self.inplace_result, code)
- self.generate_inplace_result_disposal_code(code)
- self.generate_subexpr_disposal_code(code)
-
- def generate_deletion_code(self, code):
- self.generate_subexpr_evaluation_code(code)
- code.putln(
- "if (PySequence_DelSlice(%s, %s, %s) < 0) %s" % (
- self.base.py_result(),
- self.start_code(),
- self.stop_code(),
- code.error_goto(self.pos)))
- self.generate_subexpr_disposal_code(code)
-
- def start_code(self):
- if self.start:
- return self.start.result()
- else:
- return "0"
-
- def stop_code(self):
- if self.stop:
- return self.stop.result()
- else:
- return "PY_SSIZE_T_MAX"
-
-# def calculate_result_code(self):
-# # self.result_code is not used, but this method must exist
-# return "<unused>"
-
-
-class SliceNode(ExprNode):
- # start:stop:step in subscript list
- #
- # start ExprNode
- # stop ExprNode
- # step ExprNode
-
- def compile_time_value(self, denv):
- start = self.start.compile_time_value(denv)
- stop = self.stop.compile_time_value(denv)
- step = step.step.compile_time_value(denv)
- try:
- return slice(start, stop, step)
- except Exception, e:
- self.compile_time_value_error(e)
-
- subexprs = ['start', 'stop', 'step']
-
- def analyse_types(self, env):
- self.start.analyse_types(env)
- self.stop.analyse_types(env)
- self.step.analyse_types(env)
- self.start = self.start.coerce_to_pyobject(env)
- self.stop = self.stop.coerce_to_pyobject(env)
- self.step = self.step.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Constructing Python slice object"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PySlice_New(%s, %s, %s); if (!%s) %s" % (
- result,
- self.start.py_result(),
- self.stop.py_result(),
- self.step.py_result(),
- result,
- code.error_goto(self.pos)))
-
-
-class CallNode(ExprNode):
-
- def gil_check(self, env):
- # Make sure we're not in a nogil environment
- if env.nogil:
- error(self.pos, "Calling gil-requiring function without gil")
-
-
-class SimpleCallNode(CallNode):
- # Function call without keyword, * or ** args.
- #
- # function ExprNode
- # args [ExprNode]
- # arg_tuple ExprNode or None used internally
- # self ExprNode or None used internally
- # coerced_self ExprNode or None used internally
- # function_type PyrexType used internally
-
- subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
-
- self = None
- coerced_self = None
- arg_tuple = None
- is_new = False
-
- cplus_argless_constr_type = CFuncType(None, [])
-
- def compile_time_value(self, denv):
- function = self.function.compile_time_value(denv)
- args = [arg.compile_time_value(denv) for arg in self.args]
- try:
- return function(*args)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- #print "SimpleCallNode.analyse_types:", self.pos ###
- function = self.function
- function.is_called = 1
- function.analyse_as_function(env)
- if function.is_name or function.is_attribute:
- #print "SimpleCallNode.analyse_types:", self.pos, "is name or attribute" ###
- func_entry = function.entry
- if func_entry:
- if func_entry.is_cmethod or func_entry.is_builtin_method:
- # Take ownership of the object from which the attribute
- # was obtained, because we need to pass it as 'self'.
- #print "SimpleCallNode: Snarfing self argument" ###
- self.self = function.obj
- function.obj = CloneNode(self.self)
- elif self.is_new:
- if not (func_entry.is_type and func_entry.type.is_struct_or_union
- and func_entry.type.scope.is_cplus):
- error(self.pos, "'new' operator can only be used on a C++ struct type")
- self.type = error_type
- return
- else:
- #print "SimpleCallNode.analyse_types:", self.pos, "not name or attribute" ###
- if self.is_new:
- error(self.pos, "Invalid use of 'new' operator")
- self.type = error_type
- return
- func_type = self.function.type
- if func_type.is_ptr:
- func_type = func_type.base_type
- self.function_type = func_type
- if func_type.is_pyobject:
- #print "SimpleCallNode: Python call" ###
- if self.args:
- self.arg_tuple = TupleNode(self.pos, args = self.args)
- self.arg_tuple.analyse_types(env)
- else:
- self.arg_tuple = None
- self.args = None
- if function.is_name and function.type_entry:
- # We are calling an extension type constructor
- self.type = function.type_entry.type
- self.result_ctype = py_object_type
- else:
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
- else:
- #print "SimpleCallNode: C call" ###
- for arg in self.args:
- arg.analyse_types(env)
- if func_type.is_cfunction:
- self.type = func_type.return_type
- if self.is_new:
- self.type = CPtrType(self.type)
- if func_type.is_overloaded:
- func_type = self.resolve_overloading()
- if not func_type:
- self.type = error_type
- return
- if self.self and func_type.args:
- #print "SimpleCallNode: Inserting self into argument list" ###
- # Coerce 'self' to the type expected by the method.
- expected_type = func_type.args[0].type
- self.coerced_self = CloneNode(self.self).coerce_to(
- expected_type, env)
- # Insert coerced 'self' argument into argument list.
- self.args.insert(0, self.coerced_self)
- self.analyse_c_function_call(env)
-
- def resolve_overloading(self):
- func_type = self.function_type
- arg_types = [arg.type for arg in self.args]
- signatures = func_type.signatures or [self.cplus_argless_constr_type]
- for signature in signatures:
- if signature.callable_with(arg_types):
- signature.return_type = func_type.return_type
- self.function_type = signature
- return signature
- def display_types(types):
- return ", ".join([str(type) for type in types])
- error(self.pos, "No matching signature found for argument types (%s)"
- % display_types(arg_types))
- if signatures:
- error(self.pos, "Candidates are:")
- for signature in signatures:
- error(signature.pos, "(%s)" % display_types(signature.args))
-
- def analyse_c_function_call(self, env):
- func_type = self.function_type
- # Check function type
- if not func_type.is_cfunction:
- if not func_type.is_error:
- error(self.pos, "Calling non-function type '%s'" %
- func_type)
- self.type = PyrexTypes.error_type
- return
- # Check no. of args
- expected_nargs = len(func_type.args)
- actual_nargs = len(self.args)
- if actual_nargs < expected_nargs \
- or (not func_type.has_varargs and actual_nargs > expected_nargs):
- expected_str = str(expected_nargs)
- if func_type.has_varargs:
- expected_str = "at least " + expected_str
- error(self.pos,
- "Call with wrong number of arguments (expected %s, got %s)"
- % (expected_str, actual_nargs))
- self.args = None
- self.type = PyrexTypes.error_type
- return
- # Coerce arguments
- for i in range(expected_nargs):
- formal_type = func_type.args[i].type
- self.args[i] = self.args[i].coerce_to(formal_type, env)
- for i in range(expected_nargs, actual_nargs):
- if self.args[i].type.is_pyobject:
- error(self.args[i].pos,
- "Python object cannot be passed as a varargs parameter")
- # Calc result code fragment
- #print "SimpleCallNode.analyse_c_function_call: self.type =", self.type ###
- if self.type.is_pyobject \
- or func_type.exception_value is not None \
- or func_type.exception_check:
- self.is_temp = 1
- if self.type.is_pyobject:
- self.result_ctype = py_object_type
- # Check gil
- if not func_type.nogil:
- self.gil_check(env)
- if func_type.exception_check and env.nogil:
- self.gil_error("Calling 'except ?' or 'except *' function")
-
- def calculate_result_code(self):
- return self.c_call_code()
-
- def c_call_code(self):
- if self.type.is_error or self.args is None or not self.function_type.is_cfunction:
- return "<error>"
- func_type = self.function_type
- formal_args = func_type.args
- arg_list_code = []
- for (formal_arg, actual_arg) in zip(formal_args, self.args):
- arg_code = actual_arg.result_as(formal_arg.type)
- arg_list_code.append(arg_code)
- for actual_arg in self.args[len(formal_args):]:
- arg_list_code.append(actual_arg.result())
- result = "%s(%s)" % (self.function.result(),
- join(arg_list_code, ","))
- if self.is_new:
- result = "new " + result
- return result
-
- def generate_result_code(self, code):
- if self.type.is_error:
- return
- func_type = self.function_type
- result = self.result()
- if func_type.is_pyobject:
- if self.arg_tuple:
- arg_code = self.arg_tuple.py_result()
- else:
- arg_code = "0"
- code.putln(
- "%s = PyObject_CallObject(%s, %s); if (!%s) %s" % (
- result,
- self.function.py_result(),
- arg_code,
- result,
- code.error_goto(self.pos)))
- elif func_type.is_cfunction:
- exc_checks = []
- if self.type.is_pyobject:
- exc_checks.append("!%s" % result)
- else:
- exc_val = func_type.exception_value
- exc_check = func_type.exception_check
- if exc_val is not None:
- exc_checks.append("%s == %s" % (self.result(), exc_val))
- if exc_check:
- exc_checks.append("PyErr_Occurred()")
- if self.is_temp or exc_checks:
- rhs = self.c_call_code()
- result = self.result()
- if result:
- lhs = "%s = " % result
- if self.is_temp and self.type.is_pyobject:
- #return_type = self.type # func_type.return_type
- #print "SimpleCallNode.generate_result_code: casting", rhs, \
- # "from", return_type, "to pyobject" ###
- rhs = typecast(py_object_type, self.type, rhs)
- else:
- lhs = ""
- code.putln(
- "%s%s; if (%s) %s" % (
- lhs,
- rhs,
- " && ".join(exc_checks),
- code.error_goto(self.pos)))
-
-
-class GeneralCallNode(CallNode):
- # General Python function call, including keyword,
- # * and ** arguments.
- #
- # function ExprNode
- # positional_args ExprNode Tuple of positional arguments
- # keyword_args ExprNode or None Dict of keyword arguments
- # starstar_arg ExprNode or None Dict of extra keyword args
-
- subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
-
- def compile_time_value(self, denv):
- function = self.function.compile_time_value(denv)
- positional_args = self.positional_args.compile_time_value(denv)
- keyword_args = self.keyword_args.compile_time_value(denv)
- starstar_arg = self.starstar_arg.compile_time_value(denv)
- try:
- keyword_args.update(starstar_arg)
- return function(*positional_args, **keyword_args)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- function = self.function
- function.analyse_types(env)
- self.positional_args.analyse_types(env)
- if self.keyword_args:
- self.keyword_args.analyse_types(env)
- if self.starstar_arg:
- self.starstar_arg.analyse_types(env)
- self.function = self.function.coerce_to_pyobject(env)
- self.positional_args = \
- self.positional_args.coerce_to_pyobject(env)
- if self.starstar_arg:
- self.starstar_arg = \
- self.starstar_arg.coerce_to_pyobject(env)
- if function.is_name and function.type_entry:
- # We are calling an extension type constructor
- self.type = function.type_entry.type
- self.result_ctype = py_object_type
- else:
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- def generate_result_code(self, code):
- if self.keyword_args and self.starstar_arg:
- code.putln(
- "if (PyDict_Update(%s, %s) < 0) %s" % (
- self.keyword_args.py_result(),
- self.starstar_arg.py_result(),
- code.error_goto(self.pos)))
- keyword_code = self.keyword_args.py_result()
- elif self.keyword_args:
- keyword_code = self.keyword_args.py_result()
- elif self.starstar_arg:
- keyword_code = self.starstar_arg.py_result()
- else:
- keyword_code = None
- if not keyword_code:
- call_code = "PyObject_CallObject(%s, %s)" % (
- self.function.py_result(),
- self.positional_args.py_result())
- else:
- call_code = "PyEval_CallObjectWithKeywords(%s, %s, %s)" % (
- self.function.py_result(),
- self.positional_args.py_result(),
- keyword_code)
- result = self.result()
- code.putln(
- "%s = %s; if (!%s) %s" % (
- result,
- call_code,
- result,
- code.error_goto(self.pos)))
-
-
-class AsTupleNode(ExprNode):
- # Convert argument to tuple. Used for normalising
- # the * argument of a function call.
- #
- # arg ExprNode
-
- subexprs = ['arg']
-
- def compile_time_value(self, denv):
- arg = self.arg.compile_time_value(denv)
- try:
- return tuple(arg)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- self.arg.analyse_types(env)
- self.arg = self.arg.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Constructing Python tuple"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PySequence_Tuple(%s); if (!%s) %s" % (
- result,
- self.arg.py_result(),
- result,
- code.error_goto(self.pos)))
-
-
-class AttributeNode(ExprNode):
- # obj.attribute
- #
- # obj ExprNode
- # attribute string
- #
- # Used internally:
- #
- # is_py_attr boolean Is a Python getattr operation
- # member string C name of struct member
- # is_called boolean Function call is being done on result
- # entry Entry Symbol table entry of attribute
- # interned_attr_cname string C name of interned attribute name
-
- is_attribute = 1
- subexprs = ['obj']
-
- type = PyrexTypes.error_type
- result_code = "<error>"
- entry = None
- is_called = 0
-
- def compile_time_value(self, denv):
- attr = self.attribute
- if attr.startswith("__") and attr.endswith("__"):
- self.error("Invalid attribute name '%s' in compile-time expression"
- % attr)
- return None
- obj = self.obj.compile_time_value(denv)
- try:
- return getattr(obj, attr)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_target_declaration(self, env):
- pass
-
- def analyse_target_types(self, env):
- self.analyse_types(env, target = 1)
-
- def analyse_as_function(self, env):
- module_scope = self.obj.analyse_as_module(env)
- if module_scope:
- entry = module_scope.lookup_here(self.attribute)
- if entry and entry.is_type:
- self.mutate_into_name_node(entry)
- self.analyse_constructor_entry(env)
- return
- self.analyse_types(env)
-
- def analyse_types(self, env, target = 0):
- if self.analyse_as_cimported_attribute(env, target):
- return
- if not target and self.analyse_as_unbound_cmethod(env):
- return
- self.analyse_as_ordinary_attribute(env, target)
-
- def analyse_as_cimported_attribute(self, env, target = 0, allow_type = 0):
- # Try to interpret this as a reference to an imported
- # C const, type, var or function. If successful, mutates
- # this node into a NameNode and returns 1, otherwise
- # returns 0.
- module_scope = self.obj.analyse_as_module(env)
- if module_scope:
- entry = module_scope.lookup_here(self.attribute)
- if entry and (
- entry.is_cglobal or entry.is_cfunction
- or entry.is_type or entry.is_const):
- self.mutate_into_name_node(entry)
- if entry.is_type and allow_type:
- pass
- elif target:
- self.analyse_target_types(env)
- else:
- self.analyse_rvalue_entry(env)
- return 1
- return 0
-
- def analyse_as_unbound_cmethod(self, env):
- # Try to interpret this as a reference to an unbound
- # C method of an extension type. If successful, mutates
- # this node into a NameNode and returns 1, otherwise
- # returns 0.
- type = self.obj.analyse_as_extension_type(env)
- if type:
- entry = type.scope.lookup_here(self.attribute)
- if entry and entry.is_cmethod:
- # Create a temporary entry describing the C method
- # as an ordinary function.
- ubcm_entry = Symtab.Entry(entry.name,
- "%s->%s" % (type.vtabptr_cname, entry.cname),
- entry.type)
- ubcm_entry.is_cfunction = 1
- ubcm_entry.func_cname = entry.func_cname
- self.mutate_into_name_node(ubcm_entry)
- self.analyse_rvalue_entry(env)
- return 1
- return 0
-
- def analyse_as_extension_type(self, env):
- # Try to interpret this as a reference to an extension type
- # in a cimported module. Returns the extension type, or None.
- module_scope = self.obj.analyse_as_module(env)
- if module_scope:
- entry = module_scope.lookup_here(self.attribute)
- if entry and entry.is_type and entry.type.is_extension_type:
- return entry.type
- return None
-
- def analyse_as_module(self, env):
- # Try to interpret this as a reference to a cimported module
- # in another cimported module. Returns the module scope, or None.
- module_scope = self.obj.analyse_as_module(env)
- if module_scope:
- entry = module_scope.lookup_here(self.attribute)
- if entry and entry.as_module:
- return entry.as_module
- return None
-
- def mutate_into_name_node(self, entry):
- # Turn this node into a NameNode with the given entry.
- self.__class__ = NameNode
- self.name = self.attribute
- self.entry = entry
- del self.obj
- del self.attribute
-
- def analyse_as_ordinary_attribute(self, env, target):
- self.obj.analyse_types(env)
- self.analyse_attribute(env)
- if self.entry and self.entry.is_cmethod and not self.is_called:
- error(self.pos, "C method can only be called")
- if self.is_py_attr:
- if not target:
- self.is_temp = 1
- self.result_ctype = py_object_type
-
- def analyse_attribute(self, env):
- # Look up attribute and set self.type and self.member.
- self.is_py_attr = 0
- self.member = self.attribute
- if self.obj.type.is_string:
- self.obj = self.obj.coerce_to_pyobject(env)
- obj_type = self.obj.type
- if obj_type.is_ptr:
- obj_type = obj_type.base_type
- self.op = "->"
- elif obj_type.is_extension_type:
- self.op = "->"
- else:
- self.op = "."
- if obj_type.has_attributes:
- entry = None
- if obj_type.attributes_known():
- entry = obj_type.scope.lookup_here(self.attribute)
- else:
- error(self.pos,
- "Cannot select attribute of incomplete type '%s'"
- % obj_type)
- obj_type = PyrexTypes.error_type
- self.entry = entry
- if entry:
- if obj_type.is_extension_type and entry.name == "__weakref__":
- error(self.pos, "Illegal use of special attribute __weakref__")
- if entry.is_variable or entry.is_cmethod:
- self.type = entry.type
- self.member = entry.cname
- return
- if entry.is_builtin_method and self.is_called:
- # Mutate into NameNode referring to C function
- #print "AttributeNode: Mutating builtin method into NameNode" ###
- self.type = entry.type
- self.__class__ = NameNode
- return
- else:
- # If it's not a variable or C method, it must be a Python
- # method of an extension type, so we treat it like a Python
- # attribute.
- pass
- # If we get here, the base object is not a struct/union/extension
- # type, or it is an extension type and the attribute is either not
- # declared or is declared as a Python method. Treat it as a Python
- # attribute reference.
- if obj_type.is_pyobject:
- self.type = py_object_type
- self.is_py_attr = 1
- #self.interned_attr_cname = env.intern(self.attribute)
- self.gil_check(env)
- else:
- if not obj_type.is_error:
- error(self.pos,
- "Object of type '%s' has no attribute '%s'" %
- (obj_type, self.attribute))
-
- gil_message = "Accessing Python attribute"
-
- def is_simple(self):
- if self.obj:
- return self.result_in_temp() or self.obj.is_simple()
- else:
- return NameNode.is_simple(self)
-
- def is_lvalue(self):
- if self.obj:
- return 1
- else:
- return NameNode.is_lvalue(self)
-
- def is_inplace_lvalue(self):
- return self.is_lvalue()
-
- def is_ephemeral(self):
- if self.obj:
- return self.obj.is_ephemeral()
- else:
- return NameNode.is_ephemeral(self)
-
- def calculate_result_code(self):
- obj = self.obj
- obj_code = obj.result_as(obj.type)
- if self.entry and self.entry.is_cmethod:
- return "((struct %s *)%s%s%s)->%s" % (
- obj.type.vtabstruct_cname, obj_code, self.op,
- obj.type.vtabslot_cname, self.member)
- else:
- return "%s%s%s" % (obj_code, self.op, self.member)
-
- def generate_result_code(self, code):
- if self.is_py_attr:
- result = self.result()
- cname = code.intern(self.attribute)
- code.putln(
- '%s = PyObject_GetAttr(%s, %s); if (!%s) %s' % (
- result,
- self.obj.py_result(),
- cname,
- result,
- code.error_goto(self.pos)))
-
- def generate_setattr_code(self, value_code, code):
- cname = code.intern(self.attribute)
- code.putln(
- 'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
- self.obj.py_result(),
- cname,
- value_code,
- code.error_goto(self.pos)))
-
- def generate_assignment_code(self, rhs, code):
- self.obj.generate_evaluation_code(code)
- if self.is_py_attr:
- self.generate_setattr_code(rhs.py_result(), code)
- rhs.generate_disposal_code(code)
- else:
- select_code = self.result()
- if self.type.is_pyobject:
- rhs.make_owned_reference(code)
- code.put_decref(select_code, self.ctype())
- code.putln(
- "%s = %s;" % (
- select_code,
- rhs.result_as(self.ctype())))
- rhs.generate_post_assignment_code(code)
- self.obj.generate_disposal_code(code)
-
- def generate_inplace_assignment_code(self, operator, rhs, code):
- self.obj.generate_evaluation_code(code)
- select_code = self.result()
- if self.type.is_pyobject:
- self.generate_result_code(code)
- self.generate_inplace_operation_code(operator, rhs, code)
- if self.is_py_attr:
- self.generate_setattr_code(self.inplace_result, code)
- self.generate_inplace_result_disposal_code(code)
- else:
- code.put_decref(select_code, self.ctype())
- cast_inplace_result = typecast(self.ctype(), py_object_type, self.inplace_result)
- code.putln("%s = %s;" % (select_code, cast_inplace_result))
- else:
- code.putln("%s %s %s;" % (select_code, operator, rhs.result()))
- rhs.generate_disposal_code(code)
- self.obj.generate_disposal_code(code)
-
- def generate_deletion_code(self, code):
- self.obj.generate_evaluation_code(code)
- if self.is_py_attr:
- cname = code.intern(self.attribute)
- code.putln(
- 'if (PyObject_DelAttr(%s, %s) < 0) %s' % (
- self.obj.py_result(),
- cname,
- code.error_goto(self.pos)))
- else:
- error(self.pos, "Cannot delete C attribute of extension type")
- self.obj.generate_disposal_code(code)
-
-#-------------------------------------------------------------------
-#
-# Constructor nodes
-#
-#-------------------------------------------------------------------
-
-class SequenceNode(ExprNode):
- # Base class for list and tuple constructor nodes.
- # Contains common code for performing sequence unpacking.
- #
- # args [ExprNode]
- # iterator ExprNode
- # unpacked_items [ExprNode] or None
- # coerced_unpacked_items [ExprNode] or None
-
- subexprs = ['args']
-
- is_sequence_constructor = 1
- unpacked_items = None
-
- def compile_time_value_list(self, denv):
- return [arg.compile_time_value(denv) for arg in self.args]
-
- def analyse_target_declaration(self, env):
- for arg in self.args:
- arg.analyse_target_declaration(env)
-
- def analyse_types(self, env):
- for i in range(len(self.args)):
- arg = self.args[i]
- arg.analyse_types(env)
- self.args[i] = arg.coerce_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- def analyse_target_types(self, env):
- self.iterator = PyTempNode(self.pos, env)
- self.unpacked_items = []
- self.coerced_unpacked_items = []
- for arg in self.args:
- arg.analyse_target_types(env)
- unpacked_item = PyTempNode(self.pos, env)
- coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
- self.unpacked_items.append(unpacked_item)
- self.coerced_unpacked_items.append(coerced_unpacked_item)
- self.type = py_object_type
-# env.use_utility_code(unpacking_utility_code)
-
- def allocate_target_temps(self, env, rhs):
- self.iterator.allocate_temps(env)
- if rhs:
- rhs.release_temp(env)
- for arg, node in zip(self.args, self.coerced_unpacked_items):
- node.allocate_temps(env)
- arg.allocate_target_temps(env, node)
- #arg.release_target_temp(env)
- #node.release_temp(env)
- self.iterator.release_temp(env)
-
-# def release_target_temp(self, env):
-# #for arg in self.args:
-# # arg.release_target_temp(env)
-# #for node in self.coerced_unpacked_items:
-# # node.release_temp(env)
-# self.iterator.release_temp(env)
-
- def generate_result_code(self, code):
- self.generate_operation_code(code)
-
- def generate_assignment_code(self, rhs, code):
- iter_result = self.iterator.result()
- code.putln(
- "%s = PyObject_GetIter(%s); if (!%s) %s" % (
- iter_result,
- rhs.py_result(),
- iter_result,
- code.error_goto(self.pos)))
- rhs.generate_disposal_code(code)
- for i in range(len(self.args)):
- item = self.unpacked_items[i]
- code.use_utility_code(unpacking_utility_code)
- unpack_code = "__Pyx_UnpackItem(%s)" % (
- self.iterator.py_result())
- item_result = item.result()
- code.putln(
- "%s = %s; if (!%s) %s" % (
- item_result,
- typecast(item.ctype(), py_object_type, unpack_code),
- item_result,
- code.error_goto(self.pos)))
- value_node = self.coerced_unpacked_items[i]
- value_node.generate_evaluation_code(code)
- self.args[i].generate_assignment_code(value_node, code)
- code.putln(
- "if (__Pyx_EndUnpack(%s) < 0) %s" % (
- self.iterator.py_result(),
- code.error_goto(self.pos)))
- if debug_disposal_code:
- print "UnpackNode.generate_assignment_code:"
- print "...generating disposal code for", rhs
- self.iterator.generate_disposal_code(code)
-
-
-class TupleNode(SequenceNode):
- # Tuple constructor.
-
- gil_message = "Constructing Python tuple"
-
- def compile_time_value(self, denv):
- values = self.compile_time_value_list(denv)
- try:
- return tuple(values)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def generate_operation_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyTuple_New(%s); if (!%s) %s" % (
- result,
- len(self.args),
- result,
- code.error_goto(self.pos)))
- for i in range(len(self.args)):
- arg = self.args[i]
- arg_result = arg.py_result()
- # ??? Change this to use make_owned_reference?
- if not arg.result_in_temp():
- code.put_incref(arg_result)
- code.putln(
- "PyTuple_SET_ITEM(%s, %s, %s);" % (
- result,
- i,
- arg_result))
-
- def generate_subexpr_disposal_code(self, code):
- # We call generate_post_assignment_code here instead
- # of generate_disposal_code, because values were stored
- # in the tuple using a reference-stealing operation.
- for arg in self.args:
- arg.generate_post_assignment_code(code)
-
-
-class ListNode(SequenceNode):
- # List constructor.
-
- gil_message = "Constructing Python list"
-
- def compile_time_value(self, denv):
- return self.compile_time_value_list(denv)
-
- def generate_operation_code(self, code):
- result = self.result()
- code.putln("%s = PyList_New(%s); if (!%s) %s" %
- (result,
- len(self.args),
- result,
- code.error_goto(self.pos)))
- for i in range(len(self.args)):
- arg = self.args[i]
- arg_result = arg.py_result()
- #if not arg.is_temp:
- if not arg.result_in_temp():
- code.put_incref(arg_result)
- code.putln("PyList_SET_ITEM(%s, %s, %s);" %
- (result,
- i,
- arg_result))
-
- def generate_subexpr_disposal_code(self, code):
- # We call generate_post_assignment_code here instead
- # of generate_disposal_code, because values were stored
- # in the list using a reference-stealing operation.
- for arg in self.args:
- arg.generate_post_assignment_code(code)
-
-
-class DictNode(ExprNode):
- # Dictionary constructor.
- #
- # key_value_pairs [(ExprNode, ExprNode)]
-
- def compile_time_value(self, denv):
- pairs = [(key.compile_time_value(denv), value.compile_time_value(denv))
- for (key, value) in self.key_value_pairs]
- try:
- return dict(pairs)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- new_pairs = []
- for key, value in self.key_value_pairs:
- key.analyse_types(env)
- value.analyse_types(env)
- key = key.coerce_to_pyobject(env)
- value = value.coerce_to_pyobject(env)
- new_pairs.append((key, value))
- self.key_value_pairs = new_pairs
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Constructing Python dict"
-
- def allocate_temps(self, env, result = None):
- # Custom method used here because key-value
- # pairs are evaluated and used one at a time.
- self.allocate_temp(env, result)
- for key, value in self.key_value_pairs:
- key.allocate_temps(env)
- value.allocate_temps(env)
- key.release_temp(env)
- value.release_temp(env)
-
- def generate_evaluation_code(self, code):
- # Custom method used here because key-value
- # pairs are evaluated and used one at a time.
- result = self.result()
- code.putln(
- "%s = PyDict_New(); if (!%s) %s" % (
- result,
- result,
- code.error_goto(self.pos)))
- for key, value in self.key_value_pairs:
- key.generate_evaluation_code(code)
- value.generate_evaluation_code(code)
- code.putln(
- "if (PyDict_SetItem(%s, %s, %s) < 0) %s" % (
- result,
- key.py_result(),
- value.py_result(),
- code.error_goto(self.pos)))
- key.generate_disposal_code(code)
- value.generate_disposal_code(code)
-
-
-class ClassNode(ExprNode):
- # Helper class used in the implementation of Python
- # class definitions. Constructs a class object given
- # a name, tuple of bases and class dictionary.
- #
- # name ExprNode Name of the class
- # bases ExprNode Base class tuple
- # dict ExprNode Class dict (not owned by this node)
- # doc ExprNode or None Doc string
- # module_name string Name of defining module
-
- subexprs = ['name', 'bases', 'doc']
-
- def analyse_types(self, env):
- self.name.analyse_types(env)
- self.name = self.name.coerce_to_pyobject(env)
- self.bases.analyse_types(env)
- if self.doc:
- self.doc.analyse_types(env)
- self.doc = self.doc.coerce_to_pyobject(env)
- self.module_name = env.global_scope().qualified_name
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-# env.use_utility_code(create_class_utility_code)
-
- gil_message = "Constructing Python class"
-
- def generate_result_code(self, code):
- result = self.result()
- if self.doc:
- code.putln(
- 'if (PyDict_SetItemString(%s, "__doc__", %s) < 0) %s' % (
- self.dict.py_result(),
- self.doc.py_result(),
- code.error_goto(self.pos)))
- code.use_utility_code(create_class_utility_code)
- code.putln(
- '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); if (!%s) %s' % (
- result,
- self.bases.py_result(),
- self.dict.py_result(),
- self.name.py_result(),
- self.module_name,
- result,
- code.error_goto(self.pos)))
-
-
-class UnboundMethodNode(ExprNode):
- # Helper class used in the implementation of Python
- # class definitions. Constructs an unbound method
- # object from a class and a function.
- #
- # class_cname string C var holding the class object
- # function ExprNode Function object
-
- subexprs = ['function']
-
- def analyse_types(self, env):
- self.function.analyse_types(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Constructing an unbound method"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyMethod_New(%s, 0, %s); if (!%s) %s" % (
- result,
- self.function.py_result(),
- self.class_cname,
- result,
- code.error_goto(self.pos)))
-
-
-class PyCFunctionNode(AtomicExprNode):
- # Helper class used in the implementation of Python
- # class definitions. Constructs a PyCFunction object
- # from a PyMethodDef struct.
- #
- # pymethdef_cname string PyMethodDef structure
- # module_name string Name of defining module
-
- def analyse_types(self, env):
- self.type = py_object_type
- self.module_name = env.global_scope().module_name
- self.gil_check(env)
- self.is_temp = 1
-
- gil_message = "Constructing Python function"
-
- def generate_result_code(self, code):
- result = self.result()
- code.putln(
- "%s = PyCFunction_NewEx(&%s, 0, %s); if (!%s) %s" % (
- result,
- self.pymethdef_cname,
- code.get_py_string_const(self.module_name),
- result,
- code.error_goto(self.pos)))
-
-#-------------------------------------------------------------------
-#
-# Unary operator nodes
-#
-#-------------------------------------------------------------------
-
-compile_time_unary_operators = {
- 'not': operator.not_,
- '~': operator.inv,
- '-': operator.neg,
- '+': operator.pos,
-}
-
-class UnopNode(ExprNode):
- # operator string
- # operand ExprNode
- #
- # Processing during analyse_expressions phase:
- #
- # analyse_c_operation
- # Called when the operand is not a pyobject.
- # - Check operand type and coerce if needed.
- # - Determine result type and result code fragment.
- # - Allocate temporary for result if needed.
-
- subexprs = ['operand']
-
- def compile_time_value(self, denv):
- func = compile_time_unary_operators.get(self.operator)
- if not func:
- error(self.pos,
- "Unary '%s' not supported in compile-time expression"
- % self.operator)
- operand = self.operand.compile_time_value(denv)
- try:
- return func(operand)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- self.operand.analyse_types(env)
- if self.is_py_operation():
- self.coerce_operand_to_pyobject(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
- else:
- self.analyse_c_operation(env)
-
- def check_const(self):
- self.operand.check_const()
-
- def is_py_operation(self):
- return self.operand.type.is_pyobject
-
- def coerce_operand_to_pyobject(self, env):
- self.operand = self.operand.coerce_to_pyobject(env)
-
- def generate_result_code(self, code):
- if self.operand.type.is_pyobject:
- self.generate_py_operation_code(code)
- else:
- if self.is_temp:
- self.generate_c_operation_code(code)
-
- def generate_py_operation_code(self, code):
- function = self.py_operation_function()
- result = self.result()
- code.putln(
- "%s = %s(%s); if (!%s) %s" % (
- result,
- function,
- self.operand.py_result(),
- result,
- code.error_goto(self.pos)))
-
- def type_error(self):
- if not self.operand.type.is_error:
- error(self.pos, "Invalid operand type for '%s' (%s)" %
- (self.operator, self.operand.type))
- self.type = PyrexTypes.error_type
-
-
-class NotNode(ExprNode):
- # 'not' operator
- #
- # operand ExprNode
-
- def compile_time_value(self, denv):
- operand = self.operand.compile_time_value(denv)
- try:
- return not operand
- except Exception, e:
- self.compile_time_value_error(e)
-
- subexprs = ['operand']
-
- def analyse_types(self, env):
- self.operand.analyse_types(env)
- self.operand = self.operand.coerce_to_boolean(env)
- self.type = PyrexTypes.c_int_type
-
- def calculate_result_code(self):
- return "(!%s)" % self.operand.result()
-
- def generate_result_code(self, code):
- pass
-
-
-class UnaryPlusNode(UnopNode):
- # unary '+' operator
-
- operator = '+'
-
- def analyse_c_operation(self, env):
- self.type = self.operand.type
-
- def py_operation_function(self):
- return "PyNumber_Positive"
-
- def calculate_result_code(self):
- return self.operand.result()
-
-
-class UnaryMinusNode(UnopNode):
- # unary '-' operator
-
- operator = '-'
-
- def analyse_c_operation(self, env):
- if self.operand.type.is_numeric:
- self.type = self.operand.type
- else:
- self.type_error()
-
- def py_operation_function(self):
- return "PyNumber_Negative"
-
- def calculate_result_code(self):
- return "(-%s)" % self.operand.result()
-
-
-class TildeNode(UnopNode):
- # unary '~' operator
-
- def analyse_c_operation(self, env):
- if self.operand.type.is_int:
- self.type = self.operand.type
- else:
- self.type_error()
-
- def py_operation_function(self):
- return "PyNumber_Invert"
-
- def calculate_result_code(self):
- return "(~%s)" % self.operand.result()
-
-
-class AmpersandNode(ExprNode):
- # The C address-of operator.
- #
- # operand ExprNode
-
- subexprs = ['operand']
-
- def analyse_types(self, env):
- self.operand.analyse_types(env)
- argtype = self.operand.type
- if not (argtype.is_cfunction or self.operand.is_lvalue()):
- self.error("Taking address of non-lvalue")
- return
- if argtype.is_pyobject:
- self.error("Cannot take address of Python variable")
- return
- self.type = PyrexTypes.c_ptr_type(argtype)
-
- def check_const(self):
- self.operand.check_const_addr()
-
- def error(self, mess):
- error(self.pos, mess)
- self.type = PyrexTypes.error_type
- self.result_code = "<error>"
-
- def calculate_result_code(self):
- return "(&%s)" % self.operand.result()
-
- def generate_result_code(self, code):
- pass
-
-
-unop_node_classes = {
- "+": UnaryPlusNode,
- "-": UnaryMinusNode,
- "~": TildeNode,
-}
-
-def unop_node(pos, operator, operand):
- # Construct unnop node of appropriate class for
- # given operator.
- return unop_node_classes[operator](pos,
- operator = operator,
- operand = operand)
-
-
-class TypecastNode(ExprNode):
- # C type cast
- #
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
- # operand ExprNode
-
- subexprs = ['operand']
-
- def analyse_types(self, env):
- base_type = self.base_type.analyse(env)
- _, self.type = self.declarator.analyse(base_type, env)
- if self.type.is_cfunction:
- error(self.pos,
- "Cannot cast to a function type")
- self.type = PyrexTypes.error_type
- self.operand.analyse_types(env)
- to_py = self.type.is_pyobject
- from_py = self.operand.type.is_pyobject
- if from_py and not to_py and self.operand.is_ephemeral():
- error(self.pos, "Casting temporary Python object to non-Python type")
- # Must do the following, so that the result can be increfed without
- # the operand getting evaluated twice.
- if to_py and not from_py:
- #self.result_ctype = py_object_type
- #self.is_temp = 1
- self.operand = self.operand.coerce_to_simple(env)
-
- def check_const(self):
- self.operand.check_const()
-
- def calculate_result_code(self):
- opnd = self.operand
- result_code = self.type.cast_code(opnd.result())
- return result_code
-
- def result_as(self, type):
- if not self.is_temp and type.is_pyobject and self.type.is_pyobject:
- # Optimise away some unnecessary casting
- return self.operand.result_as(type)
- else:
- return ExprNode.result_as(self, type)
-
- def generate_result_code(self, code):
- if self.is_temp:
- code.putln(
- "%s = %s;" % (
- self.result(),
- self.operand.py_result()))
- code.put_incref(self.py_result())
-
-
-class SizeofNode(ExprNode):
- # Base class for sizeof(x) expression nodes.
- #
- # sizeof_code string
-
- subexprs = []
-
- def check_const(self):
- pass
-
- def analyse_types(self, env):
- self.analyse_argument(env)
- self.type = PyrexTypes.c_size_t_type
-
- def analyse_type_argument(self, arg_type):
- if arg_type.is_pyobject:
- error(self.pos, "Cannot take sizeof Python object")
- elif arg_type.is_void:
- error(self.pos, "Cannot take sizeof void")
- elif not arg_type.is_complete():
- error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
- arg_code = arg_type.declaration_code("")
- self.sizeof_code = "(sizeof(%s))" % arg_code
-
- def calculate_result_code(self):
- return self.sizeof_code
-
- def generate_result_code(self, code):
- pass
-
-
-class SizeofTypeNode(SizeofNode):
- # C sizeof function applied to a type
- #
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
-
- def analyse_argument(self, env):
- base_type = self.base_type.analyse(env)
- _, arg_type = self.declarator.analyse(base_type, env)
- self.analyse_type_argument(arg_type)
-
-
-class SizeofVarNode(SizeofNode):
- # C sizeof function applied to a variable or qualified name
- # (which may actually refer to a type)
- #
- # operand ExprNode
-
- #subexprs = ['operand']
-
- def analyse_argument(self, env):
- is_type = 0
- operand = self.operand
- if operand.analyse_as_cimported_attribute(env, allow_type = 1):
- if operand.entry.is_type:
- is_type = 1
- self.analyse_type_argument(operand.entry.type)
- else:
- self.operand.analyse_types(env)
- self.operand.mark_vars_used()
- if not is_type:
- self.sizeof_code = "(sizeof(%s))" % operand.result()
-
-
-#-------------------------------------------------------------------
-#
-# Binary operator nodes
-#
-#-------------------------------------------------------------------
-
-compile_time_binary_operators = {
- '<': operator.lt,
- '<=': operator.le,
- '==': operator.eq,
- '!=': operator.ne,
- '>=': operator.ge,
- '>': operator.gt,
- 'is': operator.is_,
- 'is_not': operator.is_not,
- '+': operator.add,
- '&': operator.and_,
- '/': operator.div,
- '//': operator.floordiv,
- '<<': operator.lshift,
- '%': operator.mod,
- '*': operator.mul,
- '|': operator.or_,
- '**': operator.pow,
- '>>': operator.rshift,
- '-': operator.sub,
- #'/': operator.truediv,
- '^': operator.xor,
- 'in': lambda x, y: x in y,
- 'not_in': lambda x, y: x not in y,
-}
-
-def get_compile_time_binop(node):
- func = compile_time_binary_operators.get(node.operator)
- if not func:
- error(node.pos,
- "Binary '%s' not supported in compile-time expression"
- % node.operator)
- return func
-
-class BinopNode(ExprNode):
- # operator string
- # operand1 ExprNode
- # operand2 ExprNode
- #
- # Processing during analyse_expressions phase:
- #
- # analyse_c_operation
- # Called when neither operand is a pyobject.
- # - Check operand types and coerce if needed.
- # - Determine result type and result code fragment.
- # - Allocate temporary for result if needed.
-
- subexprs = ['operand1', 'operand2']
-
- def compile_time_value(self, denv):
- func = get_compile_time_binop(self)
- operand1 = self.operand1.compile_time_value(denv)
- operand2 = self.operand2.compile_time_value(denv)
- try:
- return func(operand1, operand2)
- except Exception, e:
- self.compile_time_value_error(e)
-
- def analyse_types(self, env):
- self.operand1.analyse_types(env)
- self.operand2.analyse_types(env)
- if self.is_py_operation():
- self.coerce_operands_to_pyobjects(env)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
- else:
- self.analyse_c_operation(env)
-
- def is_py_operation(self):
- return (self.operand1.type.is_pyobject
- or self.operand2.type.is_pyobject)
-
- def coerce_operands_to_pyobjects(self, env):
- self.operand1 = self.operand1.coerce_to_pyobject(env)
- self.operand2 = self.operand2.coerce_to_pyobject(env)
-
- def check_const(self):
- self.operand1.check_const()
- self.operand2.check_const()
-
- def generate_result_code(self, code):
- #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
- if self.operand1.type.is_pyobject:
- function = self.py_operation_function()
- if function == "PyNumber_Power":
- extra_args = ", Py_None"
- else:
- extra_args = ""
- result = self.result()
- code.putln(
- "%s = %s(%s, %s%s); if (!%s) %s" % (
- result,
- function,
- self.operand1.py_result(),
- self.operand2.py_result(),
- extra_args,
- result,
- code.error_goto(self.pos)))
- else:
- if self.is_temp:
- self.generate_c_operation_code(code)
-
- def type_error(self):
- if not (self.operand1.type.is_error
- or self.operand2.type.is_error):
- error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
- (self.operator, self.operand1.type,
- self.operand2.type))
- self.type = PyrexTypes.error_type
-
-
-class NumBinopNode(BinopNode):
- # Binary operation taking numeric arguments.
-
- def analyse_c_operation(self, env):
- type1 = self.operand1.type
- type2 = self.operand2.type
- if self.operator == "**" and type1.is_int and type2.is_int:
- error(self.pos, "** with two C int types is ambiguous")
- self.type = error_type
- return
- self.type = self.compute_c_result_type(type1, type2)
- if not self.type:
- self.type_error()
-
- def compute_c_result_type(self, type1, type2):
- if self.c_types_okay(type1, type2):
- return PyrexTypes.widest_numeric_type(type1, type2)
- else:
- return None
-
- def c_types_okay(self, type1, type2):
- #print "NumBinopNode.c_types_okay:", type1, type2 ###
- return (type1.is_numeric or type1.is_enum) \
- and (type2.is_numeric or type2.is_enum)
-
- def calculate_result_code(self):
- return "(%s %s %s)" % (
- self.operand1.result(),
- self.operator,
- self.operand2.result())
-
- def py_operation_function(self):
- return self.py_functions[self.operator]
-
- py_functions = {
- "|": "PyNumber_Or",
- "^": "PyNumber_Xor",
- "&": "PyNumber_And",
- "<<": "PyNumber_Lshift",
- ">>": "PyNumber_Rshift",
- "+": "PyNumber_Add",
- "-": "PyNumber_Subtract",
- "*": "PyNumber_Multiply",
- "/": "PyNumber_Divide",
- "%": "PyNumber_Remainder",
- "**": "PyNumber_Power"
- }
-
-
-class IntBinopNode(NumBinopNode):
- # Binary operation taking integer arguments.
-
- def c_types_okay(self, type1, type2):
- #print "IntBinopNode.c_types_okay:", type1, type2 ###
- return (type1.is_int or type1.is_enum) \
- and (type2.is_int or type2.is_enum)
-
-
-class AddNode(NumBinopNode):
- # '+' operator.
-
- def is_py_operation(self):
- if self.operand1.type.is_string \
- and self.operand2.type.is_string:
- return 1
- else:
- return NumBinopNode.is_py_operation(self)
-
- def compute_c_result_type(self, type1, type2):
- #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
- if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
- return type1
- elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
- return type2
- else:
- return NumBinopNode.compute_c_result_type(
- self, type1, type2)
-
-
-class SubNode(NumBinopNode):
- # '-' operator.
-
- def compute_c_result_type(self, type1, type2):
- if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
- return type1
- elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
- return PyrexTypes.c_int_type
- else:
- return NumBinopNode.compute_c_result_type(
- self, type1, type2)
-
-
-class MulNode(NumBinopNode):
- # '*' operator.
-
- def is_py_operation(self):
- type1 = self.operand1.type
- type2 = self.operand2.type
- if (type1.is_string and type2.is_int) \
- or (type2.is_string and type1.is_int):
- return 1
- else:
- return NumBinopNode.is_py_operation(self)
-
-
-class ModNode(IntBinopNode):
- # '%' operator.
-
- def is_py_operation(self):
- return (self.operand1.type.is_string
- or self.operand2.type.is_string
- or IntBinopNode.is_py_operation(self))
-
-
-class PowNode(NumBinopNode):
- # '**' operator.
-
- def analyse_types(self, env):
- env.pow_function_used = 1
- NumBinopNode.analyse_types(self, env)
-
- def compute_c_result_type(self, type1, type2):
- if self.c_types_okay(type1, type2):
- return PyrexTypes.c_double_type
- else:
- return None
-
- def calculate_result_code(self):
- return "pow(%s, %s)" % (
- self.operand1.result(), self.operand2.result())
-
-
-class BoolBinopNode(ExprNode):
- # Short-circuiting boolean operation.
- #
- # operator string
- # operand1 ExprNode
- # operand2 ExprNode
- # temp_bool ExprNode used internally
-
- temp_bool = None
-
- subexprs = ['operand1', 'operand2', 'temp_bool']
-
- def compile_time_value(self, denv):
- if self.operator == 'and':
- return self.operand1.compile_time_value(denv) \
- and self.operand2.compile_time_value(denv)
- else:
- return self.operand1.compile_time_value(denv) \
- or self.operand2.compile_time_value(denv)
-
- def analyse_types(self, env):
- self.operand1.analyse_types(env)
- self.operand2.analyse_types(env)
- if self.operand1.type.is_pyobject or \
- self.operand2.type.is_pyobject:
- self.operand1 = self.operand1.coerce_to_pyobject(env)
- self.operand2 = self.operand2.coerce_to_pyobject(env)
- self.temp_bool = TempNode(self.pos,
- PyrexTypes.c_int_type, env)
- self.type = py_object_type
- self.gil_check(env)
- else:
- self.operand1 = self.operand1.coerce_to_boolean(env)
- self.operand2 = self.operand2.coerce_to_boolean(env)
- self.type = PyrexTypes.c_int_type
- # For what we're about to do, it's vital that
- # both operands be temp nodes.
- self.operand1 = self.operand1.coerce_to_temp(env) #CTT
- self.operand2 = self.operand2.coerce_to_temp(env)
- self.is_temp = 1
-
- gil_message = "Truth-testing Python object"
-
- def allocate_temps(self, env, result_code = None):
- # We don't need both operands at the same time, and
- # one of the operands will also be our result. So we
- # use an allocation strategy here which results in
- # this node and both its operands sharing the same
- # result variable. This allows us to avoid some
- # assignments and increfs/decrefs that would otherwise
- # be necessary.
- self.allocate_temp(env, result_code)
- self.operand1.allocate_temps(env, self.result_code)
- if self.temp_bool:
- self.temp_bool.allocate_temp(env)
- self.temp_bool.release_temp(env)
- self.operand2.allocate_temps(env, self.result_code)
- # We haven't called release_temp on either operand,
- # because although they are temp nodes, they don't own
- # their result variable. And because they are temp
- # nodes, any temps in their subnodes will have been
- # released before their allocate_temps returned.
- # Therefore, they contain no temp vars that need to
- # be released.
-
- def check_const(self):
- self.operand1.check_const()
- self.operand2.check_const()
-
- def calculate_result_code(self):
- return "(%s %s %s)" % (
- self.operand1.result(),
- self.py_to_c_op[self.operator],
- self.operand2.result())
-
- py_to_c_op = {'and': "&&", 'or': "||"}
-
- def generate_evaluation_code(self, code):
- self.operand1.generate_evaluation_code(code)
- test_result = self.generate_operand1_test(code)
- if self.operator == 'and':
- sense = ""
- else:
- sense = "!"
- code.putln(
- "if (%s%s) {" % (
- sense,
- test_result))
- self.operand1.generate_disposal_code(code)
- self.operand2.generate_evaluation_code(code)
- code.putln(
- "}")
-
- def generate_operand1_test(self, code):
- # Generate code to test the truth of the first operand.
- if self.type.is_pyobject:
- test_result = self.temp_bool.result()
- code.putln(
- "%s = PyObject_IsTrue(%s); if (%s < 0) %s" % (
- test_result,
- self.operand1.py_result(),
- test_result,
- code.error_goto(self.pos)))
- else:
- test_result = self.operand1.result()
- return test_result
-
-
-class CmpNode:
- # Mixin class containing code common to PrimaryCmpNodes
- # and CascadedCmpNodes.
-
- def cascaded_compile_time_value(self, operand1, denv):
- func = get_compile_time_binop(self)
- operand2 = self.operand2.compile_time_value(denv)
- try:
- result = func(operand1, operand2)
- except Exception, e:
- self.compile_time_value_error(e)
- result = None
- if result:
- cascade = self.cascade
- if cascade:
- result = result and cascade.compile_time_value(operand2, denv)
- return result
-
- def is_python_comparison(self):
- return (self.has_python_operands()
- or (self.cascade and self.cascade.is_python_comparison())
- or self.operator in ('in', 'not_in'))
-
- def check_types(self, env, operand1, op, operand2):
- if not self.types_okay(operand1, op, operand2):
- error(self.pos, "Invalid types for '%s' (%s, %s)" %
- (self.operator, operand1.type, operand2.type))
-
- def types_okay(self, operand1, op, operand2):
- type1 = operand1.type
- type2 = operand2.type
- if type1.is_error or type2.is_error:
- return 1
- if type1.is_pyobject: # type2 will be, too
- return 1
- elif type1.is_ptr or type1.is_array:
- return type1.is_null_ptr or type2.is_null_ptr \
- or ((type2.is_ptr or type2.is_array)
- and type1.base_type.same_as(type2.base_type))
- elif ((type1.is_numeric and type2.is_numeric
- or type1.is_enum and (type2.is_int or type1.same_as(type2))
- or type1.is_int and type2.is_enum)
- and op not in ('is', 'is_not')):
- return 1
- else:
- return 0
-
- def generate_operation_code(self, code, result,
- operand1, op , operand2):
- if op == 'in' or op == 'not_in':
- code.putln(
- "%s = PySequence_Contains(%s, %s); if (%s < 0) %s" % (
- result,
- operand2.py_result(),
- operand1.py_result(),
- result,
- code.error_goto(self.pos)))
- if op == 'not_in':
- code.putln(
- "%s = !%s;" % (
- result, result))
- elif (operand1.type.is_pyobject
- and op not in ('is', 'is_not')):
- code.putln(
- "if (PyObject_Cmp(%s, %s, &%s) < 0) %s" % (
- operand1.py_result(),
- operand2.py_result(),
- result,
- code.error_goto(self.pos)))
- code.putln(
- "%s = %s %s 0;" % (
- result, result, op))
- else:
- type1 = operand1.type
- type2 = operand2.type
- if (type1.is_extension_type or type2.is_extension_type) \
- and not operand1.ctype().same_as(operand2.ctype()):
- code1 = operand1.result_as(py_object_type)
- code2 = operand2.result_as(py_object_type)
- else:
- code1 = operand1.result()
- code2 = operand2.result()
- code.putln("%s = %s %s %s;" % (
- result,
- code1,
- self.c_operator(op),
- code2))
-
- def c_operator(self, op):
- if op == 'is':
- return "=="
- elif op == 'is_not':
- return "!="
- else:
- return op
-
-
-class PrimaryCmpNode(ExprNode, CmpNode):
- # Non-cascaded comparison or first comparison of
- # a cascaded sequence.
- #
- # operator string
- # operand1 ExprNode
- # operand2 ExprNode
- # cascade CascadedCmpNode
-
- # We don't use the subexprs mechanism, because
- # things here are too complicated for it to handle.
- # Instead, we override all the framework methods
- # which use it.
-
- cascade = None
-
- def compile_time_value(self, denv):
- operand1 = self.operand1.compile_time_value(denv)
- return self.cascaded_compile_time_value(operand1, denv)
-
- def analyse_types(self, env):
- self.operand1.analyse_types(env)
- self.operand2.analyse_types(env)
- if self.cascade:
- self.cascade.analyse_types(env, self.operand2)
- self.is_pycmp = self.is_python_comparison()
- if self.is_pycmp:
- self.coerce_operands_to_pyobjects(env)
- if self.cascade:
- self.operand2 = self.operand2.coerce_to_simple(env)
- self.cascade.coerce_cascaded_operands_to_temp(env)
- self.check_operand_types(env)
- self.type = PyrexTypes.c_int_type
- if self.is_pycmp or self.cascade:
- self.is_temp = 1
-
- def check_operand_types(self, env):
- self.check_types(env,
- self.operand1, self.operator, self.operand2)
- if self.cascade:
- self.cascade.check_operand_types(env, self.operand2)
-
- def has_python_operands(self):
- return (self.operand1.type.is_pyobject
- or self.operand2.type.is_pyobject)
-
- def coerce_operands_to_pyobjects(self, env):
- self.operand1 = self.operand1.coerce_to_pyobject(env)
- self.operand2 = self.operand2.coerce_to_pyobject(env)
- if self.cascade:
- self.cascade.coerce_operands_to_pyobjects(env)
-
- def allocate_subexpr_temps(self, env):
- self.operand1.allocate_temps(env)
- self.operand2.allocate_temps(env)
- if self.cascade:
- self.cascade.allocate_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- self.operand1.release_temp(env)
- self.operand2.release_temp(env)
- if self.cascade:
- self.cascade.release_subexpr_temps(env)
-
- def check_const(self):
- self.operand1.check_const()
- self.operand2.check_const()
- if self.cascade:
- self.not_const()
-
- def calculate_result_code(self):
- return "(%s %s %s)" % (
- self.operand1.result(),
- self.c_operator(self.operator),
- self.operand2.result())
-
- def generate_evaluation_code(self, code):
- self.operand1.generate_evaluation_code(code)
- self.operand2.generate_evaluation_code(code)
- if self.is_temp:
- result = self.result()
- self.generate_operation_code(code, result,
- self.operand1, self.operator, self.operand2)
- if self.cascade:
- self.cascade.generate_evaluation_code(code,
- result, self.operand2)
- self.operand1.generate_disposal_code(code)
- self.operand2.generate_disposal_code(code)
-
- def generate_subexpr_disposal_code(self, code):
- # If this is called, it is a non-cascaded cmp,
- # so only need to dispose of the two main operands.
- self.operand1.generate_disposal_code(code)
- self.operand2.generate_disposal_code(code)
-
-
-class CascadedCmpNode(Node, CmpNode):
- # A CascadedCmpNode is not a complete expression node. It
- # hangs off the side of another comparison node, shares
- # its left operand with that node, and shares its result
- # with the PrimaryCmpNode at the head of the chain.
- #
- # operator string
- # operand2 ExprNode
- # cascade CascadedCmpNode
-
- cascade = None
-
- def analyse_types(self, env, operand1):
- self.operand2.analyse_types(env)
- if self.cascade:
- self.cascade.analyse_types(env, self.operand2)
-
- def check_operand_types(self, env, operand1):
- self.check_types(env,
- operand1, self.operator, self.operand2)
- if self.cascade:
- self.cascade.check_operand_types(env, self.operand2)
-
- def has_python_operands(self):
- return self.operand2.type.is_pyobject
-
- def coerce_operands_to_pyobjects(self, env):
- self.operand2 = self.operand2.coerce_to_pyobject(env)
- if self.cascade:
- self.cascade.coerce_operands_to_pyobjects(env)
-
- def coerce_cascaded_operands_to_temp(self, env):
- if self.cascade:
- #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
- self.operand2 = self.operand2.coerce_to_simple(env)
- self.cascade.coerce_cascaded_operands_to_temp(env)
-
- def allocate_subexpr_temps(self, env):
- self.operand2.allocate_temps(env)
- if self.cascade:
- self.cascade.allocate_subexpr_temps(env)
-
- def release_subexpr_temps(self, env):
- self.operand2.release_temp(env)
- if self.cascade:
- self.cascade.release_subexpr_temps(env)
-
- def generate_evaluation_code(self, code, result, operand1):
- code.putln("if (%s) {" % result)
- self.operand2.generate_evaluation_code(code)
- self.generate_operation_code(code, result,
- operand1, self.operator, self.operand2)
- if self.cascade:
- self.cascade.generate_evaluation_code(
- code, result, self.operand2)
- # Cascaded cmp result is always temp
- self.operand2.generate_disposal_code(code)
- code.putln("}")
-
-
-binop_node_classes = {
- "or": BoolBinopNode,
- "and": BoolBinopNode,
- "|": IntBinopNode,
- "^": IntBinopNode,
- "&": IntBinopNode,
- "<<": IntBinopNode,
- ">>": IntBinopNode,
- "+": AddNode,
- "-": SubNode,
- "*": MulNode,
- "/": NumBinopNode,
- "%": ModNode,
- "**": PowNode
-}
-
-def binop_node(pos, operator, operand1, operand2):
- # Construct binop node of appropriate class for
- # given operator.
- return binop_node_classes[operator](pos,
- operator = operator,
- operand1 = operand1,
- operand2 = operand2)
-
-#-------------------------------------------------------------------
-#
-# Coercion nodes
-#
-# Coercion nodes are special in that they are created during
-# the analyse_types phase of parse tree processing.
-# Their __init__ methods consequently incorporate some aspects
-# of that phase.
-#
-#-------------------------------------------------------------------
-
-class CoercionNode(ExprNode):
- # Abstract base class for coercion nodes.
- #
- # arg ExprNode node being coerced
-
- subexprs = ['arg']
-
- def __init__(self, arg):
- self.pos = arg.pos
- self.arg = arg
- if debug_coercion:
- print self, "Coercing", self.arg
-
-
-class CastNode(CoercionNode):
- # Wrap a node in a C type cast.
-
- def __init__(self, arg, new_type):
- CoercionNode.__init__(self, arg)
- self.type = new_type
-
- def calculate_result_code(self):
- return self.arg.result_as(self.type)
-
- def generate_result_code(self, code):
- self.arg.generate_result_code(code)
-
-
-class PyTypeTestNode(CoercionNode):
- # This node is used to check that a generic Python
- # object is an instance of a particular extension type.
- # This node borrows the result of its argument node.
-
- def __init__(self, arg, dst_type, env):
- # The arg is know to be a Python object, and
- # the dst_type is known to be an extension type.
- assert dst_type.is_extension_type, "PyTypeTest on non extension type"
- CoercionNode.__init__(self, arg)
- self.type = dst_type
- self.result_ctype = arg.ctype()
-# env.use_utility_code(type_test_utility_code)
- self.gil_check(env)
-
- gil_message = "Python type test"
-
- def result_in_temp(self):
- return self.arg.result_in_temp()
-
- def is_ephemeral(self):
- return self.arg.is_ephemeral()
-
- def calculate_result_code(self):
- return self.arg.result()
-
- def generate_result_code(self, code):
- if self.type.typeobj_is_available():
- code.use_utility_code(type_test_utility_code)
- code.putln(
- "if (!__Pyx_TypeTest(%s, %s)) %s" % (
- self.arg.py_result(),
- self.type.typeptr_cname,
- code.error_goto(self.pos)))
- else:
- error(self.pos, "Cannot test type of extern C class "
- "without type object name specification")
-
- def generate_post_assignment_code(self, code):
- self.arg.generate_post_assignment_code(code)
-
-
-class CoerceToPyTypeNode(CoercionNode):
- # This node is used to convert a C data type
- # to a Python object.
-
- def __init__(self, arg, env):
- CoercionNode.__init__(self, arg)
- self.type = py_object_type
- self.gil_check(env)
- self.is_temp = 1
- if not arg.type.to_py_function:
- error(arg.pos,
- "Cannot convert '%s' to Python object" % arg.type)
-
- gil_message = "Converting to Python object"
-
- def generate_result_code(self, code):
- function = self.arg.type.to_py_function
- result = self.result()
- code.putln('%s = %s(%s); if (!%s) %s' % (
- result,
- function,
- self.arg.result(),
- result,
- code.error_goto(self.pos)))
-
-
-class CoerceFromPyTypeNode(CoercionNode):
- # This node is used to convert a Python object
- # to a C data type.
-
- def __init__(self, result_type, arg, env):
- CoercionNode.__init__(self, arg)
- self.type = result_type
- self.is_temp = 1
- if not result_type.from_py_function:
- error(arg.pos,
- "Cannot convert Python object to '%s'" % result_type)
- if self.type.is_string and self.arg.is_ephemeral():
- error(arg.pos,
- "Obtaining char * from temporary Python value")
-
- def generate_result_code(self, code):
- function = self.type.from_py_function
- operand = self.arg.py_result()
- rhs = "%s(%s)" % (function, operand)
- if self.type.is_enum:
- rhs = typecast(self.type, c_long_type, rhs)
- result = self.result()
- if self.type.is_string:
- err_code = "!%s" % result
- else:
- err_code = "PyErr_Occurred()"
- code.putln('%s = %s; if (%s) %s' % (
- result,
- rhs,
- err_code,
- code.error_goto(self.pos)))
-
-
-class CoerceToBooleanNode(CoercionNode):
- # This node is used when a result needs to be used
- # in a boolean context.
-
- def __init__(self, arg, env):
- CoercionNode.__init__(self, arg)
- self.type = PyrexTypes.c_int_type
- if arg.type.is_pyobject:
- if env.nogil:
- self.gil_error()
- self.is_temp = 1
-
- gil_message = "Truth-testing Python object"
-
- def check_const(self):
- if self.is_temp:
- self.not_const()
- self.arg.check_const()
-
- def calculate_result_code(self):
- return "(%s != 0)" % self.arg.result()
-
- def generate_result_code(self, code):
- if self.arg.type.is_pyobject:
- result = self.result()
- code.putln(
- "%s = PyObject_IsTrue(%s); if (%s < 0) %s" % (
- result,
- self.arg.py_result(),
- result,
- code.error_goto(self.pos)))
-
-
-class CoerceToTempNode(CoercionNode):
- # This node is used to force the result of another node
- # to be stored in a temporary. It is only used if the
- # argument node's result is not already in a temporary.
-
- def __init__(self, arg, env):
- CoercionNode.__init__(self, arg)
- self.type = self.arg.type
- self.is_temp = 1
- if self.type.is_pyobject:
- self.gil_check(env)
- self.result_ctype = py_object_type
-
- gil_message = "Creating temporary Python reference"
-
-
- def generate_result_code(self, code):
- #self.arg.generate_evaluation_code(code) # Already done
- # by generic generate_subexpr_evaluation_code!
- code.putln("%s = %s;" % (
- self.result(), self.arg.result_as(self.ctype())))
- if self.type.is_pyobject:
- code.put_incref(self.py_result())
-
-
-class CloneNode(CoercionNode):
- # This node is employed when the result of another node needs
- # to be used multiple times. The argument node's result must
- # be in a temporary. This node "borrows" the result from the
- # argument node, and does not generate any evaluation or
- # disposal code for it. The original owner of the argument
- # node is responsible for doing those things.
-
- subexprs = [] # Arg is not considered a subexpr
-
- def __init__(self, arg):
- CoercionNode.__init__(self, arg)
- self.type = arg.type
- self.result_ctype = arg.result_ctype
-
- def calculate_result_code(self):
- return self.arg.result()
-
- def generate_evaluation_code(self, code):
- pass
-
- def generate_result_code(self, code):
- pass
-
-#------------------------------------------------------------------------------------
-#
-# Runtime support code
-#
-#------------------------------------------------------------------------------------
-
-get_name_utility_code = [
-"""
-static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/
-""","""
-static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
- PyObject *result;
- result = PyObject_GetAttrString(dict, name);
- if (!result)
- PyErr_SetString(PyExc_NameError, name);
- return result;
-}
-"""]
-
-get_name_interned_utility_code = [
-"""
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-""","""
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
- PyObject *result;
- result = PyObject_GetAttr(dict, name);
- if (!result)
- PyErr_SetObject(PyExc_NameError, name);
- return result;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-import_utility_code = [
-"""
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
-""","""
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
- PyObject *__import__ = 0;
- PyObject *empty_list = 0;
- PyObject *module = 0;
- PyObject *global_dict = 0;
- PyObject *empty_dict = 0;
- PyObject *list;
- __import__ = PyObject_GetAttrString(%(BUILTINS)s, "__import__");
- if (!__import__)
- goto bad;
- if (from_list)
- list = from_list;
- else {
- empty_list = PyList_New(0);
- if (!empty_list)
- goto bad;
- list = empty_list;
- }
- global_dict = PyModule_GetDict(%(GLOBALS)s);
- if (!global_dict)
- goto bad;
- empty_dict = PyDict_New();
- if (!empty_dict)
- goto bad;
- module = PyObject_CallFunction(__import__, "OOOO",
- name, global_dict, empty_dict, list);
-bad:
- Py_XDECREF(empty_list);
- Py_XDECREF(__import__);
- Py_XDECREF(empty_dict);
- return module;
-}
-""" % {
- "BUILTINS": Naming.builtins_cname,
- "GLOBALS": Naming.module_cname,
-}]
-
-#------------------------------------------------------------------------------------
-#
-#get_exception_utility_code = [
-#"""
-#static PyObject *__Pyx_GetExcValue(void); /*proto*/
-#""","""
-#static PyObject *__Pyx_GetExcValue(void) {
-# PyObject *type = 0, *value = 0, *tb = 0;
-# PyObject *result = 0;
-# PyThreadState *tstate = PyThreadState_Get();
-# PyErr_Fetch(&type, &value, &tb);
-# PyErr_NormalizeException(&type, &value, &tb);
-# if (PyErr_Occurred())
-# goto bad;
-# if (!value) {
-# value = Py_None;
-# Py_INCREF(value);
-# }
-# Py_XDECREF(tstate->exc_type);
-# Py_XDECREF(tstate->exc_value);
-# Py_XDECREF(tstate->exc_traceback);
-# tstate->exc_type = type;
-# tstate->exc_value = value;
-# tstate->exc_traceback = tb;
-# result = value;
-# Py_XINCREF(result);
-# type = 0;
-# value = 0;
-# tb = 0;
-#bad:
-# Py_XDECREF(type);
-# Py_XDECREF(value);
-# Py_XDECREF(tb);
-# return result;
-#}
-#"""]
-#
-#------------------------------------------------------------------------------------
-
-unpacking_utility_code = [
-"""
-static PyObject *__Pyx_UnpackItem(PyObject *); /*proto*/
-static int __Pyx_EndUnpack(PyObject *); /*proto*/
-""","""
-static void __Pyx_UnpackError(void) {
- PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
-}
-
-static PyObject *__Pyx_UnpackItem(PyObject *iter) {
- PyObject *item;
- if (!(item = PyIter_Next(iter))) {
- if (!PyErr_Occurred())
- __Pyx_UnpackError();
- }
- return item;
-}
-
-static int __Pyx_EndUnpack(PyObject *iter) {
- PyObject *item;
- if ((item = PyIter_Next(iter))) {
- Py_DECREF(item);
- __Pyx_UnpackError();
- return -1;
- }
- else if (!PyErr_Occurred())
- return 0;
- else
- return -1;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-type_test_utility_code = [
-"""
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
-""","""
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
- if (!type) {
- PyErr_Format(PyExc_SystemError, "Missing type object");
- return 0;
- }
- if (obj == Py_None || PyObject_TypeCheck(obj, type))
- return 1;
- PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
- obj->ob_type->tp_name, type->tp_name);
- return 0;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-create_class_utility_code = [
-"""
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
-""","""
-static PyObject *__Pyx_CreateClass(
- PyObject *bases, PyObject *dict, PyObject *name, char *modname)
-{
- PyObject *py_modname;
- PyObject *result = 0;
-
- py_modname = PyString_FromString(modname);
- if (!py_modname)
- goto bad;
- if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
- goto bad;
- result = PyClass_New(bases, dict, name);
-bad:
- Py_XDECREF(py_modname);
- return result;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-getitem_int_utility_code = [
-"""
-static PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i); /*proto*/
-""","""
-static PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i) {
- PyTypeObject *t = o->ob_type;
- PyObject *r;
- if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
- r = PySequence_GetItem(o, i);
- else {
- PyObject *j = PyInt_FromLong(i);
- if (!j)
- return 0;
- r = PyObject_GetItem(o, j);
- Py_DECREF(j);
- }
- return r;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-setitem_int_utility_code = [
-"""
-static int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v); /*proto*/
-""","""
-static int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v) {
- PyTypeObject *t = o->ob_type;
- int r;
- if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
- r = PySequence_SetItem(o, i, v);
- else {
- PyObject *j = PyInt_FromLong(i);
- if (!j)
- return -1;
- r = PyObject_SetItem(o, j, v);
- Py_DECREF(j);
- }
- return r;
-}
-"""]
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py
deleted file mode 100644
index 09092e28..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Pyrex - Filename suffixes
-#
-
-cplus_suffix = ".cpp"
-pxd_suffixes = (".pxd",)
-pyx_suffixes = (".pyx", ".pyx+")
-package_init_files = ("__init__.py", "__init__.pyx", "__init__.pyx+")
-pyx_to_c_suffix = {".pyx": ".c", ".pyx+": cplus_suffix}
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle
deleted file mode 100644
index 1631a72c..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle
+++ /dev/null
Binary files differ
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py
deleted file mode 100644
index ca303c0d..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py
+++ /dev/null
@@ -1,145 +0,0 @@
-#
-# Pyrex Scanner - Lexical Definitions
-#
-# Changing anything in this file will cause Lexicon.pickle
-# to be rebuilt next time pyrexc is run.
-#
-
-string_prefixes = "cCrR"
-
-def make_lexicon():
- from Pyrex.Plex import \
- Str, Any, AnyBut, AnyChar, Rep, Rep1, Opt, Bol, Eol, Eof, \
- TEXT, IGNORE, State, Lexicon
- from Scanning import Method
-
- letter = Any("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_")
- digit = Any("0123456789")
- octdigit = Any("01234567")
- hexdigit = Any("0123456789ABCDEFabcdef")
- indentation = Bol + Rep(Any(" \t"))
-
- decimal = Rep1(digit)
- dot = Str(".")
- exponent = Any("Ee") + Opt(Any("+-")) + decimal
- decimal_fract = (decimal + dot + Opt(decimal)) | (dot + decimal)
-
- name = letter + Rep(letter | digit)
- intconst = decimal | (Str("0x") + Rep1(hexdigit))
- longconst = intconst + Str("L")
- fltconst = (decimal_fract + Opt(exponent)) | (decimal + exponent)
- imagconst = (intconst | fltconst) + Any("jJ")
-
-# sq_string = (
-# Str("'") +
-# Rep(AnyBut("\\\n'") | (Str("\\") + AnyChar)) +
-# Str("'")
-# )
-#
-# dq_string = (
-# Str('"') +
-# Rep(AnyBut('\\\n"') | (Str("\\") + AnyChar)) +
-# Str('"')
-# )
-#
-# non_sq = AnyBut("'") | (Str('\\') + AnyChar)
-# tsq_string = (
-# Str("'''")
-# + Rep(non_sq | (Str("'") + non_sq) | (Str("''") + non_sq))
-# + Str("'''")
-# )
-#
-# non_dq = AnyBut('"') | (Str('\\') + AnyChar)
-# tdq_string = (
-# Str('"""')
-# + Rep(non_dq | (Str('"') + non_dq) | (Str('""') + non_dq))
-# + Str('"""')
-# )
-#
-# stringlit = Opt(Any(string_prefixes)) + (sq_string | dq_string | tsq_string| tdq_string)
-
- beginstring = Opt(Any(string_prefixes)) + (Str("'") | Str('"') | Str("'''") | Str('"""'))
- two_oct = octdigit + octdigit
- three_oct = octdigit + octdigit + octdigit
- two_hex = hexdigit + hexdigit
- escapeseq = Str("\\") + (two_oct | three_oct | two_hex | AnyChar)
-
- bra = Any("([{")
- ket = Any(")]}")
- punct = Any(":,;+-*/|&<>=.%`~^?")
- diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**",
- "+=", "-=", "*=", "/=", "%=", "**=", "<<=", ">>=", "&=", "^=", "|=")
- spaces = Rep1(Any(" \t\f"))
- comment = Str("#") + Rep(AnyBut("\n"))
- escaped_newline = Str("\\\n")
- lineterm = Eol + Opt(Str("\n"))
-
- return Lexicon([
- (name, 'IDENT'),
- (intconst, 'INT'),
- (longconst, 'LONG'),
- (fltconst, 'FLOAT'),
- (imagconst, 'IMAG'),
- (punct | diphthong, TEXT),
-
- (bra, Method('open_bracket_action')),
- (ket, Method('close_bracket_action')),
- (lineterm, Method('newline_action')),
-
- #(stringlit, 'STRING'),
- (beginstring, Method('begin_string_action')),
-
- (comment, IGNORE),
- (spaces, IGNORE),
- (escaped_newline, IGNORE),
-
- State('INDENT', [
- (Opt(spaces) + Opt(comment) + lineterm, IGNORE),
- (indentation, Method('indentation_action')),
- (Eof, Method('eof_action'))
- ]),
-
- State('SQ_STRING', [
- (escapeseq, 'ESCAPE'),
- (Rep1(AnyBut("'\"\n\\")), 'CHARS'),
- (Str('"'), 'CHARS'),
- (Str("\n"), Method('unclosed_string_action')),
- (Str("'"), Method('end_string_action')),
- (Eof, 'EOF')
- ]),
-
- State('DQ_STRING', [
- (escapeseq, 'ESCAPE'),
- (Rep1(AnyBut('"\n\\')), 'CHARS'),
- (Str("'"), 'CHARS'),
- (Str("\n"), Method('unclosed_string_action')),
- (Str('"'), Method('end_string_action')),
- (Eof, 'EOF')
- ]),
-
- State('TSQ_STRING', [
- (escapeseq, 'ESCAPE'),
- (Rep1(AnyBut("'\"\n\\")), 'CHARS'),
- (Any("'\""), 'CHARS'),
- (Str("\n"), 'NEWLINE'),
- (Str("'''"), Method('end_string_action')),
- (Eof, 'EOF')
- ]),
-
- State('TDQ_STRING', [
- (escapeseq, 'ESCAPE'),
- (Rep1(AnyBut('"\'\n\\')), 'CHARS'),
- (Any("'\""), 'CHARS'),
- (Str("\n"), 'NEWLINE'),
- (Str('"""'), Method('end_string_action')),
- (Eof, 'EOF')
- ]),
-
- (Eof, Method('eof_action'))
- ],
-
- # FIXME: Plex 1.9 needs different args here from Plex 1.1.4
- #debug_flags = scanner_debug_flags,
- #debug_file = scanner_dump_file
- )
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py
deleted file mode 100644
index 2769b771..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py
+++ /dev/null
@@ -1,564 +0,0 @@
-#
-# Pyrex Top Level
-#
-
-import os, re, sys
-if sys.version_info[:2] < (2, 3):
- print >>sys.stderr, "Sorry, Pyrex requires Python 2.3 or later"
- sys.exit(1)
-
-import os
-from time import time
-import Builtin
-import Code
-import Errors
-import Parsing
-import Version
-from Errors import PyrexError, CompileError, error
-from Scanning import PyrexScanner
-from Symtab import BuiltinScope, DefinitionScope, ImplementationScope
-from Pyrex.Utils import set, replace_suffix, modification_time, \
- file_newer_than, castrate_file, map_suffix
-from Filenames import cplus_suffix, pxd_suffixes, pyx_suffixes, \
- package_init_files, pyx_to_c_suffix
-
-verbose = 0
-debug_timestamps = 0
-
-module_name_pattern = re.compile(
- r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$")
-
-class Context:
- # This class encapsulates the context needed for compiling
- # one or more Pyrex implementation files along with their
- # associated and imported declaration files. It holds
- # the root of the module import namespace and the list
- # of directories to search for include files.
- #
- # modules {string : DefinitionScope}
- # include_directories [string]
-
- def __init__(self, include_directories):
- self.modules = {"__builtin__" : Builtin.builtin_scope}
- self.include_directories = include_directories
-
- def find_module(self, module_name,
- relative_to = None, pos = None, need_pxd = 1):
- # Finds and returns the module scope corresponding to
- # the given relative or absolute module name. If this
- # is the first time the module has been requested, finds
- # the corresponding .pxd file and process it.
- # If relative_to is not None, it must be a module scope,
- # and the module will first be searched for relative to
- # that module, provided its name is not a dotted name.
- debug_find_module = 0
- if debug_find_module:
- print "Context.find_module: module_name =", module_name, \
- "relative_to =", relative_to, "pos =", pos, "need_pxd =", need_pxd
- scope = None
- pxd_pathname = None
- if "." not in module_name and relative_to:
- if debug_find_module:
- print "...trying relative import"
- scope = relative_to.lookup_submodule(module_name)
- if not scope:
- qualified_name = relative_to.qualify_name(module_name)
- pxd_pathname = self.find_pxd_file(qualified_name, pos)
- if pxd_pathname:
- scope = relative_to.find_submodule(module_name)
- if not scope:
- if debug_find_module:
- print "...trying absolute import"
- scope = self
- for name in module_name.split("."):
- scope = scope.find_submodule(name)
- if debug_find_module:
- print "...scope =", scope
- if not scope.pxd_file_loaded:
- if debug_find_module:
- print "...pxd not loaded"
- scope.pxd_file_loaded = 1
- if not pxd_pathname:
- if debug_find_module:
- print "...looking for pxd file"
- pxd_pathname = self.find_pxd_file(module_name, pos)
- if debug_find_module:
- print "......found ", pxd_pathname
- if not pxd_pathname and need_pxd:
- error(pos, "Cannot find .pxd file for module '%s'" % module_name)
- if pxd_pathname:
- try:
- if debug_find_module:
- print "Context.find_module: Parsing", pxd_pathname
- pxd_tree = self.parse(pxd_pathname, scope, pxd = 1)
- pxd_tree.analyse_declarations(scope)
- except CompileError:
- pass
- return scope
-
- def find_pxd_file(self, qualified_name, pos):
- # Search include path for the .pxd file corresponding to the
- # given fully-qualified module name.
- # Will find either a dotted filename or a file in a
- # package directory. If a source file position is given,
- # the directory containing the source file is searched first
- # for a dotted filename, and its containing package root
- # directory is searched first for a non-dotted filename.
- return self.search_package_directories(qualified_name, pxd_suffixes, pos)
-
- def find_pyx_file(self, qualified_name, pos):
- # Search include path for the .pyx file corresponding to the
- # given fully-qualified module name, as for find_pxd_file().
- return self.search_package_directories(qualified_name, pyx_suffixes, pos)
-
- def search_package_directories(self, qualified_name, suffixes, pos):
- dotted_filenames = [qualified_name + suffix for suffix in suffixes]
- if pos:
- here = os.path.dirname(pos[0])
- for dotted_filename in dotted_filenames:
- path = os.path.join(here, dotted_filename)
- if os.path.exists(path):
- return path
- dirs = self.include_directories
- if pos:
- here = self.find_root_package_dir(pos[0])
- dirs = [here] + dirs
- names = qualified_name.split(".")
- package_names = names[:-1]
- module_name = names[-1]
- filenames = [module_name + suffix for suffix in suffixes]
- for root in dirs:
- for dotted_filename in dotted_filenames:
- path = os.path.join(root, dotted_filename)
- if os.path.exists(path):
- return path
- dir = self.descend_to_package_dir(root, package_names)
- if dir:
- for filename in filenames:
- path = os.path.join(dir, filename)
- if os.path.exists(path):
- return path
- for init_filename in package_init_files:
- path = os.path.join(dir, module_name, init_filename)
- if os.path.exists(path):
- return path
-
- def find_root_package_dir(self, file_path):
- # Given the full pathname of a source file, find the directory
- # containing the top-level package that it ultimately belongs to.
- dir = os.path.dirname(file_path)
- while 1:
- if not self.is_package_dir(dir):
- return dir
- parent = os.path.dirname(dir)
- if parent == dir:
- return dir
- dir = parent
-
- def descend_to_package_dir(self, root_dir, package_names):
- # Starting from the given root directory, look for a nested
- # succession of package directories. Returns the full pathname
- # of the innermost one, or None.
- dir = root_dir
- for name in package_names:
- dir = os.path.join(dir, name)
- if self.is_package_dir(dir):
- return dir
-
- def is_package_dir(self, dir_path):
- # Return true if the given directory is a package directory.
- for filename in package_init_files:
- path = os.path.join(dir_path, filename)
- if os.path.exists(path):
- return 1
-
- def find_include_file(self, filename, pos):
- # Search list of include directories for filename.
- # Reports an error and returns None if not found.
- path = self.search_include_directories(filename, pos)
- if not path:
- error(pos, "'%s' not found" % filename)
- return path
-
- def search_include_directories(self, filename, pos):
- # Search the list of include directories for the given
- # file name. If a source file position is given, first
- # searches the directory containing that file. Returns
- # None if not found, but does not report an error.
- dirs = self.include_directories
- if pos:
- here_dir = os.path.dirname(pos[0])
- dirs = [here_dir] + dirs
- for dir in dirs:
- path = os.path.join(dir, filename)
- if os.path.exists(path):
- return path
- return None
-
- def lookup_submodule(self, name):
- # Look up a top-level module. Returns None if not found.
- return self.modules.get(name, None)
-
- def find_submodule(self, name):
- # Find a top-level module, creating a new one if needed.
- scope = self.lookup_submodule(name)
- if not scope:
- scope = DefinitionScope(name,
- parent_module = None, context = self)
- self.modules[name] = scope
- return scope
-
- def parse(self, source_filename, scope, pxd):
- # Parse the given source file and return a parse tree.
- f = open(source_filename, "rU")
- s = PyrexScanner(f, source_filename, scope = scope, context = self)
- try:
- tree = Parsing.p_module(s, pxd)
- finally:
- f.close()
- if Errors.num_errors > 0:
- raise CompileError
- return tree
-
- def extract_module_name(self, path):
- # Find fully_qualified module name from the full pathname
- # of a source file.
- dir, filename = os.path.split(path)
- module_name, _ = os.path.splitext(filename)
- if "." not in module_name:
- if module_name == "__init__":
- dir, module_name = os.path.split(dir)
- names = [module_name]
- while self.is_package_dir(dir):
- parent, package_name = os.path.split(dir)
- if parent == dir:
- break
- names.insert(0, package_name)
- dir = parent
- module_name = ".".join(names)
- if not module_name_pattern.match(module_name):
- raise CompileError((path, 0, 0),
- "'%s' is not a valid module name" % module_name)
- return module_name
-
- def dep_file_out_of_date(self, source_path):
- dep_path = replace_suffix(source_path, ".dep")
- if not os.path.exists(dep_path):
- return 1
- dep_time = modification_time(dep_path)
- return file_newer_than(source_path, dep_time)
-
- def c_file_out_of_date(self, source_path):
- if debug_timestamps:
- print "Checking whether", source_path, "is out of date"
- c_path = map_suffix(source_path, pyx_to_c_suffix, ".c")
- if not os.path.exists(c_path):
- if debug_timestamps:
- print "...yes, c file doesn't exist"
- return 1
- c_time = modification_time(c_path)
- if file_newer_than(source_path, c_time):
- if debug_timestamps:
- print "...yes, newer than c file"
- return 1
- pos = [source_path]
- module_name = self.extract_module_name(source_path)
- pxd_path = self.find_pxd_file(module_name, pos)
- if pxd_path and file_newer_than(pxd_path, c_time):
- if debug_timestamps:
- print "...yes, pxd file newer than c file"
- return 1
- dep_path = replace_suffix(source_path, ".dep")
- if not os.path.exists(dep_path):
- if debug_timestamps:
- print "...yes, dep file does not exist"
- return 1
- for kind, name in self.read_dependency_file(source_path):
- if kind == "cimport":
- dep_path = self.find_pxd_file(name, pos)
- elif kind == "include":
- dep_path = self.search_include_directories(name, pos)
- else:
- continue
- if dep_path and file_newer_than(dep_path, c_time):
- if debug_timestamps:
- print "...yes,", dep_path, "newer than c file"
- return 1
- if debug_timestamps:
- print "...no"
-
- def find_cimported_module_names(self, source_path):
- for kind, name in self.read_dependency_file(source_path):
- if kind == "cimport":
- yield name
-
- def read_dependency_file(self, source_path):
- dep_path = replace_suffix(source_path, ".dep")
- if os.path.exists(dep_path):
- f = open(dep_path, "rU")
- for line in f.readlines():
- chunks = line.strip().split(" ", 1)
- if len(chunks) == 2:
- yield chunks
- f.close()
-
- def compile(self, source, options = None):
- # Compile a Pyrex implementation file in this context
- # and return a CompilationResult.
- if not options:
- options = default_options
- result = CompilationResult()
- cwd = os.getcwd()
- source = os.path.join(cwd, source)
- if options.use_listing_file:
- result.listing_file = replace_suffix(source, ".lis")
- Errors.open_listing_file(result.listing_file,
- echo_to_stderr = options.errors_to_stderr)
- else:
- Errors.open_listing_file(None)
- if options.output_file:
- result.c_file = os.path.join(cwd, options.output_file)
- else:
- if options.cplus:
- result.c_file = replace_suffix(source, cplus_suffix)
- else:
- result.c_file = map_suffix(source, pyx_to_c_suffix, ".c")
- module_name = self.extract_module_name(source)
- initial_pos = (source, 1, 0)
- def_scope = self.find_module(module_name, pos = initial_pos, need_pxd = 0)
- imp_scope = ImplementationScope(def_scope)
- errors_occurred = False
- try:
- tree = self.parse(source, imp_scope, pxd = 0)
- tree.process_implementation(imp_scope, options, result)
- except CompileError:
- errors_occurred = True
- Errors.close_listing_file()
- result.num_errors = Errors.num_errors
- if result.num_errors > 0:
- errors_occurred = True
- if errors_occurred and result.c_file:
- try:
- st = os.stat(source)
- castrate_file(result.c_file, st)
- except EnvironmentError:
- pass
- result.c_file = None
- if result.c_file and not options.c_only and c_compile:
- result.object_file = c_compile(result.c_file,
- verbose_flag = options.show_version,
- cplus = options.cplus)
- if not options.obj_only and c_link:
- result.extension_file = c_link(result.object_file,
- extra_objects = options.objects,
- verbose_flag = options.show_version,
- cplus = options.cplus)
- return result
-
-#------------------------------------------------------------------------
-#
-# Main Python entry points
-#
-#------------------------------------------------------------------------
-
-class CompilationOptions:
- """
- Options to the Pyrex compiler:
-
- show_version boolean Display version number
- use_listing_file boolean Generate a .lis file
- errors_to_stderr boolean Echo errors to stderr when using .lis
- include_path [string] Directories to search for include files
- output_file string Name of generated .c file
- generate_pxi boolean Generate .pxi file for public declarations
- recursive boolean Recursively find and compile dependencies
- timestamps boolean Only compile changed source files. If None,
- defaults to true when recursive is true.
- verbose boolean Always print source names being compiled
- quiet boolean Don't print source names in recursive mode
-
- Following options are experimental and only used on MacOSX:
-
- c_only boolean Stop after generating C file (default)
- obj_only boolean Stop after compiling to .o file
- objects [string] Extra .o files to link with
- cplus boolean Compile as c++ code
- """
-
- def __init__(self, defaults = None, c_compile = 0, c_link = 0, **kw):
- self.include_path = []
- self.objects = []
- if defaults:
- if isinstance(defaults, CompilationOptions):
- defaults = defaults.__dict__
- else:
- defaults = default_options
- self.__dict__.update(defaults)
- self.__dict__.update(kw)
- if c_compile:
- self.c_only = 0
- if c_link:
- self.obj_only = 0
-
-
-class CompilationResult:
- """
- Results from the Pyrex compiler:
-
- c_file string or None The generated C source file
- h_file string or None The generated C header file
- i_file string or None The generated .pxi file
- api_file string or None The generated C API .h file
- listing_file string or None File of error messages
- object_file string or None Result of compiling the C file
- extension_file string or None Result of linking the object file
- num_errors integer Number of compilation errors
- """
-
- def __init__(self):
- self.c_file = None
- self.h_file = None
- self.i_file = None
- self.api_file = None
- self.listing_file = None
- self.object_file = None
- self.extension_file = None
-
-
-class CompilationResultSet(dict):
- """
- Results from compiling multiple Pyrex source files. A mapping
- from source file paths to CompilationResult instances. Also
- has the following attributes:
-
- num_errors integer Total number of compilation errors
- """
-
- num_errors = 0
-
- def add(self, source, result):
- self[source] = result
- self.num_errors += result.num_errors
-
-
-def compile_single(source, options):
- """
- compile_single(source, options)
-
- Compile the given Pyrex implementation file and return a CompilationResult.
- Always compiles a single file; does not perform timestamp checking or
- recursion.
- """
- context = Context(options.include_path)
- return context.compile(source, options)
-
-def compile_multiple(sources, options):
- """
- compile_multiple(sources, options)
-
- Compiles the given sequence of Pyrex implementation files and returns
- a CompilationResultSet. Performs timestamp checking and/or recursion
- if these are specified in the options.
- """
- sources = [os.path.abspath(source) for source in sources]
- processed = set()
- results = CompilationResultSet()
- context = Context(options.include_path)
- recursive = options.recursive
- timestamps = options.timestamps
- if timestamps is None:
- timestamps = recursive
- verbose = options.verbose or ((recursive or timestamps) and not options.quiet)
- for source in sources:
- if source not in processed:
- if not timestamps or context.c_file_out_of_date(source):
- if verbose:
- print >>sys.stderr, "Compiling", source
- result = context.compile(source, options)
- results.add(source, result)
- processed.add(source)
- if recursive:
- for module_name in context.find_cimported_module_names(source):
- path = context.find_pyx_file(module_name, [source])
- if path:
- sources.append(path)
- else:
- print >>sys.stderr, \
- "Cannot find .pyx file for cimported module '%s'" % module_name
- return results
-
-def compile(source, options = None, c_compile = 0, c_link = 0, **kwds):
- """
- compile(source [, options], [, <option> = <value>]...)
-
- Compile one or more Pyrex implementation files, with optional timestamp
- checking and recursing on dependecies. The source argument may be a string
- or a sequence of strings. If it is a string and no recursion or timestamp
- checking is requested, a CompilationResult is returned, otherwise a
- CompilationResultSet is returned.
- """
- options = CompilationOptions(defaults = options, c_compile = c_compile,
- c_link = c_link, **kwds)
- if isinstance(source, basestring) and not options.timestamps \
- and not options.recursive:
- return compile_single(source, options)
- else:
- return compile_multiple(source, options)
-
-#------------------------------------------------------------------------
-#
-# Main command-line entry point
-#
-#------------------------------------------------------------------------
-
-def main(command_line = 0):
- args = sys.argv[1:]
- any_failures = 0
- if command_line:
- from CmdLine import parse_command_line
- options, sources = parse_command_line(args)
- else:
- options = CompilationOptions(default_options)
- sources = args
- if options.show_version:
- print >>sys.stderr, "Pyrex version %s" % Version.version
- try:
- result = compile(sources, options)
- if result.num_errors > 0:
- any_failures = 1
- except EnvironmentError, e:
- print >>sys.stderr, e
- any_failures = 1
- if any_failures:
- sys.exit(1)
-
-#------------------------------------------------------------------------
-#
-# Set the default options depending on the platform
-#
-#------------------------------------------------------------------------
-
-default_options = dict(
- show_version = 0,
- use_listing_file = 0,
- errors_to_stderr = 1,
- c_only = 1,
- obj_only = 1,
- cplus = 0,
- output_file = None,
- generate_pxi = 0,
- recursive = 0,
- timestamps = None,
- verbose = 0,
- quiet = 0)
-
-if sys.platform == "mac":
- from Pyrex.Mac.MacSystem import c_compile, c_link, CCompilerError
- default_options['use_listing_file'] = 1
-elif sys.platform == "darwin":
- from Pyrex.Mac.DarwinSystem import c_compile, c_link, CCompilerError
-else:
- c_compile = None
- c_link = None
-
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py
deleted file mode 100644
index 9c2b0a31..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py
+++ /dev/null
@@ -1,1678 +0,0 @@
-#
-# Pyrex - Module parse tree node
-#
-
-import os, time
-from cStringIO import StringIO
-from PyrexTypes import CPtrType, py_object_type, typecast
-from Pyrex.Utils import set
-
-# Following is set by Testing.py to suppress filename/date comments
-# in generated files, so as not to produce spurious changes in test
-# reference files.
-
-testing_mode = False
-
-
-import Code
-import Naming
-import Nodes
-import Options
-import PyrexTypes
-import TypeSlots
-import Version
-
-from Errors import error
-from PyrexTypes import py_object_type
-from Pyrex.Utils import open_new_file, replace_suffix
-
-class ModuleNode(Nodes.Node, Nodes.BlockNode):
- # doc string or None
- # body StatListNode
- #
- # referenced_modules [ModuleScope]
- # module_temp_cname string
-
- def analyse_declarations(self, env):
- env.doc = self.doc
- self.body.analyse_declarations(env)
-
- def process_implementation(self, env, options, result):
- self.analyse_declarations(env)
- env.check_c_classes()
- self.body.analyse_expressions(env)
- env.return_type = PyrexTypes.c_void_type
- self.referenced_modules = self.find_referenced_modules(env)
- if self.has_imported_c_functions():
- self.module_temp_cname = env.allocate_temp_pyobject()
- env.release_temp(self.module_temp_cname)
- if options.timestamps or options.recursive:
- self.generate_dep_file(env, result)
- self.generate_c_code(env, result)
- self.generate_h_code(env, options, result)
- self.generate_api_code(env, result)
-
- def has_imported_c_functions(self):
- for module in self.referenced_modules:
- for entry in module.cfunc_entries:
- if entry.defined_in_pxd:
- return 1
- return 0
-
- def generate_dep_file(self, env, result):
- modules = self.referenced_modules
- includes = set(env.pyrex_include_files)
- for module in modules:
- for include in module.pyrex_include_files:
- includes.add(include)
- if len(modules) > 1 or includes:
- include_list = list(includes)
- include_list.sort()
- dep_file = replace_suffix(result.c_file, ".dep")
- f = open(dep_file, "w")
- try:
- for module in modules[:-1]:
- f.write("cimport %s\n" % module.qualified_name)
- for path in include_list:
- f.write("include %s\n" % path)
- finally:
- f.close()
-
- def generate_h_code(self, env, options, result):
- def pub(entries): #, pxd = 0):
- return [entry for entry in entries
- if entry.visibility == 'public'] # or pxd and entry.defined_in_pxd]
- denv = env.definition_scope
- h_types = pub(denv.type_entries) + pub(env.type_entries)
- h_vars = pub(denv.var_entries) + pub(env.var_entries)
- h_funcs = pub(denv.cfunc_entries) + pub(env.cfunc_entries)
- h_extension_types = pub(denv.c_class_entries) + pub(env.c_class_entries)
- if h_types or h_vars or h_funcs or h_extension_types:
- result.h_file = replace_suffix(result.c_file, ".h")
- h_code = Code.CCodeWriter(open_new_file(result.h_file))
- if options.generate_pxi:
- result.i_file = replace_suffix(result.c_file, ".pxi")
- i_code = Code.PyrexCodeWriter(result.i_file)
- else:
- i_code = None
- guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
- h_code.put_h_guard(guard)
- self.generate_extern_c_macro_definition(h_code)
- self.generate_type_header_code(h_types, h_code)
- h_code.putln("")
- h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
- if h_vars:
- h_code.putln("")
- for entry in h_vars:
- self.generate_public_declaration(entry, h_code, i_code)
- if h_funcs:
- h_code.putln("")
- for entry in h_funcs:
- self.generate_public_declaration(entry, h_code, i_code)
- if h_extension_types:
- h_code.putln("")
- for entry in h_extension_types:
- self.generate_cclass_header_code(entry.type, h_code)
- if i_code:
- self.generate_cclass_include_code(entry.type, i_code)
- h_code.putln("")
- h_code.putln("#endif")
- h_code.putln("")
- h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
- h_code.putln("")
- h_code.putln("#endif")
-
- def generate_public_declaration(self, entry, h_code, i_code):
- h_code.putln("%s %s;" % (
- Naming.extern_c_macro,
- entry.type.declaration_code(
- entry.cname, dll_linkage = "DL_IMPORT")))
- if i_code:
- i_code.putln("cdef extern %s" %
- entry.type.declaration_code(entry.cname, pyrex = 1))
-
- def api_name(self, env):
- return env.qualified_name.replace(".", "__")
-
- def generate_api_code(self, env, result):
- denv = env.definition_scope
- api_funcs = []
- public_extension_types = []
- has_api_extension_types = 0
- for entry in denv.cfunc_entries:
- if entry.api:
- api_funcs.append(entry)
- for entry in env.cfunc_entries:
- if entry.api:
- api_funcs.append(entry)
- for entry in denv.c_class_entries + env.c_class_entries:
- if entry.visibility == 'public':
- public_extension_types.append(entry)
- if entry.api:
- has_api_extension_types = 1
- if api_funcs or has_api_extension_types:
- result.api_file = replace_suffix(result.c_file, "_api.h")
- h_code = Code.CCodeWriter(open_new_file(result.api_file))
- name = self.api_name(env)
- guard = Naming.api_guard_prefix + name
- h_code.put_h_guard(guard)
- h_code.putln('#include "Python.h"')
- if result.h_file:
- h_code.putln('#include "%s"' % os.path.basename(result.h_file))
- for entry in public_extension_types:
- type = entry.type
- h_code.putln("")
- h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
- h_code.putln("#define %s (*%s)" % (
- type.typeobj_cname, type.typeptr_cname))
- if api_funcs:
- h_code.putln("")
- for entry in api_funcs:
- type = CPtrType(entry.type)
- h_code.putln("static %s;" % type.declaration_code(entry.cname))
- h_code.putln("")
- h_code.put_h_guard(Naming.api_func_guard + "import_module")
- h_code.put(import_module_utility_code[1])
- h_code.putln("")
- h_code.putln("#endif")
- if api_funcs:
- h_code.putln("")
- h_code.put(function_import_utility_code[1])
- if public_extension_types:
- h_code.putln("")
- h_code.put(type_import_utility_code[1])
- h_code.putln("")
- h_code.putln("static int import_%s(void) {" % name)
- h_code.putln("PyObject *module = 0;")
- h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
- h_code.putln("if (!module) goto bad;")
- for entry in api_funcs:
- sig = entry.type.signature_string()
- h_code.putln(
- 'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % (
- entry.name,
- entry.cname,
- sig))
- h_code.putln("Py_DECREF(module); module = 0;")
- for entry in public_extension_types:
- self.generate_type_import_call(entry.type, h_code, "goto bad;")
- h_code.putln("return 0;")
- h_code.putln("bad:")
- h_code.putln("Py_XDECREF(module);")
- h_code.putln("return -1;")
- h_code.putln("}")
- h_code.putln("")
- h_code.putln("#endif")
-
- def generate_cclass_header_code(self, type, h_code):
- h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
- Naming.extern_c_macro,
- type.typeobj_cname))
- #self.generate_obj_struct_definition(type, h_code)
-
- def generate_cclass_include_code(self, type, i_code):
- i_code.putln("cdef extern class %s.%s:" % (
- type.module_name, type.name))
- i_code.indent()
- var_entries = type.scope.var_entries
- if var_entries:
- for entry in var_entries:
- i_code.putln("cdef %s" %
- entry.type.declaration_code(entry.cname, pyrex = 1))
- else:
- i_code.putln("pass")
- i_code.dedent()
-
- def generate_c_code(self, env, result):
- code = Code.MainCCodeWriter(StringIO())
- code.h = Code.CCodeWriter(StringIO())
- code.init_labels()
-
- modules = self.referenced_modules
- self.generate_module_preamble(env, modules, code.h)
-
- code.putln("")
- code.putln("/* Implementation of %s */" % env.qualified_name)
- #self.generate_const_definitions(env, code)
- #self.generate_interned_name_decls(env, code)
- #self.generate_py_string_decls(env, code)
- self.body.generate_function_definitions(env, code)
- #self.generate_interned_name_table(env, code)
- #self.generate_py_string_table(env, code)
- self.generate_typeobj_definitions(env, code)
- self.generate_method_table(env, code)
- self.generate_filename_init_prototype(code)
- self.generate_module_init_func(modules[:-1], env, code)
- self.generate_filename_table(code)
- self.generate_utility_functions(code)
-
- denv = env.definition_scope
- for module in modules:
- code.h.putln("")
- code.h.putln("/* Declarations from %s */" % module.qualified_name)
- self.generate_declarations_for_module(module, code.h,
- implementation = module is denv)
-
- code.h.putln("")
- code.h.putln("/* Declarations from implementation of %s */" %
- env.qualified_name)
- self.generate_declarations_for_module(env, code.h, implementation = 1)
- code.global_state.generate_const_declarations(code.h)
- #self.generate_interned_name_table(code.interned_strings, code.h)
- #self.generate_py_string_table(code.py_strings, code.h)
- self.generate_default_value_declarations(env, code.h)
-
- f = open_new_file(result.c_file)
- f.write(code.h.f.getvalue())
- f.write("\n")
- f.write(code.f.getvalue())
- f.close()
- result.c_file_generated = 1
-
- def find_referenced_modules(self, env):
- # Given the ImplementationScope, find the DefinitionScopes of all
- # modules cimported, directly or indirectly. Includes this module's
- # DefinitionScope as the last entry in the list.
- denv = env.definition_scope
- module_list = []
- modules_seen = set()
- def add_module(module):
- if module not in modules_seen:
- modules_seen.add(module)
- add_modules(module.cimported_modules)
- module_list.append(module)
- def add_modules(modules):
- for module in modules:
- add_module(module)
- modules_seen.add(denv)
- add_modules(denv.cimported_modules)
- add_modules(env.cimported_modules)
- module_list.append(denv)
- #self.print_referenced_modules(module_list) ###
- return module_list
-
- def print_referenced_modules(self, module_list):
- print "find_referenced_modules: result =",
- for m in module_list:
- print m,
- print
-
- def generate_module_preamble(self, env, cimported_modules, code):
- comment = "Generated by Pyrex"
- if not testing_mode:
- comment = "%s %s on %s" % (comment, Version.version, time.asctime())
- code.putln('/* %s */' % comment)
- code.putln('')
- code.putln('#define PY_SSIZE_T_CLEAN')
- for filename in env.python_include_files:
- code.putln('#include "%s"' % filename)
- code.putln("#ifndef PY_LONG_LONG")
- code.putln(" #define PY_LONG_LONG LONG_LONG")
- code.putln("#endif")
- code.putln("#if PY_VERSION_HEX < 0x02050000")
- code.putln(" typedef int Py_ssize_t;")
- code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
- code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
- code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
- code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
- code.putln("#endif")
- code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
- code.putln(" #ifndef __stdcall")
- code.putln(" #define __stdcall")
- code.putln(" #endif")
- code.putln(" #ifndef __cdecl")
- code.putln(" #define __cdecl")
- code.putln(" #endif")
- code.putln("#endif")
- self.generate_extern_c_macro_definition(code)
- code.putln("#include <math.h>")
- self.generate_includes(env, cimported_modules, code)
- code.putln('')
- code.put(Nodes.utility_function_predeclarations)
- code.putln('')
- code.putln('static PyObject *%s;' % env.module_cname)
- code.putln('static PyObject *%s;' % Naming.builtins_cname)
- code.putln('static int %s;' % Naming.lineno_cname)
- code.putln('static char *%s;' % Naming.filename_cname)
- code.putln('static char **%s;' % Naming.filetable_cname)
- doc = None
- doc1 = env.definition_scope.doc
- doc2 = env.doc
- if doc1 and doc2:
- doc = "%s\\n%s" % (doc1, doc2)
- else:
- doc = doc1 or doc2
- if doc:
- code.putln('')
- code.putln('static char %s[] = "%s";' % (env.doc_cname, doc))
-
- def generate_extern_c_macro_definition(self, code):
- name = Naming.extern_c_macro
- code.putln("#ifdef __cplusplus")
- code.putln('#define %s extern "C"' % name)
- code.putln("#else")
- code.putln("#define %s extern" % name)
- code.putln("#endif")
-
- def generate_includes(self, env, cimported_modules, code):
- includes = []
- for module in cimported_modules + [env]:
- for filename in module.include_files:
- if filename not in includes:
- includes.append(filename)
- for filename in includes:
- code.putln('#include "%s"' % filename)
-
- def generate_filename_table(self, code):
- code.global_state.generate_filename_table(code)
-
- def generate_declarations_for_module(self, env, code, implementation):
- self.generate_type_predeclarations(env, code)
- self.generate_type_definitions(env, code) #, implementation)
- self.generate_global_declarations(env, code, implementation)
- self.generate_cfunction_predeclarations(env, code, implementation)
-
- def generate_type_predeclarations(self, env, code):
- pass
-
- def generate_type_header_code(self, type_entries, code):
- # Generate definitions of structs/unions/enums/typedefs/objstructs.
- #self.generate_gcc33_hack(env, code) # Is this still needed?
- #for entry in env.type_entries:
- for entry in type_entries:
- if not entry.in_cinclude:
- #print "generate_type_header_code:", entry.name, repr(entry.type) ###
- type = entry.type
- if type.is_typedef: # Must test this first!
- self.generate_typedef(entry, code)
- elif type.is_struct_or_union:
- self.generate_struct_union_definition(entry, code)
- elif type.is_enum:
- self.generate_enum_definition(entry, code)
- elif type.is_extension_type:
- self.generate_obj_struct_definition(type, code)
-
- def generate_type_definitions(self, env, code): #, implementation):
- #print "generate_type_definitions:", env ###
- type_entries = env.type_entries
- self.generate_type_header_code(type_entries, code)
- for entry in env.c_class_entries:
- if not entry.in_cinclude:
- self.generate_typeobject_predeclaration(entry, code)
- self.generate_exttype_vtable_struct(entry, code)
- self.generate_exttype_vtabptr_declaration(entry, code)
-
- def generate_typedef(self, entry, code):
- base_type = entry.type.typedef_base_type
- code.putln("")
- code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
-
- def sue_header_footer(self, type, kind, name):
- if type.typedef_flag:
- header = "typedef %s {" % kind
- footer = "} %s;" % name
- else:
- header = "%s %s {" % (kind, name)
- footer = "};"
- return header, footer
-
- def generate_struct_union_definition(self, entry, code):
- type = entry.type
- scope = type.scope
- if scope:
- header, footer = \
- self.sue_header_footer(type, type.kind, type.cname)
- code.putln("")
- code.putln(header)
- var_entries = scope.var_entries
- if not var_entries and not scope.cfunc_entries:
- error(entry.pos,
- "Empty struct or union definition not allowed outside a"
- " 'cdef extern from' block")
- for attr in var_entries:
- code.putln(
- "%s;" %
- attr.type.declaration_code(attr.cname))
- code.putln(footer)
-
- def generate_enum_definition(self, entry, code):
- type = entry.type
- name = entry.cname or entry.name or ""
- header, footer = \
- self.sue_header_footer(type, "enum", name)
- code.putln("")
- code.putln(header)
- enum_values = entry.enum_values
- if not enum_values:
- error(entry.pos,
- "Empty enum definition not allowed outside a"
- " 'cdef extern from' block")
- else:
- last_entry = enum_values[-1]
- for value_entry in enum_values:
- if value_entry.value == value_entry.name:
- value_code = value_entry.cname
- else:
- value_code = ("%s = %s" % (
- value_entry.cname,
- value_entry.value))
- if value_entry is not last_entry:
- value_code += ","
- code.putln(value_code)
- code.putln(footer)
-
- def generate_typeobject_predeclaration(self, entry, code):
- code.putln("")
- name = entry.type.typeobj_cname
- if name:
- if entry.visibility == 'extern' and not entry.in_cinclude:
- code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
- Naming.extern_c_macro,
- name))
- elif entry.visibility == 'public':
- #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
- code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
- Naming.extern_c_macro,
- name))
-
- def generate_exttype_vtable_struct(self, entry, code):
- # Generate struct declaration for an extension type's vtable.
- type = entry.type
- scope = type.scope
- if type.vtabstruct_cname:
- code.putln("")
- code.putln(
- "struct %s {" %
- type.vtabstruct_cname)
- if type.base_type and type.base_type.vtabstruct_cname:
- code.putln("struct %s %s;" % (
- type.base_type.vtabstruct_cname,
- Naming.obj_base_cname))
- for method_entry in scope.cfunc_entries:
- if not method_entry.is_inherited:
- code.putln(
- "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
- code.putln(
- "};")
-
- def generate_exttype_vtabptr_declaration(self, entry, code):
- # Generate declaration of pointer to an extension type's vtable.
- type = entry.type
- if type.vtabptr_cname:
- code.putln("static struct %s *%s;" % (
- type.vtabstruct_cname,
- type.vtabptr_cname))
-
- def generate_obj_struct_definition(self, type, code):
- # Generate object struct definition for an
- # extension type.
- if not type.scope:
- return # Forward declared but never defined
- header, footer = \
- self.sue_header_footer(type, "struct", type.objstruct_cname)
- code.putln("")
- code.putln(header)
- base_type = type.base_type
- if base_type:
- code.putln(
- "%s%s %s;" % (
- ("struct ", "")[base_type.typedef_flag],
- base_type.objstruct_cname,
- Naming.obj_base_cname))
- else:
- code.putln(
- "PyObject_HEAD")
- if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
- code.putln(
- "struct %s *%s;" % (
- type.vtabstruct_cname,
- type.vtabslot_cname))
- for attr in type.scope.var_entries:
- code.putln(
- "%s;" %
- attr.type.declaration_code(attr.cname))
- code.putln(footer)
-
- def generate_global_declarations(self, env, code, implementation):
- code.putln("")
- for entry in env.c_class_entries:
- if implementation or entry.defined_in_pxd:
- code.putln("static PyTypeObject *%s = 0;" %
- entry.type.typeptr_cname)
- #code.putln("/* var_entries */") ###
- code.put_var_declarations(env.var_entries, static = 1,
- dll_linkage = "DL_EXPORT", definition = implementation)
-
- def generate_default_value_declarations(self, env, code):
- #code.putln("/* default_entries */") ###
- code.putln("")
- code.put_var_declarations(env.default_entries, static = 1)
-
- def generate_cfunction_predeclarations(self, env, code, implementation):
- for entry in env.cfunc_entries:
- if not entry.in_cinclude:
- # and (definition or entry.defined_in_pxd or
- # entry.visibility == 'extern'):
- if entry.visibility in ('public', 'extern'):
- dll_linkage = "DL_EXPORT"
- else:
- dll_linkage = None
- type = entry.type
- if not implementation: #and entry.defined_in_pxd:
- type = CPtrType(type)
- header = type.declaration_code(entry.cname,
- dll_linkage = dll_linkage)
- if entry.visibility <> 'private':
- storage_class = "%s " % Naming.extern_c_macro
- else:
- storage_class = "static "
- code.putln("%s%s; /*proto*/" % (
- storage_class,
- header))
-
- def generate_typeobj_definitions(self, env, code):
- full_module_name = env.qualified_name
- denv = env.definition_scope
- for entry in denv.c_class_entries + env.c_class_entries:
- #print "generate_typeobj_definitions:", entry.name
- #print "...visibility =", entry.visibility
- if entry.visibility <> 'extern':
- type = entry.type
- scope = type.scope
- if scope: # could be None if there was an error
- self.generate_exttype_vtable(scope, code)
- self.generate_new_function(scope, code)
- self.generate_dealloc_function(scope, code)
- self.generate_traverse_function(scope, code)
- self.generate_clear_function(scope, code)
- if scope.defines_any(["__getitem__"]):
- self.generate_getitem_int_function(scope, code)
- if scope.defines_any(["__setitem__", "__delitem__"]):
- self.generate_ass_subscript_function(scope, code)
- if scope.defines_any(["__setslice__", "__delslice__"]):
- self.generate_ass_slice_function(scope, code)
- if scope.defines_any(["__getattr__"]):
- self.generate_getattro_function(scope, code)
- if scope.defines_any(["__setattr__", "__delattr__"]):
- self.generate_setattro_function(scope, code)
- if scope.defines_any(["__get__"]):
- self.generate_descr_get_function(scope, code)
- if scope.defines_any(["__set__", "__delete__"]):
- self.generate_descr_set_function(scope, code)
- self.generate_property_accessors(scope, code)
- self.generate_method_table(scope, code)
- self.generate_member_table(scope, code)
- self.generate_getset_table(scope, code)
- self.generate_typeobj_definition(full_module_name, entry, code)
-
- def generate_exttype_vtable(self, scope, code):
- # Generate the definition of an extension type's vtable.
- type = scope.parent_type
- if type.vtable_cname:
- code.putln("static struct %s %s;" % (
- type.vtabstruct_cname,
- type.vtable_cname))
-
- def generate_self_cast(self, scope, code):
- type = scope.parent_type
- code.putln(
- "%s = (%s)o;" % (
- type.declaration_code("p"),
- type.declaration_code("")))
-
- def generate_new_function(self, scope, code):
- type = scope.parent_type
- base_type = type.base_type
- py_attrs = []
- for entry in scope.var_entries:
- if entry.type.is_pyobject:
- py_attrs.append(entry)
- need_self_cast = type.vtabslot_cname or py_attrs
- code.putln("")
- code.putln(
- "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
- % scope.mangle_internal("tp_new"))
- if need_self_cast:
- code.putln(
- "%s;"
- % scope.parent_type.declaration_code("p"))
- if base_type:
- code.putln(
- "PyObject *o = %s->tp_new(t, a, k);" %
- base_type.typeptr_cname)
- else:
- code.putln(
- "PyObject *o = (*t->tp_alloc)(t, 0);")
- code.putln(
- "if (!o) return 0;")
- if need_self_cast:
- code.putln(
- "p = %s;"
- % type.cast_code("o"))
- #if need_self_cast:
- # self.generate_self_cast(scope, code)
- if type.vtabslot_cname:
- code.putln("*(struct %s **)&p->%s = %s;" % (
- type.vtabstruct_cname,
- type.vtabslot_cname,
- type.vtabptr_cname))
- for entry in py_attrs:
- if entry.name == "__weakref__":
- code.putln("p->%s = 0;" % entry.cname)
- else:
- code.put_init_var_to_py_none(entry, "p->%s")
- entry = scope.lookup_here("__new__")
- if entry:
- code.putln(
- "if (%s(o, a, k) < 0) {" %
- entry.func_cname)
- code.put_decref_clear("o", py_object_type);
- code.putln(
- "}")
- code.putln(
- "return o;")
- code.putln(
- "}")
-
- def generate_dealloc_function(self, scope, code):
- base_type = scope.parent_type.base_type
- code.putln("")
- code.putln(
- "static void %s(PyObject *o) {"
- % scope.mangle_internal("tp_dealloc"))
- #py_attrs = []
- #for entry in scope.var_entries:
- # if entry.type.is_pyobject and entry.name <> "__weakref__":
- # py_attrs.append(entry)
- py_attrs = scope.pyattr_entries
- if py_attrs:
- self.generate_self_cast(scope, code)
- self.generate_usr_dealloc_call(scope, code)
- if scope.lookup_here("__weakref__"):
- code.putln("PyObject_ClearWeakRefs(o);")
- for entry in py_attrs:
- code.put_xdecref("p->%s" % entry.cname, entry.type)
- if base_type:
- code.putln(
- "%s->tp_dealloc(o);" %
- base_type.typeptr_cname)
- else:
- code.putln(
- "(*o->ob_type->tp_free)(o);")
- code.putln(
- "}")
-
- def generate_usr_dealloc_call(self, scope, code):
- entry = scope.lookup_here("__dealloc__")
- if entry:
- code.putln(
- "{")
- code.putln(
- "PyObject *etype, *eval, *etb;")
- code.putln(
- "PyErr_Fetch(&etype, &eval, &etb);")
- code.putln(
- "++o->ob_refcnt;")
- code.putln(
- "%s(o);" %
- entry.func_cname)
- code.putln(
- "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
- code.putln(
- "--o->ob_refcnt;")
- code.putln(
- "PyErr_Restore(etype, eval, etb);")
- code.putln(
- "}")
-
- def generate_traverse_function(self, scope, code):
- py_attrs = scope.pyattr_entries
- if py_attrs:
- base_type = scope.parent_type.base_type
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, visitproc v, void *a) {"
- % scope.mangle_internal("tp_traverse"))
- code.putln(
- "int e;")
- self.generate_self_cast(scope, code)
- if base_type:
- code.putln(
- "traverseproc t;")
- code.putln(
- "if ((t = %s->tp_traverse)) {" %
- base_type.typeptr_cname)
- code.putln(
- "e = t(o, v, a); if (e) return e;")
- code.putln(
- "}")
- for entry in py_attrs:
- var_code = "p->%s" % entry.cname
- code.putln(
- "if (%s) {"
- % var_code)
- if entry.type.is_extension_type:
- var_code = "((PyObject*)%s)" % var_code
- code.putln(
- "e = (*v)(%s, a); if (e) return e;"
- % var_code)
- code.putln(
- "}")
- code.putln(
- "return 0;")
- code.putln(
- "}")
-
- def generate_clear_function(self, scope, code):
- py_attrs = scope.pyattr_entries
- if py_attrs:
- base_type = scope.parent_type.base_type
- code.putln("")
- code.putln(
- "static int %s(PyObject *o) {"
- % scope.mangle_internal("tp_clear"))
- self.generate_self_cast(scope, code)
- code.putln(
- "PyObject *t;")
- if base_type:
- code.putln(
- "inquiry c;")
- code.putln(
- "if ((c = %s->tp_clear)) {" %
- base_type.typeptr_cname)
- code.putln(
- "c(o);")
- code.putln(
- "}")
- for entry in py_attrs:
- name = "p->%s" % entry.cname
- code.putln(
- "t = %s; " %
- typecast(py_object_type, entry.type, name))
- code.put_init_var_to_py_none(entry, "p->%s")
- #code.put_xdecref(name, entry.type)
- code.putln(
- "Py_XDECREF(t);")
- code.putln(
- "return 0;")
- code.putln(
- "}")
-
- def generate_getitem_int_function(self, scope, code):
- # This function is put into the sq_item slot when
- # a __getitem__ method is present. It converts its
- # argument to a Python integer and calls mp_subscript.
- code.putln(
- "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
- scope.mangle_internal("sq_item"))
- code.putln(
- "PyObject *r;")
- code.putln(
- "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
- code.putln(
- "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
- code.putln(
- "Py_DECREF(x);")
- code.putln(
- "return r;")
- code.putln(
- "}")
-
- def generate_ass_subscript_function(self, scope, code):
- # Setting and deleting an item are both done through
- # the ass_subscript method, so we dispatch to user's __setitem__
- # or __delitem__, or raise an exception.
- base_type = scope.parent_type.base_type
- set_entry = scope.lookup_here("__setitem__")
- del_entry = scope.lookup_here("__delitem__")
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
- scope.mangle_internal("mp_ass_subscript"))
- code.putln(
- "if (v) {")
- if set_entry:
- code.putln(
- "return %s(o, i, v);" %
- set_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
- code.putln(
- "PyErr_Format(PyExc_NotImplementedError,")
- code.putln(
- ' "Subscript assignment not supported by %s", o->ob_type->tp_name);')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "else {")
- if del_entry:
- code.putln(
- "return %s(o, i);" %
- del_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
- code.putln(
- "PyErr_Format(PyExc_NotImplementedError,")
- code.putln(
- ' "Subscript deletion not supported by %s", o->ob_type->tp_name);')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "}")
-
- def generate_guarded_basetype_call(
- self, base_type, substructure, slot, args, code):
- if base_type:
- base_tpname = base_type.typeptr_cname
- if substructure:
- code.putln(
- "if (%s->%s && %s->%s->%s)" % (
- base_tpname, substructure, base_tpname, substructure, slot))
- code.putln(
- " return %s->%s->%s(%s);" % (
- base_tpname, substructure, slot, args))
- else:
- code.putln(
- "if (%s->%s)" % (
- base_tpname, slot))
- code.putln(
- " return %s->%s(%s);" % (
- base_tpname, slot, args))
-
- def generate_ass_slice_function(self, scope, code):
- # Setting and deleting a slice are both done through
- # the ass_slice method, so we dispatch to user's __setslice__
- # or __delslice__, or raise an exception.
- base_type = scope.parent_type.base_type
- set_entry = scope.lookup_here("__setslice__")
- del_entry = scope.lookup_here("__delslice__")
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
- scope.mangle_internal("sq_ass_slice"))
- code.putln(
- "if (v) {")
- if set_entry:
- code.putln(
- "return %s(o, i, j, v);" %
- set_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
- code.putln(
- "PyErr_Format(PyExc_NotImplementedError,")
- code.putln(
- ' "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "else {")
- if del_entry:
- code.putln(
- "return %s(o, i, j);" %
- del_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
- code.putln(
- "PyErr_Format(PyExc_NotImplementedError,")
- code.putln(
- ' "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "}")
-
- def generate_getattro_function(self, scope, code):
- # First try to get the attribute using PyObject_GenericGetAttr.
- # If that raises an AttributeError, call the user's __getattr__
- # method.
- entry = scope.lookup_here("__getattr__")
- code.putln("")
- code.putln(
- "static PyObject *%s(PyObject *o, PyObject *n) {"
- % scope.mangle_internal("tp_getattro"))
- code.putln(
- "PyObject *v = PyObject_GenericGetAttr(o, n);")
- code.putln(
- "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
- code.putln(
- "PyErr_Clear();")
- code.putln(
- "v = %s(o, n);" %
- entry.func_cname)
- code.putln(
- "}")
- code.putln(
- "return v;")
- code.putln(
- "}")
-
- def generate_setattro_function(self, scope, code):
- # Setting and deleting an attribute are both done through
- # the setattro method, so we dispatch to user's __setattr__
- # or __delattr__ or fall back on PyObject_GenericSetAttr.
- base_type = scope.parent_type.base_type
- set_entry = scope.lookup_here("__setattr__")
- del_entry = scope.lookup_here("__delattr__")
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
- scope.mangle_internal("tp_setattro"))
- code.putln(
- "if (v) {")
- if set_entry:
- code.putln(
- "return %s(o, n, v);" %
- set_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, None, "tp_setattro", "o, n, v", code)
- code.putln(
- "return PyObject_GenericSetAttr(o, n, v);")
- code.putln(
- "}")
- code.putln(
- "else {")
- if del_entry:
- code.putln(
- "return %s(o, n);" %
- del_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, None, "tp_setattro", "o, n, v", code)
- code.putln(
- "return PyObject_GenericSetAttr(o, n, 0);")
- code.putln(
- "}")
- code.putln(
- "}")
-
- def generate_descr_get_function(self, scope, code):
- # The __get__ function of a descriptor object can be
- # called with NULL for the second or third arguments
- # under some circumstances, so we replace them with
- # None in that case.
- user_get_entry = scope.lookup_here("__get__")
- code.putln("")
- code.putln(
- "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
- scope.mangle_internal("tp_descr_get"))
- code.putln(
- "PyObject *r = 0;")
- code.putln(
- "if (!i) i = Py_None;")
- code.putln(
- "if (!c) c = Py_None;")
- #code.put_incref("i", py_object_type)
- #code.put_incref("c", py_object_type)
- code.putln(
- "r = %s(o, i, c);" %
- user_get_entry.func_cname)
- #code.put_decref("i", py_object_type)
- #code.put_decref("c", py_object_type)
- code.putln(
- "return r;")
- code.putln(
- "}")
-
- def generate_descr_set_function(self, scope, code):
- # Setting and deleting are both done through the __set__
- # method of a descriptor, so we dispatch to user's __set__
- # or __delete__ or raise an exception.
- base_type = scope.parent_type.base_type
- user_set_entry = scope.lookup_here("__set__")
- user_del_entry = scope.lookup_here("__delete__")
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
- scope.mangle_internal("tp_descr_set"))
- code.putln(
- "if (v) {")
- if user_set_entry:
- code.putln(
- "return %s(o, i, v);" %
- user_set_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, None, "tp_descr_set", "o, i, v", code)
- code.putln(
- 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "else {")
- if user_del_entry:
- code.putln(
- "return %s(o, i);" %
- user_del_entry.func_cname)
- else:
- self.generate_guarded_basetype_call(
- base_type, None, "tp_descr_set", "o, i, v", code)
- code.putln(
- 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "}")
-
- def generate_property_accessors(self, cclass_scope, code):
- for entry in cclass_scope.property_entries:
- property_scope = entry.scope
- if property_scope.defines_any(["__get__"]):
- self.generate_property_get_function(entry, code)
- if property_scope.defines_any(["__set__", "__del__"]):
- self.generate_property_set_function(entry, code)
-
- def generate_property_get_function(self, property_entry, code):
- property_scope = property_entry.scope
- property_entry.getter_cname = property_scope.parent_scope.mangle(
- Naming.prop_get_prefix, property_entry.name)
- get_entry = property_scope.lookup_here("__get__")
- code.putln("")
- code.putln(
- "static PyObject *%s(PyObject *o, void *x) {" %
- property_entry.getter_cname)
- code.putln(
- "return %s(o);" %
- get_entry.func_cname)
- code.putln(
- "}")
-
- def generate_property_set_function(self, property_entry, code):
- property_scope = property_entry.scope
- property_entry.setter_cname = property_scope.parent_scope.mangle(
- Naming.prop_set_prefix, property_entry.name)
- set_entry = property_scope.lookup_here("__set__")
- del_entry = property_scope.lookup_here("__del__")
- code.putln("")
- code.putln(
- "static int %s(PyObject *o, PyObject *v, void *x) {" %
- property_entry.setter_cname)
- code.putln(
- "if (v) {")
- if set_entry:
- code.putln(
- "return %s(o, v);" %
- set_entry.func_cname)
- else:
- code.putln(
- 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "else {")
- if del_entry:
- code.putln(
- "return %s(o);" %
- del_entry.func_cname)
- else:
- code.putln(
- 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
- code.putln(
- "return -1;")
- code.putln(
- "}")
- code.putln(
- "}")
-
- def generate_typeobj_definition(self, modname, entry, code):
- type = entry.type
- scope = type.scope
- for suite in TypeSlots.substructures:
- suite.generate_substructure(scope, code)
- code.putln("")
- if entry.visibility == 'public':
- header = "DL_EXPORT(PyTypeObject) %s = {"
- else:
- header = "PyTypeObject %s = {"
- code.putln(header % type.typeobj_cname)
- code.putln(
- "PyObject_HEAD_INIT(0)")
- code.putln(
- "0, /*ob_size*/")
- code.putln(
- '"%s.%s", /*tp_name*/' % (
- modname, scope.class_name))
- if type.typedef_flag:
- objstruct = type.objstruct_cname
- else:
- #objstruct = "struct %s" % scope.parent_type.objstruct_cname
- objstruct = "struct %s" % type.objstruct_cname
- code.putln(
- "sizeof(%s), /*tp_basicsize*/" %
- objstruct)
- code.putln(
- "0, /*tp_itemsize*/")
- for slot in TypeSlots.slot_table:
- slot.generate(scope, code)
- code.putln(
- "};")
-
- def generate_method_table(self, env, code):
- code.putln("")
- code.putln(
- "static struct PyMethodDef %s[] = {" %
- env.method_table_cname)
- for entry in env.pyfunc_entries:
- code.put_pymethoddef(entry, ",")
- code.putln(
- "{0, 0, 0, 0}")
- code.putln(
- "};")
-
- def generate_member_table(self, env, code):
- #print "ModuleNode.generate_member_table: scope =", env ###
- if env.public_attr_entries:
- code.putln("")
- code.putln(
- "static struct PyMemberDef %s[] = {" %
- env.member_table_cname)
- type = env.parent_type
- if type.typedef_flag:
- objstruct = type.objstruct_cname
- else:
- objstruct = "struct %s" % type.objstruct_cname
- for entry in env.public_attr_entries:
- type_code = entry.type.pymemberdef_typecode
- if entry.visibility == 'readonly':
- flags = "READONLY"
- else:
- flags = "0"
- code.putln('{"%s", %s, %s, %s, 0},' % (
- entry.name,
- type_code,
- "offsetof(%s, %s)" % (objstruct, entry.cname),
- flags))
- code.putln(
- "{0, 0, 0, 0, 0}")
- code.putln(
- "};")
-
- def generate_getset_table(self, env, code):
- if env.property_entries:
- code.putln("")
- code.putln(
- "static struct PyGetSetDef %s[] = {" %
- env.getset_table_cname)
- for entry in env.property_entries:
- if entry.doc:
- doc_code = code.get_string_const(entry.doc)
- else:
- doc_code = "0"
- code.putln(
- '{"%s", %s, %s, %s, 0},' % (
- entry.name,
- entry.getter_cname or "0",
- entry.setter_cname or "0",
- doc_code))
- code.putln(
- "{0, 0, 0, 0, 0}")
- code.putln(
- "};")
-
- def generate_interned_name_table(self, interned_strings, code):
- code.putln("")
- code.putln(
- "static PyObject **%s[] = {" % Naming.intern_tab_cname)
- for s in interned_strings:
- code.putln("&%s," % s.py_cname)
- code.putln("0")
- code.putln(
- "};")
-
- def generate_filename_init_prototype(self, code):
- code.putln("");
- code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
-
- def generate_module_init_func(self, imported_modules, env, code):
- denv = env.definition_scope
- code.putln("")
- header = "PyMODINIT_FUNC init%s(void)" % env.module_name
- code.putln("%s; /*proto*/" % header)
- code.putln("%s {" % header)
- code.put_var_declarations(env.temp_entries)
-
- if env.gil_used:
- # Workaround for GIL/threading bug in 2.3
- code.putln("#if PY_VERSION_HEX < 0x02040000 && defined(WITH_THREAD)")
- code.putln(" PyEval_InitThreads();")
- code.putln("#endif")
-
- #code.putln("/*--- Libary function declarations ---*/")
- env.generate_library_function_declarations(code)
- self.generate_filename_init_call(code)
-
- #code.putln("/*--- Module creation code ---*/")
- self.generate_module_creation_code(env, code)
-
- #code.putln("/*--- String init code ---*/")
- self.generate_string_init_code(env, code)
-
- #code.putln("/*--- Intern code ---*/")
- #self.generate_intern_code(env, code)
-
- #code.putln("/*--- Global init code ---*/")
- self.generate_global_init_code(env, code)
-
- #code.putln("/*--- Function export code ---*/")
- self.generate_pxd_function_export_code(env, code)
- self.generate_api_function_export_code(env, code)
-
- #code.putln("/*--- Function import code ---*/")
- for module in imported_modules:
- self.generate_c_function_import_code_for_module(module, env, code)
-
- #code.putln("/*--- Type init code ---*/")
- self.generate_type_init_code(env, code)
-
- #code.putln("/*--- Type import code ---*/")
- for module in imported_modules:
- self.generate_type_import_code_for_module(module, env, code)
-
- #code.putln("/*--- Execution code ---*/")
- self.body.generate_execution_code(code)
- code.putln("return;")
- code.put_label(code.error_label)
- code.put_var_xdecrefs(env.temp_entries)
- code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
- code.use_utility_code(Nodes.traceback_utility_code)
- code.putln('}')
-
- def generate_filename_init_call(self, code):
- code.putln("%s();" % Naming.fileinit_cname)
-
- def generate_module_creation_code(self, env, code):
- # Generate code to create the module object and
- # install the builtins.
- if env.doc:
- doc = env.doc_cname
- else:
- doc = "0"
- code.putln(
- '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
- env.module_cname,
- env.module_name,
- env.method_table_cname,
- doc))
- code.putln(
- "if (!%s) %s;" % (
- env.module_cname,
- code.error_goto(self.pos)));
- code.putln(
- "Py_INCREF(%s);" %
- env.module_cname)
- code.putln(
- '%s = PyImport_AddModule("__builtin__");' %
- Naming.builtins_cname)
- code.putln(
- "if (!%s) %s;" % (
- Naming.builtins_cname,
- code.error_goto(self.pos)));
- code.putln(
- 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
- env.module_cname,
- Naming.builtins_cname,
- code.error_goto(self.pos)))
-
- def generate_string_init_code(self, env, code):
- code.use_utility_code(Nodes.init_string_tab_utility_code)
- code.putln(
- "if (__Pyx_InitStrings(%s) < 0) %s;" % (
- Naming.stringtab_cname,
- code.error_goto(self.pos)))
-
- def generate_global_init_code(self, env, code):
- # Generate code to initialise global PyObject *
- # variables to None.
- for entry in env.var_entries:
- if entry.visibility <> 'extern':
- if entry.type.is_pyobject:
- code.put_init_var_to_py_none(entry)
-
- def generate_pxd_function_export_code(self, env, code):
- denv = env.definition_scope
- for entry in denv.cfunc_entries:
- if entry.visibility <> 'extern':
- self.generate_c_function_export_code(env, entry, code)
-
- def generate_api_function_export_code(self, env, code):
- for entry in env.cfunc_entries:
- if entry.api:
- self.generate_c_function_export_code(env, entry, code)
-
- def generate_c_function_export_code(self, env, entry, code):
- code.use_utility_code(function_export_utility_code)
- signature = entry.type.signature_string()
- code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % (
- entry.name,
- entry.cname,
- signature,
- code.error_goto(self.pos)))
-
- def generate_type_import_code_for_module(self, module, env, code):
- # Generate type import code for all exported extension types in
- # an imported module.
- #if module.c_class_entries:
- #print "generate_type_import_code_for_module:", module ###
- for entry in module.c_class_entries:
- if entry.defined_in_pxd:
- self.generate_type_import_code(env, entry.type, entry.pos, code)
-
- def generate_c_function_import_code_for_module(self, module, env, code):
- # Generate import code for all exported C functions in a cimported module.
- entries = []
- for entry in module.cfunc_entries:
- if entry.defined_in_pxd:
- entries.append(entry)
- if entries:
- code.use_utility_code(import_module_utility_code)
- code.use_utility_code(function_import_utility_code)
- temp = self.module_temp_cname
- code.putln(
- '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
- temp,
- module.qualified_name,
- temp,
- code.error_goto(self.pos)))
- for entry in entries:
- code.putln(
- 'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % (
- temp,
- entry.name,
- entry.cname,
- entry.type.signature_string(),
- code.error_goto(self.pos)))
- code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
-
- def generate_type_init_code(self, env, code):
- # Generate type import code for extern extension types
- # and type ready code for non-extern ones.
- #print "generate_type_init_code:", env ###
- denv = env.definition_scope
- for entry in denv.c_class_entries + env.c_class_entries:
- if entry.visibility == 'extern':
- self.generate_type_import_code(env, entry.type, entry.pos, code)
- else:
- self.generate_base_type_import_code(env, entry, code)
- self.generate_exttype_vtable_init_code(entry, code)
- self.generate_type_ready_code(env, entry, code)
- self.generate_typeptr_assignment_code(entry, code)
-
- def generate_base_type_import_code(self, env, entry, code):
- base_type = entry.type.base_type
- if base_type and base_type.module_name <> env.qualified_name:
- self.generate_type_import_code(env, base_type, self.pos, code)
-
- def use_type_import_utility_code(self, code):
- import ExprNodes
- code.use_utility_code(type_import_utility_code)
- code.use_utility_code(import_module_utility_code)
-
- def generate_type_import_code(self, env, type, pos, code):
- # If not already done, generate code to import the typeobject of an
- # extension type defined in another module, and extract its C method
- # table pointer if any.
- #print "generate_type_import_code:", type ###
- if not type.is_builtin and type not in env.types_imported:
- if type.typedef_flag:
- objstruct = type.objstruct_cname
- else:
- objstruct = "struct %s" % type.objstruct_cname
- self.generate_type_import_call(type, code, code.error_goto(pos))
- self.use_type_import_utility_code(code)
- if type.vtabptr_cname:
- code.putln(
- "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
- type.typeptr_cname,
- type.vtabptr_cname,
- code.error_goto(pos)))
- code.use_utility_code(Nodes.get_vtable_utility_code)
- env.types_imported[type] = 1
-
- def generate_type_import_call(self, type, code, error_code):
- if type.typedef_flag:
- objstruct = type.objstruct_cname
- else:
- objstruct = "struct %s" % type.objstruct_cname
- code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
- type.typeptr_cname,
- type.module_name,
- type.name,
- objstruct,
- type.typeptr_cname,
- error_code))
-
- def generate_type_ready_code(self, env, entry, code):
- # Generate a call to PyType_Ready for an extension
- # type defined in this module.
- type = entry.type
- typeobj_cname = type.typeobj_cname
- scope = type.scope
- if scope: # could be None if there was an error
- if entry.visibility <> 'extern':
- for slot in TypeSlots.slot_table:
- slot.generate_dynamic_init_code(scope, code)
- code.putln(
- "if (PyType_Ready(&%s) < 0) %s" % (
- typeobj_cname,
- code.error_goto(entry.pos)))
- if type.vtable_cname:
- code.putln(
- "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
- typeobj_cname,
- type.vtabptr_cname,
- code.error_goto(entry.pos)))
- code.use_utility_code(Nodes.set_vtable_utility_code)
- code.putln(
- 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
- Naming.module_cname,
- scope.class_name,
- typeobj_cname,
- code.error_goto(entry.pos)))
- weakref_entry = scope.lookup_here("__weakref__")
- if weakref_entry:
- if weakref_entry.type is py_object_type:
- tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
- code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
- tp_weaklistoffset,
- tp_weaklistoffset,
- type.objstruct_cname,
- weakref_entry.cname))
- else:
- error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
-
- def generate_exttype_vtable_init_code(self, entry, code):
- # Generate code to initialise the C method table of an
- # extension type.
- type = entry.type
- if type.vtable_cname:
- code.putln(
- "%s = &%s;" % (
- type.vtabptr_cname,
- type.vtable_cname))
- if type.base_type and type.base_type.vtabptr_cname:
- code.putln(
- "%s.%s = *%s;" % (
- type.vtable_cname,
- Naming.obj_base_cname,
- type.base_type.vtabptr_cname))
- for meth_entry in type.scope.cfunc_entries:
- if meth_entry.func_cname:
- code.putln(
- "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
- type.vtable_cname,
- meth_entry.cname,
- meth_entry.func_cname))
-
- def generate_typeptr_assignment_code(self, entry, code):
- # Generate code to initialise the typeptr of an extension
- # type defined in this module to point to its type object.
- type = entry.type
- if type.typeobj_cname:
- code.putln(
- "%s = &%s;" % (
- type.typeptr_cname, type.typeobj_cname))
-
- def generate_utility_functions(self, code):
- code.global_state.generate_utility_functions(code)
-
-#------------------------------------------------------------------------------------
-#
-# Runtime support code
-#
-#------------------------------------------------------------------------------------
-
-import_module_utility_code = [
-"""
-static PyObject *__Pyx_ImportModule(char *name); /*proto*/
-""","""
-#ifndef __PYX_HAVE_RT_ImportModule
-#define __PYX_HAVE_RT_ImportModule
-static PyObject *__Pyx_ImportModule(char *name) {
- PyObject *py_name = 0;
-
- py_name = PyString_FromString(name);
- if (!py_name)
- goto bad;
- return PyImport_Import(py_name);
-bad:
- Py_XDECREF(py_name);
- return 0;
-}
-#endif
-"""]
-
-#------------------------------------------------------------------------------------
-
-type_import_utility_code = [
-"""
-static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
-""",r"""
-#ifndef __PYX_HAVE_RT_ImportType
-#define __PYX_HAVE_RT_ImportType
-static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
- long size)
-{
- PyObject *py_module = 0;
- PyObject *result = 0;
-
- py_module = __Pyx_ImportModule(module_name);
- if (!py_module)
- goto bad;
- result = PyObject_GetAttrString(py_module, class_name);
- if (!result)
- goto bad;
- if (!PyType_Check(result)) {
- PyErr_Format(PyExc_TypeError,
- "%s.%s is not a type object",
- module_name, class_name);
- goto bad;
- }
-#ifdef __PYX_CHECK_IMPORTED_TYPES
- if (((PyTypeObject *)result)->tp_basicsize != size) {
- PyErr_Format(PyExc_ValueError,
- "%s.%s does not appear to be the correct type object",
- module_name, class_name);
- goto bad;
- }
-#endif
- return (PyTypeObject *)result;
-bad:
- Py_XDECREF(result);
- return 0;
-}
-#endif
-"""]
-
-#------------------------------------------------------------------------------------
-
-function_export_utility_code = [
-"""
-static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
-""",r"""
-static int __Pyx_ExportFunction(char *n, void *f, char *s) {
- PyObject *d = 0;
- PyObject *p = 0;
- d = PyObject_GetAttrString(%(MODULE)s, "%(API)s");
- if (!d) {
- PyErr_Clear();
- d = PyDict_New();
- if (!d)
- goto bad;
- Py_INCREF(d);
- if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0)
- goto bad;
- }
- p = PyCObject_FromVoidPtrAndDesc(f, s, 0);
- if (!p)
- goto bad;
- if (PyDict_SetItemString(d, n, p) < 0)
- goto bad;
- Py_DECREF(p);
- Py_DECREF(d);
- return 0;
-bad:
- Py_XDECREF(p);
- Py_XDECREF(d);
- return -1;
-}
-""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}]
-
-#------------------------------------------------------------------------------------
-
-function_import_utility_code = [
-"""
-static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
-""","""
-#ifndef __PYX_HAVE_RT_ImportFunction
-#define __PYX_HAVE_RT_ImportFunction
-static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
- PyObject *d = 0;
- PyObject *cobj = 0;
- char *desc;
-
- d = PyObject_GetAttrString(module, "%(API)s");
- if (!d)
- goto bad;
- cobj = PyDict_GetItemString(d, funcname);
- if (!cobj) {
- PyErr_Format(PyExc_ImportError,
- "%%s does not export expected C function %%s",
- PyModule_GetName(module), funcname);
- goto bad;
- }
- desc = (char *)PyCObject_GetDesc(cobj);
- if (!desc)
- goto bad;
- if (strcmp(desc, sig) != 0) {
- PyErr_Format(PyExc_TypeError,
- "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
- PyModule_GetName(module), funcname, sig, desc);
- goto bad;
- }
- *f = PyCObject_AsVoidPtr(cobj);
- Py_DECREF(d);
- return 0;
-bad:
- Py_XDECREF(d);
- return -1;
-}
-#endif
-""" % dict(API = Naming.api_name)]
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py
deleted file mode 100644
index 61076a81..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Pyrex - C naming conventions
-#
-#
-# Prefixes for generating C names.
-# Collected here to facilitate ensuring uniqueness.
-#
-
-pyrex_prefix = "__pyx_"
-
-arg_prefix = pyrex_prefix + "arg_"
-funcdoc_prefix = pyrex_prefix + "doc_"
-enum_prefix = pyrex_prefix + "e_"
-func_prefix = pyrex_prefix + "f_"
-gstab_prefix = pyrex_prefix + "getsets_"
-prop_get_prefix = pyrex_prefix + "getprop_"
-const_prefix = pyrex_prefix + "k"
-label_prefix = pyrex_prefix + "L"
-pymethdef_prefix = pyrex_prefix + "mdef_"
-methtab_prefix = pyrex_prefix + "methods_"
-memtab_prefix = pyrex_prefix + "members_"
-interned_prefix = pyrex_prefix + "n_"
-objstruct_prefix = pyrex_prefix + "obj_"
-typeptr_prefix = pyrex_prefix + "ptype_"
-prop_set_prefix = pyrex_prefix + "setprop_"
-type_prefix = pyrex_prefix + "t_"
-typeobj_prefix = pyrex_prefix + "type_"
-var_prefix = pyrex_prefix + "v_"
-vtable_prefix = pyrex_prefix + "vtable_"
-vtabptr_prefix = pyrex_prefix + "vtabptr_"
-vtabstruct_prefix = pyrex_prefix + "vtabstruct_"
-
-args_cname = pyrex_prefix + "args"
-kwdlist_cname = pyrex_prefix + "argnames"
-obj_base_cname = pyrex_prefix + "base"
-builtins_cname = pyrex_prefix + "b"
-moddict_cname = pyrex_prefix + "d"
-default_prefix = pyrex_prefix + "d"
-dummy_cname = pyrex_prefix + "dummy"
-filename_cname = pyrex_prefix + "filename"
-filetable_cname = pyrex_prefix + "f"
-filenames_cname = pyrex_prefix + "filenames"
-fileinit_cname = pyrex_prefix + "init_filenames"
-intern_tab_cname = pyrex_prefix + "intern_tab"
-kwds_cname = pyrex_prefix + "kwds"
-lineno_cname = pyrex_prefix + "lineno"
-module_cname = pyrex_prefix + "m"
-moddoc_cname = pyrex_prefix + "mdoc"
-methtable_cname = pyrex_prefix + "methods"
-retval_cname = pyrex_prefix + "r"
-reqd_kwds_cname = pyrex_prefix + "reqd_kwds"
-self_cname = pyrex_prefix + "self"
-stringtab_cname = pyrex_prefix + "string_tab"
-vtabslot_cname = pyrex_prefix + "vtab"
-
-extern_c_macro = pyrex_prefix.upper() + "EXTERN_C"
-
-exc_type_name = pyrex_prefix + "exc_type"
-exc_value_name = pyrex_prefix + "exc_value"
-exc_tb_name = pyrex_prefix + "exc_tb"
-exc_lineno_name = pyrex_prefix + "exc_lineno"
-
-exc_vars = (exc_type_name, exc_value_name, exc_tb_name)
-
-api_name = pyrex_prefix + "capi__"
-
-h_guard_prefix = "__PYX_HAVE__"
-api_guard_prefix = "__PYX_HAVE_API__"
-api_func_guard = "__PYX_HAVE_API_FUNC_"
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py
deleted file mode 100644
index fb974df0..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py
+++ /dev/null
@@ -1,3249 +0,0 @@
-#
-# Pyrex - Parse tree nodes
-#
-
-import string, sys
-
-import Code
-from Errors import error, one_time_warning, InternalError
-import Naming
-import PyrexTypes
-from PyrexTypes import py_object_type, c_int_type, error_type, \
- CTypedefType, CFuncType
-from Symtab import ModuleScope, LocalScope, \
- StructOrUnionScope, PyClassScope, CClassScope
-from Pyrex.Utils import open_new_file, replace_suffix
-import Options
-
-from DebugFlags import debug_disposal_code
-
-class Node:
- # pos (string, int, int) Source file position
- # is_name boolean Is a NameNode
- # is_literal boolean Is a ConstNode
-
- is_name = 0
- is_literal = 0
-
- def __init__(self, pos, **kw):
- self.pos = pos
- self.__dict__.update(kw)
-
- gil_message = "Operation"
-
- def gil_check(self, env):
- if env.nogil:
- self.gil_error()
-
- def gil_error(self, message = None):
- error(self.pos, "%s not allowed without gil" % (message or self.gil_message))
-
- #
- # There are 3 phases of parse tree processing, applied in order to
- # all the statements in a given scope-block:
- #
- # (1) analyse_declarations
- # Make symbol table entries for all declarations at the current
- # level, both explicit (def, cdef, etc.) and implicit (assignment
- # to an otherwise undeclared name).
- #
- # (2) analyse_expressions
- # Determine the result types of expressions and fill in the
- # 'type' attribute of each ExprNode. Insert coercion nodes into the
- # tree where needed to convert to and from Python objects.
- # Allocate temporary locals for intermediate results.
- #
- # (3) generate_code
- # Emit C code for all declarations, statements and expressions.
- # Recursively applies the 3 processing phases to the bodies of
- # functions.
- #
-
- def analyse_declarations(self, env):
- pass
-
- def analyse_expressions(self, env):
- raise InternalError("analyse_expressions not implemented for %s" % \
- self.__class__.__name__)
-
- def generate_code(self, code):
- raise InternalError("generate_code not implemented for %s" % \
- self.__class__.__name__)
-
-
-class BlockNode:
- # Mixin class for nodes representing a declaration block.
- pass
-
-# def generate_const_definitions(self, env, code):
-# if env.const_entries:
-# code.putln("")
-# for entry in env.const_entries:
-# if not entry.is_interned:
-# code.put_var_declaration(entry, static = 1)
-
-# def generate_interned_name_decls(self, env, code):
-# # Flush accumulated interned names from the global scope
-# # and generate declarations for them.
-# genv = env.global_scope()
-# intern_map = genv.intern_map
-# names = genv.interned_names
-# if names:
-# code.putln("")
-# for name in names:
-# code.putln(
-# "static PyObject *%s;" % intern_map[name])
-# del names[:]
-
-# def generate_py_string_decls(self, env, code):
-# entries = env.pystring_entries
-# if entries:
-# code.putln("")
-# for entry in entries:
-# code.putln(
-# "static PyObject *%s;" % entry.pystring_cname)
-
-
-class StatListNode(Node):
- # stats a list of StatNode
-
- def analyse_declarations(self, env):
- #print "StatListNode.analyse_declarations" ###
- for stat in self.stats:
- stat.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- #print "StatListNode.analyse_expressions" ###
- for stat in self.stats:
- stat.analyse_expressions(env)
-
- def generate_function_definitions(self, env, code):
- #print "StatListNode.generate_function_definitions" ###
- for stat in self.stats:
- stat.generate_function_definitions(env, code)
-
- def generate_execution_code(self, code):
- #print "StatListNode.generate_execution_code" ###
- for stat in self.stats:
- code.mark_pos(stat.pos)
- stat.generate_execution_code(code)
-
-
-class StatNode(Node):
- #
- # Code generation for statements is split into the following subphases:
- #
- # (1) generate_function_definitions
- # Emit C code for the definitions of any structs,
- # unions, enums and functions defined in the current
- # scope-block.
- #
- # (2) generate_execution_code
- # Emit C code for executable statements.
- #
-
- def generate_function_definitions(self, env, code):
- pass
-
- def generate_execution_code(self, code):
- raise InternalError("generate_execution_code not implemented for %s" % \
- self.__class__.__name__)
-
-
-class CDefExternNode(StatNode):
- # include_file string or None
- # body StatNode
-
- def analyse_declarations(self, env):
- if self.include_file:
- env.add_include_file(self.include_file)
- old_cinclude_flag = env.in_cinclude
- env.in_cinclude = 1
- self.body.analyse_declarations(env)
- env.in_cinclude = old_cinclude_flag
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class CDeclaratorNode(Node):
- # Part of a C declaration.
- #
- # Processing during analyse_declarations phase:
- #
- # analyse
- # Returns (name, type) pair where name is the
- # CNameDeclaratorNode of the name being declared
- # and type is the type it is being declared as.
- #
- # calling_convention string Calling convention of CFuncDeclaratorNode
- # for which this is a base
-
- calling_convention = ""
-
-
-class CNameDeclaratorNode(CDeclaratorNode):
- # name string The Pyrex name being declared
- # cname string or None C name, if specified
-
- def analyse(self, base_type, env):
- return self, base_type
-
-
-class CPtrDeclaratorNode(CDeclaratorNode):
- # base CDeclaratorNode
-
- def analyse(self, base_type, env):
- if base_type.is_pyobject:
- error(self.pos,
- "Pointer base type cannot be a Python object")
- ptr_type = PyrexTypes.c_ptr_type(base_type)
- return self.base.analyse(ptr_type, env)
-
-
-class CArrayDeclaratorNode(CDeclaratorNode):
- # base CDeclaratorNode
- # dimension ExprNode
-
- def analyse(self, base_type, env):
- if self.dimension:
- self.dimension.analyse_const_expression(env)
- if not self.dimension.type.is_int:
- error(self.dimension.pos, "Array dimension not integer")
- size = self.dimension.result()
- else:
- size = None
- if not base_type.is_complete():
- error(self.pos,
- "Array element type '%s' is incomplete" % base_type)
- if base_type.is_pyobject:
- error(self.pos,
- "Array element cannot be a Python object")
- if base_type.is_cfunction:
- error(self.pos,
- "Array element cannot be a function")
- array_type = PyrexTypes.c_array_type(base_type, size)
- return self.base.analyse(array_type, env)
-
-
-class CFuncDeclaratorNode(CDeclaratorNode):
- # base CDeclaratorNode
- # args [CArgDeclNode]
- # has_varargs boolean
- # exception_value ConstNode
- # exception_check boolean True if PyErr_Occurred check needed
- # nogil boolean Can be called without gil
- # with_gil boolean Acquire gil around function body
-
- def analyse(self, return_type, env):
- func_type_args = []
- for arg_node in self.args:
- name_declarator, type = arg_node.analyse(env)
- name = name_declarator.name
- if name_declarator.cname:
- error(self.pos,
- "Function argument cannot have C name specification")
- # Turn *[] argument into **
- if type.is_array:
- type = PyrexTypes.c_ptr_type(type.base_type)
- # Catch attempted C-style func(void) decl
- if type.is_void:
- error(arg_node.pos, "Function argument cannot be void")
- func_type_args.append(
- PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
- if arg_node.default:
- error(arg_node.pos, "C function argument cannot have default value")
- exc_val = None
- exc_check = 0
- if return_type.is_pyobject \
- and (self.exception_value or self.exception_check):
- error(self.pos,
- "Exception clause not allowed for function returning Python object")
- else:
- if self.exception_value:
- self.exception_value.analyse_const_expression(env)
- exc_val = self.exception_value.result()
- if not return_type.assignable_from(self.exception_value.type):
- error(self.exception_value.pos,
- "Exception value incompatible with function return type")
- exc_check = self.exception_check
- if return_type.is_array:
- error(self.pos,
- "Function cannot return an array")
- if return_type.is_cfunction:
- error(self.pos,
- "Function cannot return a function")
- func_type = PyrexTypes.CFuncType(
- return_type, func_type_args, self.has_varargs,
- exception_value = exc_val, exception_check = exc_check,
- calling_convention = self.base.calling_convention,
- nogil = self.nogil, with_gil = self.with_gil)
- return self.base.analyse(func_type, env)
-
-
-class CArgDeclNode(Node):
- # Item in a function declaration argument list.
- #
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
- # #not_none boolean Tagged with 'not None'
- # allow_none tristate True == 'or None', False == 'not None', None = unspecified
- # default ExprNode or None
- # default_entry Symtab.Entry Entry for the variable holding the default value
- # is_self_arg boolean Is the "self" arg of an extension type method
- # is_kw_only boolean Is a keyword-only argument
-
- is_self_arg = 0
-
- def analyse(self, env):
- #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
- base_type = self.base_type.analyse(env)
- return self.declarator.analyse(base_type, env)
-
-
-class CBaseTypeNode(Node):
- # Abstract base class for C base type nodes.
- #
- # Processing during analyse_declarations phase:
- #
- # analyse
- # Returns the type.
-
- pass
-
-
-class CSimpleBaseTypeNode(CBaseTypeNode):
- # name string
- # module_path [string] Qualifying name components
- # is_basic_c_type boolean
- # signed boolean
- # longness integer
- # is_self_arg boolean Is self argument of C method
-
- def analyse(self, env):
- # Return type descriptor.
- #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
- type = None
- if self.is_basic_c_type:
- type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
- if not type:
- error(self.pos, "Unrecognised type modifier combination")
- elif self.name == "object" and not self.module_path:
- type = py_object_type
- elif self.name is None:
- if self.is_self_arg and env.is_c_class_scope:
- #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
- type = env.parent_type
- else:
- type = py_object_type
- else:
- scope = env.find_imported_module(self.module_path, self.pos)
- if scope:
- entry = scope.find(self.name, self.pos)
- if entry and entry.is_type:
- type = entry.type
- else:
- error(self.pos, "'%s' is not a type identifier" % self.name)
- if type:
- return type
- else:
- return PyrexTypes.error_type
-
-
-class CComplexBaseTypeNode(CBaseTypeNode):
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
-
- def analyse(self, env):
- base = self.base_type.analyse(env)
- _, type = self.declarator.analyse(base, env)
- return type
-
-
-class CVarDefNode(StatNode):
- # C variable definition or forward/extern function declaration.
- #
- # visibility 'private' or 'public' or 'extern'
- # base_type CBaseTypeNode
- # declarators [CDeclaratorNode]
- # in_pxd boolean
- # api boolean
-
- def analyse_declarations(self, env, dest_scope = None):
- if not dest_scope:
- dest_scope = env
- base_type = self.base_type.analyse(env)
- for declarator in self.declarators:
- name_declarator, type = declarator.analyse(base_type, env)
- if not type.is_complete():
- if not (self.visibility == 'extern' and type.is_array):
- error(declarator.pos,
- "Variable type '%s' is incomplete" % type)
- if self.visibility == 'extern' and type.is_pyobject:
- error(declarator.pos,
- "Python object cannot be declared extern")
- name = name_declarator.name
- cname = name_declarator.cname
- if type.is_cfunction:
- entry = dest_scope.declare_cfunction(name, type, declarator.pos,
- cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
- api = self.api)
- else:
- if self.in_pxd and self.visibility <> 'extern':
- error(self.pos,
- "Only 'extern' C variable declaration allowed in .pxd file")
- dest_scope.declare_var(name, type, declarator.pos,
- cname = cname, visibility = self.visibility, is_cdef = 1)
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class CStructOrUnionDefNode(StatNode):
- # name string
- # cname string or None
- # module_path [string]
- # kind "struct" or "union"
- # typedef_flag boolean
- # cplus_flag boolean
- # visibility "public" or "private"
- # in_pxd boolean
- # attributes [CVarDefNode] or None
- # entry Entry
- # bases [([name, ...], name), ...]
-
- def analyse_declarations(self, env):
- scope = None
- base_scopes = []
- for base in self.bases:
- base_entry = env.find_qualified_name(base, self.pos)
- if base_entry:
- if base_entry.is_type and base_entry.type.is_struct_or_union \
- and base_entry.type.scope.is_cplus:
- base_scopes.append(base_entry.type.scope)
- else:
- error(self.pos, "Base type '%s' is not a C++ struct" %
- ".".join(base[0] + [base[1]]))
- if self.attributes is not None:
- scope = StructOrUnionScope(base_scopes = base_scopes, is_cplus = self.cplus_flag)
- if self.module_path:
- home_scope = env.find_imported_module(self.module_path, self.pos)
- if not home_scope:
- return
- else:
- home_scope = env
- def declare():
- self.entry = home_scope.declare_struct_or_union(
- self.name, self.kind, scope, self.typedef_flag, self.pos,
- self.cname, visibility = self.visibility)
- if self.attributes is not None:
- if self.in_pxd and not env.in_cinclude:
- self.entry.defined_in_pxd = 1
- if not self.typedef_flag:
- declare()
- if self.attributes is not None:
- for attr in self.attributes:
- attr.analyse_declarations(env, scope)
- if self.typedef_flag:
- declare()
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class CEnumDefNode(StatNode):
- # name string or None
- # cname string or None
- # items [CEnumDefItemNode]
- # typedef_flag boolean
- # visibility "public" or "private"
- # in_pxd boolean
- # entry Entry
-
- def analyse_declarations(self, env):
- self.entry = env.declare_enum(self.name, self.pos,
- cname = self.cname, typedef_flag = self.typedef_flag,
- visibility = self.visibility)
- if self.items is not None:
- if self.in_pxd and not env.in_cinclude:
- self.entry.defined_in_pxd = 1
- for item in self.items:
- item.analyse_declarations(env, self.entry)
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class CEnumDefItemNode(StatNode):
- # name string
- # cname string or None
- # value ExprNode or None
-
- def analyse_declarations(self, env, enum_entry):
- value_node = self.value
- if value_node:
- value_node.analyse_const_expression(env)
- type = value_node.type
- if type.is_int or type.is_enum:
- value = value_node.result()
- else:
- error(self.pos,
- "Type '%s' is not a valid enum value" % type)
- value = "<error>"
- else:
- value = self.name
- entry = env.declare_const(self.name, enum_entry.type,
- value, self.pos, cname = self.cname)
- enum_entry.enum_values.append(entry)
-
-
-class CTypeDefNode(StatNode):
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
- # visibility "public" or "private"
- # in_pxd boolean
-
- def analyse_declarations(self, env):
- base = self.base_type.analyse(env)
- name_declarator, type = self.declarator.analyse(base, env)
- name = name_declarator.name
- cname = name_declarator.cname
- entry = env.declare_typedef(name, type, self.pos,
- cname = cname, visibility = self.visibility)
- if self.in_pxd and not env.in_cinclude:
- entry.defined_in_pxd = 1
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class FuncDefNode(StatNode, BlockNode):
- # Base class for function definition nodes.
- #
- # return_type PyrexType
- # #filename string C name of filename string const
- # entry Symtab.Entry
-
- def analyse_expressions(self, env):
- pass
-
- def need_gil_acquisition(self, lenv):
- return 0
-
- def generate_function_definitions(self, env, code):
- # Generate C code for header and body of function
- genv = env.global_scope()
- lenv = LocalScope(name = self.entry.name, outer_scope = genv)
- lenv.return_type = self.return_type
- type = self.entry.type
- if type.is_cfunction:
- lenv.nogil = type.nogil and not type.with_gil
- code.init_labels()
- self.declare_arguments(lenv)
- self.body.analyse_declarations(lenv)
- self.body.analyse_expressions(lenv)
- # Code for nested function definitions would go here
- # if we supported them, which we probably won't.
- # ----- Function header
- code.putln("")
- self.generate_function_header(code,
- with_pymethdef = env.is_py_class_scope)
- # ----- Local variable declarations
- self.generate_argument_declarations(lenv, code)
- code.put_var_declarations(lenv.var_entries)
- init = ""
- if not self.return_type.is_void:
- code.putln(
- "%s%s;" %
- (self.return_type.declaration_code(
- Naming.retval_cname),
- init))
- code.put_var_declarations(lenv.temp_entries)
- self.generate_keyword_list(code)
- # ----- Extern library function declarations
- lenv.generate_library_function_declarations(code)
- # ----- GIL acquisition
- acquire_gil = self.need_gil_acquisition(lenv)
- if acquire_gil:
- lenv.global_scope().gil_used = 1
- code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
- # ----- Fetch arguments
- self.generate_argument_parsing_code(code)
- self.generate_argument_increfs(lenv, code)
- # ----- Initialise local variables
- for entry in lenv.var_entries:
- if entry.type.is_pyobject and entry.init_to_none and entry.used:
- code.put_init_var_to_py_none(entry)
- # ----- Check and convert arguments
- self.generate_argument_conversion_code(code)
- self.generate_argument_type_tests(code)
- # ----- Function body
- self.body.generate_execution_code(code)
- # ----- Default return value
- code.putln("")
- if self.return_type.is_pyobject:
- #if self.return_type.is_extension_type:
- # lhs = "(PyObject *)%s" % Naming.retval_cname
- #else:
- lhs = Naming.retval_cname
- code.put_init_to_py_none(lhs, self.return_type)
- else:
- val = self.return_type.default_value
- if val:
- code.putln("%s = %s;" % (Naming.retval_cname, val))
- #code.putln("goto %s;" % code.return_label)
- # ----- Error cleanup
- if code.error_label in code.labels_used:
- code.put_goto(code.return_label)
- code.put_label(code.error_label)
- code.put_var_xdecrefs(lenv.temp_entries)
- default_retval = self.return_type.default_value
- err_val = self.error_value()
- exc_check = self.caller_will_check_exceptions()
- if err_val or exc_check:
- code.putln(
- '__Pyx_AddTraceback("%s");' %
- self.entry.qualified_name)
- val = err_val or default_retval
- if val:
- code.putln(
- "%s = %s;" % (
- Naming.retval_cname,
- val))
- else:
- code.use_utility_code(unraisable_exception_utility_code)
- code.putln(
- '__Pyx_WriteUnraisable("%s");' %
- self.entry.qualified_name)
- #if not self.return_type.is_void:
- if default_retval:
- code.putln(
- "%s = %s;" % (
- Naming.retval_cname,
- default_retval))
- #self.return_type.default_value))
- # ----- Return cleanup
- code.put_label(code.return_label)
- code.put_var_decrefs(lenv.var_entries, used_only = 1)
- #code.put_var_decrefs(lenv.arg_entries)
- self.generate_argument_decrefs(lenv, code)
- self.put_stararg_decrefs(code)
- if acquire_gil:
- code.putln("PyGILState_Release(_save);")
- if not self.return_type.is_void:
- code.putln("return %s;" % Naming.retval_cname)
- code.putln("}")
-
- def put_stararg_decrefs(self, code):
- pass
-
- def declare_argument(self, env, arg, readonly = 0):
- if arg.type.is_void:
- error(arg.pos, "Invalid use of 'void'")
- elif not arg.type.is_complete() and not arg.type.is_array:
- error(arg.pos,
- "Argument type '%s' is incomplete" % arg.type)
- return env.declare_arg(arg.name, arg.type, arg.pos,
- readonly = readonly)
-
- def generate_argument_increfs(self, env, code):
- # Turn writable borrowed argument refs into owned refs.
- # This is necessary, because if the argument is assigned to,
- # it will be decrefed.
- for entry in env.arg_entries:
- if not entry.is_readonly:
- code.put_var_incref(entry)
-
- def generate_argument_decrefs(self, env, code):
- for entry in env.arg_entries:
- if not entry.is_readonly:
- code.put_var_decref(entry)
-
- def generate_execution_code(self, code):
- pass
-
-
-class CFuncDefNode(FuncDefNode):
- # C function definition.
- #
- # visibility 'private' or 'public' or 'extern'
- # base_type CBaseTypeNode
- # declarator CDeclaratorNode
- # body StatListNode
- # api boolean
- #
- # with_gil boolean Acquire GIL around body
- # type CFuncType
-
- def unqualified_name(self):
- return self.entry.name
-
- def analyse_declarations(self, env):
- base_type = self.base_type.analyse(env)
- name_declarator, type = self.declarator.analyse(base_type, env)
- if not type.is_cfunction:
- error(self.pos,
- "Suite attached to non-function declaration")
- # Remember the actual type according to the function header
- # written here, because the type in the symbol table entry
- # may be different if we're overriding a C method inherited
- # from the base type of an extension type.
- self.type = type
- name = name_declarator.name
- cname = name_declarator.cname
- self.entry = env.declare_cfunction(
- name, type, self.pos,
- cname = cname, visibility = self.visibility,
- defining = self.body is not None,
- api = self.api)
- self.return_type = type.return_type
-
- def declare_arguments(self, env):
- type = self.type
- without_gil = type.nogil and not type.with_gil
- for arg in type.args:
- if not arg.name:
- error(arg.pos, "Missing argument name")
- self.declare_argument(env, arg,
- readonly = without_gil and arg.type.is_pyobject)
-
- def need_gil_acquisition(self, lenv):
- type = self.type
- with_gil = type.with_gil
- if type.nogil and not with_gil:
-# for arg in type.args:
-# if arg.type.is_pyobject:
-# error(self.pos,
-# "Function with Python argument cannot be declared nogil")
- if type.return_type.is_pyobject:
- error(self.pos,
- "Function with Python return type cannot be declared nogil")
- for entry in lenv.var_entries + lenv.temp_entries:
- #print "CFuncDefNode.need_gil_acquisition:", entry.name, entry.cname, "readonly =", entry.is_readonly ###
- if entry.type.is_pyobject and not entry.is_readonly:
- error(self.pos, "Function declared nogil has Python locals or temporaries")
- return with_gil
-
- def generate_function_header(self, code, with_pymethdef):
- arg_decls = []
- type = self.type
- visibility = self.entry.visibility
- for arg in type.args:
- arg_decls.append(arg.declaration_code())
- if type.has_varargs:
- arg_decls.append("...")
- if not arg_decls:
- arg_decls = ["void"]
- entity = type.function_header_code(self.entry.func_cname,
- string.join(arg_decls, ","))
- if visibility == 'public':
- dll_linkage = "DL_EXPORT"
- else:
- dll_linkage = None
- header = self.return_type.declaration_code(entity,
- dll_linkage = dll_linkage)
- if visibility <> 'private':
- storage_class = "%s " % Naming.extern_c_macro
- else:
- storage_class = "static "
- code.putln("%s%s {" % (
- storage_class,
- header))
-
- def generate_argument_declarations(self, env, code):
- # Arguments already declared in function header
- pass
-
- def generate_keyword_list(self, code):
- pass
-
- def generate_argument_parsing_code(self, code):
- pass
-
- def generate_argument_conversion_code(self, code):
- pass
-
- def generate_argument_type_tests(self, code):
- pass
-
- def error_value(self):
- if self.return_type.is_pyobject:
- return "0"
- else:
- #return None
- return self.entry.type.exception_value
-
- def caller_will_check_exceptions(self):
- return self.entry.type.exception_check
-
-
-class PyArgDeclNode(Node):
- # Argument which must be a Python object (used
- # for * and ** arguments).
- #
- # name string
- # entry Symtab.Entry
-
- pass
-
-
-class DefNode(FuncDefNode):
- # A Python function definition.
- #
- # name string the Python name of the function
- # args [CArgDeclNode] formal arguments
- # star_arg PyArgDeclNode or None * argument
- # starstar_arg PyArgDeclNode or None ** argument
- # doc string or None
- # body StatListNode
- #
- # The following subnode is constructed internally
- # when the def statement is inside a Python class definition.
- #
- # assmt AssignmentNode Function construction/assignment
-
- assmt = None
- num_kwonly_args = 0
- reqd_kw_flags_cname = "0"
- has_star_or_kwonly_args = 0
-
- def __init__(self, pos, **kwds):
- FuncDefNode.__init__(self, pos, **kwds)
- n = 0
- for arg in self.args:
- if arg.kw_only:
- n += 1
- self.num_kwonly_args = n
- if self.star_arg or self.starstar_arg or n > 0:
- self.has_star_or_kwonly_args = 1
-
- def analyse_declarations(self, env):
- for arg in self.args:
- base_type = arg.base_type.analyse(env)
- name_declarator, type = \
- arg.declarator.analyse(base_type, env)
- arg.name = name_declarator.name
- if name_declarator.cname:
- error(self.pos,
- "Python function argument cannot have C name specification")
- arg.type = type.as_argument_type()
- arg.hdr_type = None
- arg.needs_conversion = 0
- arg.needs_type_test = 0
- arg.is_generic = 1
- if arg.allow_none is not None and not arg.type.is_extension_type:
- error(self.pos,
- "Only extension type arguments can have 'or None' or 'not None'")
- self.declare_pyfunction(env)
- self.analyse_signature(env)
- self.return_type = self.entry.signature.return_type()
-# if self.has_star_or_kwonly_args:
-# env.use_utility_code(get_starargs_utility_code)
-
- def analyse_signature(self, env):
- any_type_tests_needed = 0
- sig = self.entry.signature
- nfixed = sig.num_fixed_args()
- for i in range(nfixed):
- if i < len(self.args):
- arg = self.args[i]
- arg.is_generic = 0
- if sig.is_self_arg(i):
- arg.is_self_arg = 1
- arg.hdr_type = arg.type = env.parent_type
- arg.needs_conversion = 0
- else:
- arg.hdr_type = sig.fixed_arg_type(i)
- if not arg.type.same_as(arg.hdr_type):
- if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
- arg.needs_type_test = 1
- any_type_tests_needed = 1
- else:
- arg.needs_conversion = 1
- if arg.needs_conversion:
- arg.hdr_cname = Naming.arg_prefix + arg.name
- else:
- arg.hdr_cname = Naming.var_prefix + arg.name
- else:
- self.bad_signature()
- return
- if nfixed < len(self.args):
- if not sig.has_generic_args:
- self.bad_signature()
- for arg in self.args:
- if arg.is_generic and arg.type.is_extension_type:
- arg.needs_type_test = 1
- any_type_tests_needed = 1
-# if any_type_tests_needed:
-# env.use_utility_code(arg_type_test_utility_code)
-
- def bad_signature(self):
- sig = self.entry.signature
- expected_str = "%d" % sig.num_fixed_args()
- if sig.has_generic_args:
- expected_str = expected_str + " or more"
- name = self.name
- if name.startswith("__") and name.endswith("__"):
- desc = "Special method"
- else:
- desc = "Method"
- error(self.pos,
- "%s %s has wrong number of arguments "
- "(%d declared, %s expected)" % (
- desc, self.name, len(self.args), expected_str))
-
- def declare_pyfunction(self, env):
- #print "DefNode.declare_pyfunction:", self.name, "in", env ###
- name = self.name
- entry = env.declare_pyfunction(self.name, self.pos)
- self.entry = entry
- prefix = env.scope_prefix
- entry.func_cname = \
- Naming.func_prefix + prefix + name
- entry.pymethdef_cname = \
- Naming.pymethdef_prefix + prefix + name
- if not entry.is_special:
- entry.doc = self.doc
- entry.doc_cname = \
- Naming.funcdoc_prefix + prefix + name
-
- def declare_arguments(self, env):
- for arg in self.args:
- if not arg.name:
- error(arg.pos, "Missing argument name")
- if arg.needs_conversion:
- arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
- if arg.type.is_pyobject:
- arg.entry.init = "0"
- arg.entry.init_to_none = 0
- else:
- arg.entry = self.declare_argument(env, arg)
- arg.entry.used = 1
- arg.entry.is_self_arg = arg.is_self_arg
- if arg.hdr_type:
- if arg.is_self_arg or \
- (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
- arg.entry.is_declared_generic = 1
- self.declare_python_arg(env, self.star_arg)
- self.declare_python_arg(env, self.starstar_arg)
-
- def declare_python_arg(self, env, arg):
- if arg:
- entry = env.declare_var(arg.name,
- PyrexTypes.py_object_type, arg.pos)
- entry.used = 1
- entry.init = "0"
- entry.init_to_none = 0
- entry.xdecref_cleanup = 1
- arg.entry = entry
-
- def analyse_expressions(self, env):
- self.analyse_default_values(env)
- if env.is_py_class_scope:
- self.synthesize_assignment_node(env)
-
- def analyse_default_values(self, env):
- for arg in self.args:
- if arg.default:
- if arg.is_generic:
- arg.default.analyse_types(env)
- arg.default = arg.default.coerce_to(arg.type, env)
- arg.default.allocate_temps(env)
- arg.default_entry = env.add_default_value(arg.type)
- arg.default_entry.used = 1
- else:
- error(arg.pos,
- "This argument cannot have a default value")
- arg.default = None
-
- def synthesize_assignment_node(self, env):
- import ExprNodes
- self.assmt = SingleAssignmentNode(self.pos,
- lhs = ExprNodes.NameNode(self.pos, name = self.name),
- rhs = ExprNodes.UnboundMethodNode(self.pos,
- class_cname = env.class_obj_cname,
- function = ExprNodes.PyCFunctionNode(self.pos,
- pymethdef_cname = self.entry.pymethdef_cname)))
- self.assmt.analyse_declarations(env)
- self.assmt.analyse_expressions(env)
-
- def generate_function_header(self, code, with_pymethdef):
- arg_code_list = []
- sig = self.entry.signature
- if sig.has_dummy_arg:
- arg_code_list.append(
- "PyObject *%s" % Naming.self_cname)
- for arg in self.args:
- if not arg.is_generic:
- if arg.is_self_arg:
- arg_code_list.append("PyObject *%s" % arg.hdr_cname)
- else:
- arg_code_list.append(
- arg.hdr_type.declaration_code(arg.hdr_cname))
- if sig.has_generic_args:
- arg_code_list.append(
- "PyObject *%s, PyObject *%s"
- % (Naming.args_cname, Naming.kwds_cname))
- arg_code = ", ".join(arg_code_list)
- dc = self.return_type.declaration_code(self.entry.func_cname)
- header = "static %s(%s)" % (dc, arg_code)
- code.putln("%s; /*proto*/" % header)
- if self.entry.doc:
- code.putln(
- 'static char %s[] = "%s";' % (
- self.entry.doc_cname,
- self.entry.doc))
- if with_pymethdef:
- code.put(
- "static PyMethodDef %s = " %
- self.entry.pymethdef_cname)
- code.put_pymethoddef(self.entry, ";")
- code.putln("%s {" % header)
-
- def generate_argument_declarations(self, env, code):
- for arg in self.args:
- if arg.is_generic: # or arg.needs_conversion:
- code.put_var_declaration(arg.entry)
-
- def generate_keyword_list(self, code):
- if self.entry.signature.has_generic_args:
- reqd_kw_flags = []
- has_reqd_kwds = False
- code.put(
- "static char *%s[] = {" %
- Naming.kwdlist_cname)
- for arg in self.args:
- if arg.is_generic:
- code.put(
- '"%s",' %
- arg.name)
- if arg.kw_only and not arg.default:
- has_reqd_kwds = 1
- flag = "1"
- else:
- flag = "0"
- reqd_kw_flags.append(flag)
- code.putln(
- "0};")
- if has_reqd_kwds:
- flags_name = Naming.reqd_kwds_cname
- self.reqd_kw_flags_cname = flags_name
- code.putln(
- "static char %s[] = {%s};" % (
- flags_name,
- ",".join(reqd_kw_flags)))
-
- def generate_argument_parsing_code(self, code):
- # Generate PyArg_ParseTuple call for generic
- # arguments, if any.
- has_kwonly_args = self.num_kwonly_args > 0
- has_star_or_kw_args = self.star_arg is not None \
- or self.starstar_arg is not None or has_kwonly_args
- if not self.entry.signature.has_generic_args:
- if has_star_or_kw_args:
- error(self.pos, "This method cannot have * or keyword arguments")
- else:
- arg_addrs = []
- arg_formats = []
- default_seen = 0
- for arg in self.args:
- arg_entry = arg.entry
- if arg.is_generic:
- if arg.default:
- code.putln(
- "%s = %s;" % (
- arg_entry.cname,
- arg.default_entry.cname))
- if not default_seen:
- arg_formats.append("|")
- default_seen = 1
- elif default_seen and not arg.kw_only:
- error(arg.pos, "Non-default argument following default argument")
- arg_addrs.append("&" + arg_entry.cname)
- format = arg_entry.type.parsetuple_format
- if format:
- arg_formats.append(format)
- else:
- error(arg.pos,
- "Cannot convert Python object argument to type '%s'"
- % arg.type)
- error_return_code = "return %s;" % self.error_value()
- argformat = '"%s"' % string.join(arg_formats, "")
- if has_star_or_kw_args:
- self.generate_stararg_getting_code(code)
- pt_arglist = [Naming.args_cname, Naming.kwds_cname, argformat,
- Naming.kwdlist_cname] + arg_addrs
- pt_argstring = string.join(pt_arglist, ", ")
- code.put(
- 'if (!PyArg_ParseTupleAndKeywords(%s)) ' %
- pt_argstring)
- if has_star_or_kw_args:
- code.putln("{")
- code.put_xdecref(Naming.args_cname, py_object_type)
- code.put_xdecref(Naming.kwds_cname, py_object_type)
- self.generate_arg_xdecref(self.star_arg, code)
- self.generate_arg_xdecref(self.starstar_arg, code)
- code.putln(error_return_code)
- code.putln("}")
- else:
- code.putln(error_return_code)
-
- def put_stararg_decrefs(self, code):
- if self.has_star_or_kwonly_args:
- code.put_xdecref(Naming.args_cname, py_object_type)
- code.put_xdecref(Naming.kwds_cname, py_object_type)
-
- def generate_arg_xdecref(self, arg, code):
- if arg:
- code.put_var_xdecref(arg.entry)
-
- def arg_address(self, arg):
- if arg:
- return "&%s" % arg.entry.cname
- else:
- return 0
-
- def generate_stararg_getting_code(self, code):
- num_kwonly = self.num_kwonly_args
- nargs = len(self.args) - num_kwonly - self.entry.signature.num_fixed_args()
- star_arg_addr = self.arg_address(self.star_arg)
- starstar_arg_addr = self.arg_address(self.starstar_arg)
- code.use_utility_code(get_starargs_utility_code)
- code.putln(
- "if (__Pyx_GetStarArgs(&%s, &%s, %s, %s, %s, %s, %s) < 0) return %s;" % (
- Naming.args_cname,
- Naming.kwds_cname,
- Naming.kwdlist_cname,
- nargs,
- star_arg_addr,
- starstar_arg_addr,
- self.reqd_kw_flags_cname,
- self.error_value()))
-
- def generate_argument_conversion_code(self, code):
- # Generate code to convert arguments from
- # signature type to declared type, if needed.
- for arg in self.args:
- if arg.needs_conversion:
- self.generate_arg_conversion(arg, code)
-
- def generate_arg_conversion(self, arg, code):
- # Generate conversion code for one argument.
- old_type = arg.hdr_type
- new_type = arg.type
- if old_type.is_pyobject:
- self.generate_arg_conversion_from_pyobject(arg, code)
- elif new_type.is_pyobject:
- self.generate_arg_conversion_to_pyobject(arg, code)
- else:
- if new_type.assignable_from(old_type):
- code.putln(
- "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
- else:
- error(arg.pos,
- "Cannot convert argument from '%s' to '%s'" %
- (old_type, new_type))
-
- def generate_arg_conversion_from_pyobject(self, arg, code):
- new_type = arg.type
- func = new_type.from_py_function
- if func:
- code.putln("%s = %s(%s); if (PyErr_Occurred()) %s" % (
- arg.entry.cname,
- func,
- arg.hdr_cname,
- code.error_goto(arg.pos)))
- else:
- error(arg.pos,
- "Cannot convert Python object argument to type '%s'"
- % new_type)
-
- def generate_arg_conversion_to_pyobject(self, arg, code):
- old_type = arg.hdr_type
- func = old_type.to_py_function
- if func:
- code.putln("%s = %s(%s); if (!%s) %s" % (
- arg.entry.cname,
- func,
- arg.hdr_cname,
- arg.entry.cname,
- code.error_goto(arg.pos)))
- else:
- error(arg.pos,
- "Cannot convert argument of type '%s' to Python object"
- % old_type)
-
- def generate_argument_type_tests(self, code):
- # Generate type tests for args whose signature
- # type is PyObject * and whose declared type is
- # a subtype thereof.
- for arg in self.args:
- if arg.needs_type_test:
- self.generate_arg_type_test(arg, code)
-
- def generate_arg_type_test(self, arg, code):
- # Generate type test for one argument.
- if arg.type.typeobj_is_available():
- typeptr_cname = arg.type.typeptr_cname
- arg_code = "((PyObject *)%s)" % arg.entry.cname
- code.use_utility_code(arg_type_test_utility_code)
- code.putln(
- 'if (!__Pyx_ArgTypeTest(%s, %s, %d, "%s")) %s' % (
- arg_code,
- typeptr_cname,
- #not arg.not_none,
- arg.allow_none <> False,
- arg.name,
- code.error_goto(arg.pos)))
- if arg.allow_none is None:
- one_time_warning(arg.pos, 'or_none',
- "'not None' will become the default in a future version of Pyrex. "
- "Use 'or None' to allow passing None.")
- else:
- error(arg.pos, "Cannot test type of extern C class "
- "without type object name specification")
-
- def generate_execution_code(self, code):
- # Evaluate and store argument default values
- for arg in self.args:
- default = arg.default
- if default:
- default.generate_evaluation_code(code)
- default.make_owned_reference(code)
- code.putln(
- "%s = %s;" % (
- arg.default_entry.cname,
- default.result_as(arg.default_entry.type)))
- default.generate_post_assignment_code(code)
-# if default.is_temp and default.type.is_pyobject:
-# code.putln(
-# "%s = 0;" %
-# default.result())
- # For Python class methods, create and store function object
- if self.assmt:
- self.assmt.generate_execution_code(code)
-
- def error_value(self):
- return self.entry.signature.error_value
-
- def caller_will_check_exceptions(self):
- return 1
-
-
-class PyClassDefNode(StatNode, BlockNode):
- # A Python class definition.
- #
- # name string Name of the class
- # doc string or None
- # body StatNode Attribute definition code
- # entry Symtab.Entry
- # scope PyClassScope
- #
- # The following subnodes are constructed internally:
- #
- # dict DictNode Class dictionary
- # classobj ClassNode Class object
- # target NameNode Variable to assign class object to
-
- def __init__(self, pos, name, bases, doc, body):
- StatNode.__init__(self, pos)
- self.name = name
- self.doc = doc
- self.body = body
- import ExprNodes
- self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
- if self.doc:
- doc_node = ExprNodes.StringNode(pos, value = self.doc)
- else:
- doc_node = None
- self.classobj = ExprNodes.ClassNode(pos,
- name = ExprNodes.StringNode(pos, value = name),
- bases = bases, dict = self.dict, doc = doc_node)
- self.target = ExprNodes.NameNode(pos, name = name)
-
- def analyse_declarations(self, env):
- self.target.analyse_target_declaration(env)
-
- def analyse_expressions(self, env):
- self.dict.analyse_expressions(env)
- self.classobj.analyse_expressions(env)
- genv = env.global_scope()
- cenv = PyClassScope(name = self.name, outer_scope = genv)
- cenv.class_dict_cname = self.dict.result()
- cenv.class_obj_cname = self.classobj.result()
- self.scope = cenv
- self.body.analyse_declarations(cenv)
- self.body.analyse_expressions(cenv)
- self.target.analyse_target_expression(env, self.classobj)
- self.dict.release_temp(env)
- #self.classobj.release_temp(env)
- #self.target.release_target_temp(env)
-
- def generate_function_definitions(self, env, code):
- #self.generate_py_string_decls(self.scope, code)
- self.body.generate_function_definitions(
- self.scope, code)
-
- def generate_execution_code(self, code):
- self.dict.generate_evaluation_code(code)
- self.classobj.generate_evaluation_code(code)
- self.body.generate_execution_code(code)
- self.target.generate_assignment_code(self.classobj, code)
- self.dict.generate_disposal_code(code)
-
-
-class CClassDefNode(StatNode):
- # An extension type definition.
- #
- # visibility 'private' or 'public' or 'extern'
- # typedef_flag boolean
- # api boolean
- # module_name string or None For import of extern type objects
- # class_name string Unqualified name of class
- # as_name string or None Name to declare as in this scope
- # base_class_module string or None Module containing the base class
- # base_class_name string or None Name of the base class
- # options CClassOptions:
- # objstruct_name string or None Specified C name of object struct
- # typeobj_name string or None Specified C name of type object
- # no_gc boolean Suppress GC support
- # in_pxd boolean Is in a .pxd file
- # doc string or None
- # body StatNode or None
- # entry Symtab.Entry
- # base_type PyExtensionType or None
-
- entry = None
-
- def analyse_declarations(self, env):
- #print "CClassDefNode.analyse_declarations:", self.class_name
- #print "...visibility =", self.visibility
- #print "...module_name =", self.module_name
- if env.in_cinclude and not self.options.objstruct_cname:
- error(self.pos, "Object struct name specification required for "
- "C class defined in 'extern from' block")
- self.base_type = None
- has_body = self.body is not None
- if self.base_class_name:
- if self.base_class_module:
- base_class_scope = env.find_module(self.base_class_module, self.pos)
- else:
- base_class_scope = env
- if base_class_scope:
- base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
- if base_class_entry:
- if not base_class_entry.is_type:
- error(self.pos, "'%s' is not a type name" % self.base_class_name)
- elif not base_class_entry.type.is_extension_type:
- error(self.pos, "'%s' is not an extension type" % self.base_class_name)
- elif has_body and base_class_entry.visibility <> 'extern' and not base_class_entry.type.is_defined():
- error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
- else:
- self.base_type = base_class_entry.type
- if self.module_name and self.visibility <> 'extern':
- module_path = self.module_name.split(".")
- home_scope = env.find_imported_module(module_path, self.pos)
- if not home_scope:
- return
- else:
- home_scope = env
- self.entry = home_scope.declare_c_class(
- name = self.class_name,
- pos = self.pos,
- defining = has_body and self.in_pxd,
- implementing = has_body and not self.in_pxd,
- module_name = self.module_name,
- base_type = self.base_type,
- visibility = self.visibility,
- typedef_flag = self.typedef_flag,
- api = self.api,
- options = self.options)
- if home_scope is not env and self.visibility == 'extern':
- env.add_imported_entry(self.class_name, self.entry, pos)
- scope = self.entry.type.scope
- if self.doc:
- scope.doc = self.doc
- if has_body:
- self.body.analyse_declarations(scope)
- if self.in_pxd:
- scope.defined = 1
- else:
- scope.implemented = 1
- env.allocate_vtable_names(self.entry)
-
- def analyse_expressions(self, env):
- if self.body:
- self.body.analyse_expressions(env)
-
- def generate_function_definitions(self, env, code):
- if self.entry and self.body:
-# self.body.generate_function_definitions(
-# self.entry.type.scope, code)
- self.body.generate_function_definitions(env, code)
-
- def generate_execution_code(self, code):
- # This is needed to generate evaluation code for
- # default values of method arguments.
- if self.body:
- self.body.generate_execution_code(code)
-
-
-class PropertyNode(StatNode):
- # Definition of a property in an extension type.
- #
- # name string
- # doc string or None Doc string
- # body StatListNode
-
- def analyse_declarations(self, env):
- #print "PropertyNode.analyse_declarations:", env ###
- entry = env.declare_property(self.name, self.doc, self.pos)
- if entry:
- #if self.doc:
- # doc_entry = env.get_string_const(self.doc)
- # entry.doc_cname = doc_entry.cname
- self.body.analyse_declarations(entry.scope)
-
- def analyse_expressions(self, env):
- self.body.analyse_expressions(env)
-
- def generate_function_definitions(self, env, code):
- self.body.generate_function_definitions(env, code)
-
- def generate_execution_code(self, code):
- pass
-
-
-class GlobalNode(StatNode):
- # Global variable declaration.
- #
- # names [string]
-
- def analyse_declarations(self, env):
- for name in self.names:
- env.declare_global(name, self.pos)
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class ExprStatNode(StatNode):
- # Expression used as a statement.
- #
- # expr ExprNode
-
- def analyse_expressions(self, env):
- self.expr.analyse_expressions(env)
- self.expr.release_temp(env)
-
- def generate_execution_code(self, code):
- self.expr.generate_evaluation_code(code)
- if not self.expr.is_temp and self.expr.result():
- code.putln("%s;" % self.expr.result())
- self.expr.generate_disposal_code(code)
-
-
-class AssignmentNode(StatNode):
- # Abstract base class for assignment nodes.
- #
- # The analyse_expressions and generate_execution_code
- # phases of assignments are split into two sub-phases
- # each, to enable all the right hand sides of a
- # parallel assignment to be evaluated before assigning
- # to any of the left hand sides.
-
- def analyse_expressions(self, env):
- self.analyse_types(env)
- self.allocate_rhs_temps(env)
- self.allocate_lhs_temps(env)
-
- def generate_execution_code(self, code):
- self.generate_rhs_evaluation_code(code)
- self.generate_assignment_code(code)
-
-
-class SingleAssignmentNode(AssignmentNode):
- # The simplest case:
- #
- # a = b
- #
- # lhs ExprNode Left hand side
- # rhs ExprNode Right hand side
-
- def analyse_declarations(self, env):
- self.lhs.analyse_target_declaration(env)
-
- def analyse_types(self, env, use_temp = 0):
- self.rhs.analyse_types(env)
- self.lhs.analyse_target_types(env)
- self.lhs.gil_assignment_check(env)
- self.rhs = self.rhs.coerce_to(self.lhs.type, env)
- if use_temp:
- self.rhs = self.rhs.coerce_to_temp(env)
-
- def allocate_rhs_temps(self, env):
- self.rhs.allocate_temps(env)
-
- def allocate_lhs_temps(self, env):
- self.lhs.allocate_target_temps(env, self.rhs)
-
- def generate_rhs_evaluation_code(self, code):
- self.rhs.generate_evaluation_code(code)
-
- def generate_assignment_code(self, code):
- self.lhs.generate_assignment_code(self.rhs, code)
-
-
-class AugmentedAssignmentNode(SingleAssignmentNode):
- # An in-place operation:
- #
- # a op= b
- #
- # lhs ExprNode Left hand side
- # operator string
- # rhs ExprNode Right hand side
-
- def analyse_types(self, env):
- op = self.operator
- self.rhs.analyse_types(env)
- self.lhs.analyse_inplace_types(env)
- type = self.lhs.type
- if type.is_pyobject:
- type = py_object_type
- else:
- if type.is_ptr and (op == '+=' or op == '-='):
- type = c_int_type
- elif op == "**=":
- error(self.pos, "**= operator not supported for non-Python types")
- return
- self.rhs = self.rhs.coerce_to(type, env)
-
- def allocate_lhs_temps(self, env):
- self.lhs.allocate_inplace_target_temps(env, self.rhs)
-
- def generate_assignment_code(self, code):
- self.lhs.generate_inplace_assignment_code(self.operator, self.rhs, code)
-
-
-class CascadedAssignmentNode(AssignmentNode):
- # An assignment with multiple left hand sides:
- #
- # a = b = c
- #
- # lhs_list [ExprNode] Left hand sides
- # rhs ExprNode Right hand sides
- #
- # Used internally:
- #
- # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
-
- def analyse_declarations(self, env):
- for lhs in self.lhs_list:
- lhs.analyse_target_declaration(env)
-
- def analyse_types(self, env, use_temp = 0):
- self.rhs.analyse_types(env)
- if use_temp:
- self.rhs = self.rhs.coerce_to_temp(env)
- else:
- self.rhs = self.rhs.coerce_to_simple(env)
- from ExprNodes import CloneNode
- self.coerced_rhs_list = []
- for lhs in self.lhs_list:
- lhs.analyse_target_types(env)
- lhs.gil_assignment_check(env)
- rhs = CloneNode(self.rhs)
- rhs = rhs.coerce_to(lhs.type, env)
- self.coerced_rhs_list.append(rhs)
-
- def allocate_rhs_temps(self, env):
- self.rhs.allocate_temps(env)
-
- def allocate_lhs_temps(self, env):
- for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
- rhs.allocate_temps(env)
- lhs.allocate_target_temps(env, rhs)
- #lhs.release_target_temp(env)
- #rhs.release_temp(env)
- self.rhs.release_temp(env)
-
- def generate_rhs_evaluation_code(self, code):
- self.rhs.generate_evaluation_code(code)
-
- def generate_assignment_code(self, code):
- for i in range(len(self.lhs_list)):
- lhs = self.lhs_list[i]
- rhs = self.coerced_rhs_list[i]
- rhs.generate_evaluation_code(code)
- lhs.generate_assignment_code(rhs, code)
- # Assignment has disposed of the cloned RHS
- self.rhs.generate_disposal_code(code)
-
-class ParallelAssignmentNode(AssignmentNode):
- # A combined packing/unpacking assignment:
- #
- # a, b, c = d, e, f
- #
- # This has been rearranged by the parser into
- #
- # a = d ; b = e ; c = f
- #
- # but we must evaluate all the right hand sides
- # before assigning to any of the left hand sides.
- #
- # stats [AssignmentNode] The constituent assignments
-
- def analyse_declarations(self, env):
- for stat in self.stats:
- stat.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- for stat in self.stats:
- stat.analyse_types(env, use_temp = 1)
- stat.allocate_rhs_temps(env)
- for stat in self.stats:
- stat.allocate_lhs_temps(env)
-
- def generate_execution_code(self, code):
- for stat in self.stats:
- stat.generate_rhs_evaluation_code(code)
- for stat in self.stats:
- stat.generate_assignment_code(code)
-
-
-class PrintStatNode(StatNode):
- # print statement
- #
- # args [ExprNode]
- # ends_with_comma boolean
-
- def analyse_expressions(self, env):
- for i in range(len(self.args)):
- arg = self.args[i]
- arg.analyse_types(env)
- arg = arg.coerce_to_pyobject(env)
- arg.allocate_temps(env)
- arg.release_temp(env)
- self.args[i] = arg
-# env.use_utility_code(printing_utility_code)
- self.gil_check(env)
-
- gil_message = "Python print statement"
-
- def generate_execution_code(self, code):
- for arg in self.args:
- arg.generate_evaluation_code(code)
- code.use_utility_code(printing_utility_code)
- code.putln(
- "if (__Pyx_PrintItem(%s) < 0) %s" % (
- arg.py_result(),
- code.error_goto(self.pos)))
- arg.generate_disposal_code(code)
- if not self.ends_with_comma:
- code.use_utility_code(printing_utility_code)
- code.putln(
- "if (__Pyx_PrintNewline() < 0) %s" %
- code.error_goto(self.pos))
-
-
-class DelStatNode(StatNode):
- # del statement
- #
- # args [ExprNode]
-
- def analyse_declarations(self, env):
- for arg in self.args:
- arg.analyse_target_declaration(env)
-
- def analyse_expressions(self, env):
- for arg in self.args:
- arg.analyse_target_expression(env, None)
- type = arg.type
- if not (type.is_pyobject
- or (type.is_ptr and type.base_type.is_struct_or_union
- and type.base_type.scope.is_cplus)):
- error(arg.pos, "'del' can only be applied to Python object or pointer to C++ type")
- if type.is_pyobject:
- self.gil_check(env)
-
- gil_message = "Deleting Python object"
-
- def generate_execution_code(self, code):
- for arg in self.args:
- if arg.type.is_pyobject:
- arg.generate_deletion_code(code)
- else:
- arg.generate_evaluation_code(code)
- code.putln("delete %s;" % arg.result())
- arg.generate_disposal_code(code)
-
-
-class PassStatNode(StatNode):
- # pass statement
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class BreakStatNode(StatNode):
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- if not code.break_label:
- error(self.pos, "break statement not inside loop")
- else:
- #code.putln(
- # "goto %s;" %
- # code.break_label)
- code.put_goto(code.break_label)
-
-
-class ContinueStatNode(StatNode):
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- if code.in_try_finally:
- error(self.pos, "continue statement inside try of try...finally")
- elif not code.continue_label:
- error(self.pos, "continue statement not inside loop")
- else:
- #code.putln(
- # "goto %s;" %
- # code.continue_label)
- code.put_goto(code.continue_label)
-
-
-class ReturnStatNode(StatNode):
- # return statement
- #
- # value ExprNode or None
- # return_type PyrexType
- # temps_in_use [Entry] Temps in use at time of return
-
- def analyse_expressions(self, env):
- return_type = env.return_type
- self.return_type = return_type
- self.temps_in_use = env.temps_in_use()
- if not return_type:
- error(self.pos, "Return not inside a function body")
- return
- if self.value:
- self.value.analyse_types(env)
- if return_type.is_void or return_type.is_returncode:
- error(self.value.pos,
- "Return with value in void function")
- else:
- self.value = self.value.coerce_to(env.return_type, env)
- self.value.allocate_temps(env)
- self.value.release_temp(env)
- else:
- if (not return_type.is_void
- and not return_type.is_pyobject
- and not return_type.is_returncode):
- error(self.pos, "Return value required")
- if return_type.is_pyobject:
- self.gil_check(env)
-
- gil_message = "Returning Python object"
-
- def generate_execution_code(self, code):
- if not self.return_type:
- # error reported earlier
- return
- if self.value:
- self.value.generate_evaluation_code(code)
- self.value.make_owned_reference(code)
- code.putln(
- "%s = %s;" % (
- Naming.retval_cname,
- self.value.result_as(self.return_type)))
- self.value.generate_post_assignment_code(code)
- else:
- if self.return_type.is_pyobject:
- code.put_init_to_py_none(Naming.retval_cname, self.return_type)
- elif self.return_type.is_returncode:
- code.putln(
- "%s = %s;" % (
- Naming.retval_cname,
- self.return_type.default_value))
- for entry in self.temps_in_use:
- code.put_var_decref_clear(entry)
- #code.putln(
- # "goto %s;" %
- # code.return_label)
- code.put_goto(code.return_label)
-
-
-class RaiseStatNode(StatNode):
- # raise statement
- #
- # exc_type ExprNode or None
- # exc_value ExprNode or None
- # exc_tb ExprNode or None
-
- def analyse_expressions(self, env):
- if self.exc_type:
- self.exc_type.analyse_types(env)
- self.exc_type = self.exc_type.coerce_to_pyobject(env)
- self.exc_type.allocate_temps(env)
- if self.exc_value:
- self.exc_value.analyse_types(env)
- self.exc_value = self.exc_value.coerce_to_pyobject(env)
- self.exc_value.allocate_temps(env)
- if self.exc_tb:
- self.exc_tb.analyse_types(env)
- self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
- self.exc_tb.allocate_temps(env)
- if self.exc_type:
- self.exc_type.release_temp(env)
- if self.exc_value:
- self.exc_value.release_temp(env)
- if self.exc_tb:
- self.exc_tb.release_temp(env)
- self.gil_check(env)
-
- gil_message = "Raising exception"
-
- def generate_execution_code(self, code):
- if self.exc_type:
- self.exc_type.generate_evaluation_code(code)
- type_code = self.exc_type.py_result()
- else:
- type_code = 0
- if self.exc_value:
- self.exc_value.generate_evaluation_code(code)
- value_code = self.exc_value.py_result()
- else:
- value_code = "0"
- if self.exc_tb:
- self.exc_tb.generate_evaluation_code(code)
- tb_code = self.exc_tb.py_result()
- else:
- tb_code = "0"
- code.use_utility_code(raise_utility_code)
- code.putln(
- "__Pyx_Raise(%s, %s, %s);" % (
- type_code,
- value_code,
- tb_code))
- if self.exc_type:
- self.exc_type.generate_disposal_code(code)
- if self.exc_value:
- self.exc_value.generate_disposal_code(code)
- if self.exc_tb:
- self.exc_tb.generate_disposal_code(code)
- code.putln(
- code.error_goto(self.pos))
-
-
-class ReraiseStatNode(StatNode):
-
- def analyse_expressions(self, env):
- env.reraise_used = 1
- self.gil_check(env)
-
- gil_message = "Raising exception"
-
- def generate_execution_code(self, code):
- vars = code.exc_vars
- if vars:
- tvars = tuple(vars)
- code.putln("PyErr_Restore(%s, %s, %s);" % tvars)
- code.putln("%s = %s = %s = 0;" % tvars)
- code.putln(code.error_goto(self.pos))
- else:
- error(self.pos, "Reraise not inside except clause")
-
-
-class AssertStatNode(StatNode):
- # assert statement
- #
- # cond ExprNode
- # value ExprNode or None
-
- def analyse_expressions(self, env):
- self.cond = self.cond.analyse_boolean_expression(env)
- if self.value:
- self.value.analyse_types(env)
- self.value = self.value.coerce_to_pyobject(env)
- self.value.allocate_temps(env)
- self.cond.release_temp(env)
- if self.value:
- self.value.release_temp(env)
- self.gil_check(env)
-
- gil_message = "Raising exception"
-
- def generate_execution_code(self, code):
- code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
- self.cond.generate_evaluation_code(code)
- code.putln(
- "if (!%s) {" %
- self.cond.result())
- if self.value:
- self.value.generate_evaluation_code(code)
- if self.value:
- code.putln(
- "PyErr_SetObject(PyExc_AssertionError, %s);" %
- self.value.py_result())
- else:
- code.putln(
- "PyErr_SetNone(PyExc_AssertionError);")
- code.putln(
- code.error_goto(self.pos))
- code.putln(
- "}")
- self.cond.generate_disposal_code(code)
- # Disposal code for value not needed because exception always raised
- #if self.value:
- # self.value.generate_disposal_code(code)
- code.putln("#endif")
-
-class IfStatNode(StatNode):
- # if statement
- #
- # if_clauses [IfClauseNode]
- # else_clause StatNode or None
-
- def analyse_declarations(self, env):
- for if_clause in self.if_clauses:
- if_clause.analyse_declarations(env)
- if self.else_clause:
- self.else_clause.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- for if_clause in self.if_clauses:
- if_clause.analyse_expressions(env)
- if self.else_clause:
- self.else_clause.analyse_expressions(env)
-
- def generate_execution_code(self, code):
- end_label = code.new_label()
- for if_clause in self.if_clauses:
- if_clause.generate_execution_code(code, end_label)
- if self.else_clause:
- code.putln("/*else*/ {")
- self.else_clause.generate_execution_code(code)
- code.putln("}")
- code.put_label(end_label)
-
-
-class IfClauseNode(Node):
- # if or elif clause in an if statement
- #
- # condition ExprNode
- # body StatNode
-
- def analyse_declarations(self, env):
- self.condition.analyse_declarations(env)
- self.body.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- self.condition = \
- self.condition.analyse_temp_boolean_expression(env)
- self.condition.release_temp(env)
- self.body.analyse_expressions(env)
-
- def generate_execution_code(self, code, end_label):
- self.condition.generate_evaluation_code(code)
- code.putln(
- "if (%s) {" %
- self.condition.result())
- self.body.generate_execution_code(code)
- #code.putln(
- # "goto %s;" %
- # end_label)
- code.put_goto(end_label)
- code.putln("}")
-
-
-class WhileStatNode(StatNode):
- # while statement
- #
- # condition ExprNode
- # body StatNode
- # else_clause StatNode
-
- def analyse_declarations(self, env):
- self.body.analyse_declarations(env)
- if self.else_clause:
- self.else_clause.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- self.condition = \
- self.condition.analyse_temp_boolean_expression(env)
- self.condition.release_temp(env)
- #env.recycle_pending_temps() # TEMPORARY
- self.body.analyse_expressions(env)
- if self.else_clause:
- self.else_clause.analyse_expressions(env)
-
- def generate_execution_code(self, code):
- old_loop_labels = code.new_loop_labels()
- code.putln(
- "while (1) {")
- self.condition.generate_evaluation_code(code)
- code.putln(
- "if (!%s) break;" %
- self.condition.result())
- self.body.generate_execution_code(code)
- code.put_label(code.continue_label)
- code.putln("}")
- break_label = code.break_label
- code.set_loop_labels(old_loop_labels)
- if self.else_clause:
- code.putln("/*else*/ {")
- self.else_clause.generate_execution_code(code)
- code.putln("}")
- code.put_label(break_label)
-
-
-class ForInStatNode(StatNode):
- # for statement
- #
- # target ExprNode
- # iterator IteratorNode
- # body StatNode
- # else_clause StatNode
- # item NextNode used internally
-
- def analyse_declarations(self, env):
- self.target.analyse_target_declaration(env)
- self.body.analyse_declarations(env)
- if self.else_clause:
- self.else_clause.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- import ExprNodes
- self.iterator.analyse_expressions(env)
- self.target.analyse_target_types(env)
- self.item = ExprNodes.NextNode(self.iterator, env)
- self.item = self.item.coerce_to(self.target.type, env)
- self.item.allocate_temps(env)
- self.target.allocate_target_temps(env, self.item)
- #self.item.release_temp(env)
- #self.target.release_target_temp(env)
- self.body.analyse_expressions(env)
- if self.else_clause:
- self.else_clause.analyse_expressions(env)
- self.iterator.release_temp(env)
-
- def generate_execution_code(self, code):
- old_loop_labels = code.new_loop_labels()
- self.iterator.generate_evaluation_code(code)
- code.putln(
- "for (;;) {")
- self.item.generate_evaluation_code(code)
- self.target.generate_assignment_code(self.item, code)
- self.body.generate_execution_code(code)
- code.put_label(code.continue_label)
- code.putln(
- "}")
- break_label = code.break_label
- code.set_loop_labels(old_loop_labels)
- if self.else_clause:
- code.putln("/*else*/ {")
- self.else_clause.generate_execution_code(code)
- code.putln("}")
- code.put_label(break_label)
- self.iterator.generate_disposal_code(code)
-
-
-class IntegerForStatNode(StatNode):
- # for expr rel name rel expr
- #
- # bound1 ExprNode
- # relation1 string
- # target NameNode
- # relation2 string
- # bound2 ExprNode
- # body StatNode
- # else_clause StatNode or None
- #
- # Used internally:
- #
- # is_py_target bool
- # loopvar_name string
- # py_loopvar_node PyTempNode or None
-
- def analyse_declarations(self, env):
- self.target.analyse_target_declaration(env)
- self.body.analyse_declarations(env)
- if self.else_clause:
- self.else_clause.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- import ExprNodes
- self.target.analyse_target_types(env)
- self.bound1.analyse_types(env)
- self.bound2.analyse_types(env)
- self.bound1 = self.bound1.coerce_to_integer(env)
- self.bound2 = self.bound2.coerce_to_integer(env)
- if not (self.bound2.is_name or self.bound2.is_literal):
- self.bound2 = self.bound2.coerce_to_temp(env)
- target_type = self.target.type
- if not (target_type.is_pyobject or target_type.is_int):
- error(self.target.pos,
- "Integer for-loop variable must be of type int or Python object")
- #if not (target_type.is_pyobject
- # or target_type.assignable_from(PyrexTypes.c_int_type)):
- # error(self.target.pos,
- # "Cannot assign integer to variable of type '%s'" % target_type)
- if target_type.is_int:
- self.is_py_target = 0
- self.loopvar_name = self.target.entry.cname
- self.py_loopvar_node = None
- else:
- self.is_py_target = 1
- c_loopvar_node = ExprNodes.TempNode(self.pos,
- PyrexTypes.c_long_type, env)
- c_loopvar_node.allocate_temps(env)
- self.loopvar_name = c_loopvar_node.result()
- self.py_loopvar_node = \
- ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
- self.bound1.allocate_temps(env)
- self.bound2.allocate_temps(env)
- if self.is_py_target:
- self.py_loopvar_node.allocate_temps(env)
- self.target.allocate_target_temps(env, self.py_loopvar_node)
- #self.target.release_target_temp(env)
- #self.py_loopvar_node.release_temp(env)
- self.body.analyse_expressions(env)
- if self.is_py_target:
- c_loopvar_node.release_temp(env)
- if self.else_clause:
- self.else_clause.analyse_expressions(env)
- self.bound1.release_temp(env)
- self.bound2.release_temp(env)
-
- def generate_execution_code(self, code):
- old_loop_labels = code.new_loop_labels()
- self.bound1.generate_evaluation_code(code)
- self.bound2.generate_evaluation_code(code)
- offset, incop = self.relation_table[self.relation1]
- code.putln(
- "for (%s = %s%s; %s %s %s; %s%s) {" % (
- self.loopvar_name,
- self.bound1.result(), offset,
- self.loopvar_name, self.relation2, self.bound2.result(),
- incop, self.loopvar_name))
- if self.py_loopvar_node:
- self.py_loopvar_node.generate_evaluation_code(code)
- self.target.generate_assignment_code(self.py_loopvar_node, code)
- self.body.generate_execution_code(code)
- code.put_label(code.continue_label)
- code.putln("}")
- break_label = code.break_label
- code.set_loop_labels(old_loop_labels)
- if self.else_clause:
- code.putln("/*else*/ {")
- self.else_clause.generate_execution_code(code)
- code.putln("}")
- code.put_label(break_label)
- self.bound1.generate_disposal_code(code)
- self.bound2.generate_disposal_code(code)
-
- relation_table = {
- # {relop : (initial offset, increment op)}
- '<=': ("", "++"),
- '<' : ("+1", "++"),
- '>=': ("", "--"),
- '>' : ("-1", "--")
- }
-
-
-class TryExceptStatNode(StatNode):
- # try .. except statement
- #
- # body StatNode
- # except_clauses [ExceptClauseNode]
- # else_clause StatNode or None
- # cleanup_list [Entry] temps to clean up on error
-
- def analyse_declarations(self, env):
- self.body.analyse_declarations(env)
- for except_clause in self.except_clauses:
- except_clause.analyse_declarations(env)
- if self.else_clause:
- self.else_clause.analyse_declarations(env)
- self.gil_check(env)
-
- def analyse_expressions(self, env):
- self.body.analyse_expressions(env)
- self.cleanup_list = env.free_temp_entries[:]
- for except_clause in self.except_clauses:
- except_clause.analyse_expressions(env)
- if self.else_clause:
- self.else_clause.analyse_expressions(env)
- self.gil_check(env)
-
- gil_message = "Try-except statement"
-
- def generate_execution_code(self, code):
- old_error_label = code.new_error_label()
- our_error_label = code.error_label
- end_label = code.new_label()
- code.putln(
- "/*try:*/ {")
- self.body.generate_execution_code(code)
- code.putln(
- "}")
- code.error_label = old_error_label
- if self.else_clause:
- code.putln(
- "/*else:*/ {")
- self.else_clause.generate_execution_code(code)
- code.putln(
- "}")
- code.put_goto(end_label)
- code.put_label(our_error_label)
- code.put_var_xdecrefs_clear(self.cleanup_list)
- default_clause_seen = 0
- for except_clause in self.except_clauses:
- if not except_clause.pattern:
- default_clause_seen = 1
- else:
- if default_clause_seen:
- error(except_clause.pos, "Default except clause not last")
- except_clause.generate_handling_code(code, end_label)
- if not default_clause_seen:
- code.put_goto(code.error_label)
- code.put_label(end_label)
-
-
-class ExceptClauseNode(Node):
- # Part of try ... except statement.
- #
- # pattern ExprNode
- # exc_target ExprNode or None
- # tb_target ExprNode or None
- # body StatNode
- # match_flag string result of exception match
- # exc_value ExcValueNode used internally
- # tb_value ExcValueNode used internally
- # function_name string qualified name of enclosing function
- # exc_vars (string * 3) local exception variables
- # reraise_used boolean body contains reraise statement
-
- def analyse_declarations(self, env):
- if self.exc_target:
- self.exc_target.analyse_target_declaration(env)
- if self.tb_target:
- self.tb_target.analyse_target_declaration(env)
- self.body.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- genv = env.global_scope()
- self.function_name = env.qualified_name
- if self.pattern:
- self.pattern.analyse_expressions(env)
- self.pattern = self.pattern.coerce_to_pyobject(env)
- self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
- self.pattern.release_temp(env)
- env.release_temp(self.match_flag)
- self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
- self.exc_value = self.analyse_target(env, self.exc_target, 1)
- self.tb_value = self.analyse_target(env, self.tb_target, 2)
- old_reraise_used = env.reraise_used
- env.reraise_used = False
- self.body.analyse_expressions(env)
- self.reraise_used = env.reraise_used
- env.reraise_used = old_reraise_used
- for var in self.exc_vars:
- env.release_temp(var)
-
- def analyse_target(self, env, target, var_no):
- if target:
- import ExprNodes
- value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[var_no])
- value.allocate_temps(env)
- target.analyse_target_expression(env, value)
- return value
-
- def generate_handling_code(self, code, end_label):
- code.mark_pos(self.pos)
- if self.pattern:
- self.pattern.generate_evaluation_code(code)
- code.putln(
- "%s = PyErr_ExceptionMatches(%s);" % (
- self.match_flag,
- self.pattern.py_result()))
- self.pattern.generate_disposal_code(code)
- code.putln(
- "if (%s) {" %
- self.match_flag)
- else:
- code.putln(
- "/*except:*/ {")
- any_bindings = self.exc_target or self.tb_target
- exc_vars_used = any_bindings or self.reraise_used
- if exc_vars_used:
- if any_bindings:
- code.putln(
- '%s; __Pyx_AddTraceback("%s");' % (
- code.error_setup(self.pos),
- self.function_name))
- exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
- code.putln("PyErr_Fetch(%s);" % exc_args)
- if any_bindings:
- code.use_utility_code(normalize_exception_utility_code)
- code.putln("if (__Pyx_NormalizeException(%s) < 0) %s" % (exc_args,
- code.error_goto(self.pos)))
- if self.exc_target:
- self.exc_value.generate_evaluation_code(code)
- self.exc_target.generate_assignment_code(self.exc_value, code)
- if self.tb_target:
- self.tb_value.generate_evaluation_code(code)
- self.tb_target.generate_assignment_code(self.tb_value, code)
- old_exc_vars = code.exc_vars
- code.exc_vars = self.exc_vars
- self.body.generate_execution_code(code)
- code.exc_vars = old_exc_vars
- if exc_vars_used:
- for var in self.exc_vars:
- code.putln("Py_XDECREF(%s); %s = 0;" % (var, var))
- code.put_goto(end_label)
- code.putln(
- "}")
-
-
-class TryFinallyStatNode(StatNode):
- # try ... finally statement
- #
- # body StatNode
- # finally_clause StatNode
- #
- # cleanup_list [Entry] temps to clean up on error
- #
- # The plan is that we funnel all continue, break
- # return and error gotos into the beginning of the
- # finally block, setting a variable to remember which
- # one we're doing. At the end of the finally block, we
- # switch on the variable to figure out where to go.
- # In addition, if we're doing an error, we save the
- # exception on entry to the finally block and restore
- # it on exit.
-
- preserve_exception = 1
-
- disallow_continue_in_try_finally = 0
- # There doesn't seem to be any point in disallowing
- # continue in the try block, since we have no problem
- # handling it.
-
- def analyse_declarations(self, env):
- self.body.analyse_declarations(env)
- self.finally_clause.analyse_declarations(env)
-
- def analyse_expressions(self, env):
- self.body.analyse_expressions(env)
- self.cleanup_list = env.free_temp_entries[:]
- self.finally_clause.analyse_expressions(env)
- self.gil_check(env)
-
- gil_message = "Try-finally statement"
-
- def generate_execution_code(self, code):
- old_error_label = code.error_label
- old_labels = code.all_new_labels()
- new_labels = code.get_all_labels()
- new_error_label = code.error_label
- catch_label = code.new_label()
- code.putln(
- "/*try:*/ {")
- if self.disallow_continue_in_try_finally:
- was_in_try_finally = code.in_try_finally
- code.in_try_finally = 1
- self.body.generate_execution_code(code)
- if self.disallow_continue_in_try_finally:
- code.in_try_finally = was_in_try_finally
- code.putln(
- "}")
- code.putln(
- "/*finally:*/ {")
- cases_used = []
- error_label_used = 0
- for i, new_label in enumerate(new_labels):
- if new_label in code.labels_used:
- cases_used.append(i)
- if new_label == new_error_label:
- error_label_used = 1
- error_label_case = i
- if cases_used:
- code.putln(
- "int __pyx_why;")
- if error_label_used and self.preserve_exception:
- code.putln(
- "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
- code.putln(
- "int %s;" % Naming.exc_lineno_name)
- code.use_label(catch_label)
- code.putln(
- "__pyx_why = 0; goto %s;" % catch_label)
- for i in cases_used:
- new_label = new_labels[i]
- #if new_label and new_label <> "<try>":
- if new_label == new_error_label and self.preserve_exception:
- self.put_error_catcher(code,
- new_error_label, i+1, catch_label)
- else:
- code.putln(
- "%s: __pyx_why = %s; goto %s;" % (
- new_label,
- i+1,
- catch_label))
- code.put_label(catch_label)
- code.set_all_labels(old_labels)
- if error_label_used:
- code.new_error_label()
- finally_error_label = code.error_label
- self.finally_clause.generate_execution_code(code)
- if error_label_used:
- if finally_error_label in code.labels_used and self.preserve_exception:
- over_label = code.new_label()
- code.put_goto(over_label);
- code.put_label(finally_error_label)
- code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
- for var in Naming.exc_vars:
- code.putln("Py_XDECREF(%s);" % var)
- code.putln("}")
- code.put_goto(old_error_label)
- code.put_label(over_label)
- code.error_label = old_error_label
- if cases_used:
- code.putln(
- "switch (__pyx_why) {")
- for i in cases_used:
- old_label = old_labels[i]
- if old_label == old_error_label and self.preserve_exception:
- self.put_error_uncatcher(code, i+1, old_error_label)
- else:
- code.use_label(old_label)
- code.putln(
- "case %s: goto %s;" % (
- i+1,
- old_label))
- code.putln(
- "}")
- code.putln(
- "}")
-
- def put_error_catcher(self, code, error_label, i, catch_label):
- code.putln(
- "%s: {" %
- error_label)
- code.putln(
- "__pyx_why = %s;" %
- i)
- code.put_var_xdecrefs_clear(self.cleanup_list)
- code.putln(
- "PyErr_Fetch(&%s, &%s, &%s);" %
- Naming.exc_vars)
- code.putln(
- "%s = %s;" % (
- Naming.exc_lineno_name, Naming.lineno_cname))
- #code.putln(
- # "goto %s;" %
- # catch_label)
- code.put_goto(catch_label)
- code.putln(
- "}")
-
- def put_error_uncatcher(self, code, i, error_label):
- code.putln(
- "case %s: {" %
- i)
- code.putln(
- "PyErr_Restore(%s, %s, %s);" %
- Naming.exc_vars)
- code.putln(
- "%s = %s;" % (
- Naming.lineno_cname, Naming.exc_lineno_name))
- for var in Naming.exc_vars:
- code.putln(
- "%s = 0;" %
- var)
- code.put_goto(error_label)
- code.putln(
- "}")
-
-
-class GILStatNode(TryFinallyStatNode):
- # 'with gil' or 'with nogil' statement
- #
- # state string 'gil' or 'nogil'
-
- preserve_exception = 0
-
- def __init__(self, pos, state, body):
- self.state = state
- TryFinallyStatNode.__init__(self, pos,
- body = body,
- finally_clause = GILExitNode(pos, state = state))
-
- def analyse_expressions(self, env):
- env.global_scope().gil_used = 1
- was_nogil = env.nogil
- env.nogil = 1
- TryFinallyStatNode.analyse_expressions(self, env)
- env.nogil = was_nogil
-
- def gil_check(self, env):
- pass
-
- def generate_execution_code(self, code):
- code.putln("/*with %s:*/ {" % self.state)
- if self.state == 'gil':
- code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
- else:
- code.putln("PyThreadState *_save;")
- code.putln("Py_UNBLOCK_THREADS")
- TryFinallyStatNode.generate_execution_code(self, code)
- code.putln("}")
-
-
-class GILExitNode(StatNode):
- # Used as the 'finally' block in a GILStatNode
- #
- # state string 'gil' or 'nogil'
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- if self.state == 'gil':
- code.putln("PyGILState_Release();")
- else:
- code.putln("Py_BLOCK_THREADS")
-
-
-class CImportStatNode(StatNode):
- # cimport statement
- #
- # module_name string Qualified name of module being imported
- # as_name string or None Name specified in "as" clause, if any
-
- def analyse_declarations(self, env):
- module_scope = env.find_module(self.module_name, self.pos)
- if "." in self.module_name:
- names = self.module_name.split(".")
- top_name = names[0]
- top_module_scope = env.context.find_submodule(top_name)
- module_scope = top_module_scope
- for name in names[1:]:
- submodule_scope = module_scope.find_submodule(name)
- module_scope.declare_module(name, submodule_scope, self.pos)
- if not self.as_name:
- env.add_imported_module(submodule_scope)
- module_scope = submodule_scope
- if self.as_name:
- env.declare_module(self.as_name, module_scope, self.pos)
- env.add_imported_module(module_scope)
- else:
- env.declare_module(top_name, top_module_scope, self.pos)
- env.add_imported_module(top_module_scope)
- else:
- name = self.as_name or self.module_name
- env.declare_module(name, module_scope, self.pos)
- env.add_imported_module(module_scope)
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class FromCImportStatNode(StatNode):
- # from ... cimport statement
- #
- # module_name string Qualified name of module
- # imported_names Parsing.ImportedName Names to be imported
-
- def analyse_declarations(self, env):
- module_scope = env.find_module(self.module_name, self.pos)
- env.add_imported_module(module_scope)
- for imp in self.imported_names:
- kind = imp.kind
- #entry = module_scope.find(imp.name, imp.pos)
- entry = module_scope.lookup(imp.name)
- if entry:
- if kind and not self.declaration_matches(entry, kind):
- entry.redeclared(pos)
- else:
- if kind == 'struct' or kind == 'union':
- entry = module_scope.declare_struct_or_union(imp.name,
- kind = kind, scope = None, typedef_flag = 0, pos = imp.pos)
- elif kind == 'class':
- entry = module_scope.declare_c_class(imp.name, pos = imp.pos,
- module_name = self.module_name)
- else:
- error(imp.pos, "Name '%s' not declared in module '%s'"
- % (imp.name, self.module_name))
- if entry:
- local_name = imp.as_name or imp.name
- env.add_imported_entry(local_name, entry, imp.pos)
-
- def declaration_matches(self, entry, kind):
- if not entry.is_type:
- return 0
- type = entry.type
- if kind == 'class':
- if not type.is_extension_type:
- return 0
- else:
- if not type.is_struct_or_union:
- return 0
- if kind <> type.kind:
- return 0
- return 1
-
- def analyse_expressions(self, env):
- pass
-
- def generate_execution_code(self, code):
- pass
-
-
-class FromImportStatNode(StatNode):
- # from ... import statement
- #
- # module ImportNode
- # items [(string, NameNode)]
- # #interned_items [(string, NameNode)]
- # item PyTempNode used internally
-
- def analyse_declarations(self, env):
- for _, target in self.items:
- target.analyse_target_declaration(env)
-
- def analyse_expressions(self, env):
- import ExprNodes
- self.module.analyse_expressions(env)
- self.item = ExprNodes.PyTempNode(self.pos, env)
- self.item.allocate_temp(env)
- #self.interned_items = []
- for name, target in self.items:
- #self.interned_items.append((env.intern(name), target))
- target.analyse_target_expression(env, None)
- self.module.release_temp(env)
- self.item.release_temp(env)
-
- def generate_execution_code(self, code):
- self.module.generate_evaluation_code(code)
- #for cname, target in self.interned_items:
- for name, target in self.items:
- cname = code.intern(name)
- code.putln(
- '%s = PyObject_GetAttr(%s, %s); if (!%s) %s' % (
- self.item.result(),
- self.module.py_result(),
- cname,
- self.item.result(),
- code.error_goto(self.pos)))
- target.generate_assignment_code(self.item, code)
- self.module.generate_disposal_code(code)
-
-#------------------------------------------------------------------------------------
-#
-# Runtime support code
-#
-#------------------------------------------------------------------------------------
-
-#utility_function_predeclarations = \
-#"""
-#typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
-#typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
-#"""
-
-utility_function_predeclarations = \
-"""
-typedef struct {PyObject **p; int i; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
-"""
-
-#get_name_predeclaration = \
-#"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
-
-#get_name_interned_predeclaration = \
-#"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
-
-#------------------------------------------------------------------------------------
-
-printing_utility_code = [
-"""
-static int __Pyx_PrintItem(PyObject *); /*proto*/
-static int __Pyx_PrintNewline(void); /*proto*/
-""",r"""
-static PyObject *__Pyx_GetStdout(void) {
- PyObject *f = PySys_GetObject("stdout");
- if (!f) {
- PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
- }
- return f;
-}
-
-static int __Pyx_PrintItem(PyObject *v) {
- PyObject *f;
-
- if (!(f = __Pyx_GetStdout()))
- return -1;
- if (PyFile_SoftSpace(f, 1)) {
- if (PyFile_WriteString(" ", f) < 0)
- return -1;
- }
- if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
- return -1;
- if (PyString_Check(v)) {
- char *s = PyString_AsString(v);
- Py_ssize_t len = PyString_Size(v);
- if (len > 0 &&
- isspace(Py_CHARMASK(s[len-1])) &&
- s[len-1] != ' ')
- PyFile_SoftSpace(f, 0);
- }
- return 0;
-}
-
-static int __Pyx_PrintNewline(void) {
- PyObject *f;
-
- if (!(f = __Pyx_GetStdout()))
- return -1;
- if (PyFile_WriteString("\n", f) < 0)
- return -1;
- PyFile_SoftSpace(f, 0);
- return 0;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-# The following function is based on do_raise() from ceval.c.
-
-raise_utility_code = [
-"""
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-""","""
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
- if (value == Py_None)
- value = NULL;
- if (tb == Py_None)
- tb = NULL;
- Py_XINCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- if (tb && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto raise_error;
- }
- #if PY_VERSION_HEX < 0x02050000
- if (!PyClass_Check(type))
- #else
- if (!PyType_Check(type))
- #endif
- {
- /* Raising an instance. The value should be a dummy. */
- if (value) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto raise_error;
- }
- /* Normalize to raise <class>, <instance> */
- value = type;
- #if PY_VERSION_HEX < 0x02050000
- if (PyInstance_Check(type)) {
- type = (PyObject*) ((PyInstanceObject*)type)->in_class;
- Py_INCREF(type);
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception must be an old-style class or instance");
- goto raise_error;
- }
- #else
- type = (PyObject*) type->ob_type;
- Py_INCREF(type);
- if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: exception class must be a subclass of BaseException");
- goto raise_error;
- }
- #endif
- }
- PyErr_Restore(type, value, tb);
- return;
-raise_error:
- Py_XDECREF(value);
- Py_XDECREF(type);
- Py_XDECREF(tb);
- return;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-#reraise_utility_code = [
-#"""
-#static void __Pyx_ReRaise(void); /*proto*/
-#""","""
-#static void __Pyx_ReRaise(void) {
-# PyThreadState *tstate = PyThreadState_Get();
-# PyObject *type = tstate->exc_type;
-# PyObject *value = tstate->exc_value;
-# PyObject *tb = tstate->exc_traceback;
-# Py_XINCREF(type);
-# Py_XINCREF(value);
-# Py_XINCREF(tb);
-# PyErr_Restore(type, value, tb);
-#}
-#"""]
-
-#------------------------------------------------------------------------------------
-
-arg_type_test_utility_code = [
-"""
-static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
-""","""
-static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
- if (!type) {
- PyErr_Format(PyExc_SystemError, "Missing type object");
- return 0;
- }
- if ((none_allowed && obj == Py_None) || PyObject_TypeCheck(obj, type))
- return 1;
- PyErr_Format(PyExc_TypeError,
- "Argument '%s' has incorrect type (expected %s, got %s)",
- name, type->tp_name, obj->ob_type->tp_name);
- return 0;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-#
-# __Pyx_GetStarArgs splits the args tuple and kwds dict into two parts
-# each, one part suitable for passing to PyArg_ParseTupleAndKeywords,
-# and the other containing any extra arguments. On success, replaces
-# the borrowed references *args and *kwds with references to a new
-# tuple and dict, and passes back new references in *args2 and *kwds2.
-# Does not touch any of its arguments on failure.
-#
-# Any of *kwds, args2 and kwds2 may be 0 (but not args or kwds). If
-# *kwds == 0, it is not changed. If kwds2 == 0 and *kwds != 0, a new
-# reference to the same dictionary is passed back in *kwds.
-#
-# If rqd_kwds is not 0, it is an array of booleans corresponding to the
-# names in kwd_list, indicating required keyword arguments. If any of
-# these are not present in kwds, an exception is raised.
-#
-
-get_starargs_utility_code = [
-"""
-static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], \
- Py_ssize_t nargs, PyObject **args2, PyObject **kwds2, char rqd_kwds[]); /*proto*/
-""","""
-static int __Pyx_GetStarArgs(
- PyObject **args,
- PyObject **kwds,
- char *kwd_list[],
- Py_ssize_t nargs,
- PyObject **args2,
- PyObject **kwds2,
- char rqd_kwds[])
-{
- PyObject *x = 0, *args1 = 0, *kwds1 = 0;
- int i;
- char **p;
-
- if (args2)
- *args2 = 0;
- if (kwds2)
- *kwds2 = 0;
-
- if (args2) {
- args1 = PyTuple_GetSlice(*args, 0, nargs);
- if (!args1)
- goto bad;
- *args2 = PyTuple_GetSlice(*args, nargs, PyTuple_GET_SIZE(*args));
- if (!*args2)
- goto bad;
- }
- else if (PyTuple_GET_SIZE(*args) > nargs) {
- int m = nargs;
- int n = PyTuple_GET_SIZE(*args);
- PyErr_Format(PyExc_TypeError,
- "function takes at most %d positional arguments (%d given)",
- m, n);
- goto bad;
- }
- else {
- args1 = *args;
- Py_INCREF(args1);
- }
-
- if (rqd_kwds && !*kwds)
- for (i = 0, p = kwd_list; *p; i++, p++)
- if (rqd_kwds[i])
- goto missing_kwarg;
-
- if (kwds2) {
- if (*kwds) {
- kwds1 = PyDict_New();
- if (!kwds1)
- goto bad;
- *kwds2 = PyDict_Copy(*kwds);
- if (!*kwds2)
- goto bad;
- for (i = 0, p = kwd_list; *p; i++, p++) {
- x = PyDict_GetItemString(*kwds, *p);
- if (x) {
- if (PyDict_SetItemString(kwds1, *p, x) < 0)
- goto bad;
- if (PyDict_DelItemString(*kwds2, *p) < 0)
- goto bad;
- }
- else if (rqd_kwds && rqd_kwds[i])
- goto missing_kwarg;
- }
- }
- else {
- *kwds2 = PyDict_New();
- if (!*kwds2)
- goto bad;
- }
- }
- else {
- kwds1 = *kwds;
- Py_XINCREF(kwds1);
- if (rqd_kwds && *kwds)
- for (i = 0, p = kwd_list; *p; i++, p++)
- if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p))
- goto missing_kwarg;
- }
-
- *args = args1;
- *kwds = kwds1;
- return 0;
-missing_kwarg:
- PyErr_Format(PyExc_TypeError,
- "required keyword argument '%s' is missing", *p);
-bad:
- Py_XDECREF(args1);
- Py_XDECREF(kwds1);
- if (args2) {
- Py_XDECREF(*args2);
- }
- if (kwds2) {
- Py_XDECREF(*kwds2);
- }
- return -1;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-unraisable_exception_utility_code = [
-"""
-static void __Pyx_WriteUnraisable(char *name); /*proto*/
-""","""
-static void __Pyx_WriteUnraisable(char *name) {
- PyObject *old_exc, *old_val, *old_tb;
- PyObject *ctx;
- PyGILState_STATE state = PyGILState_Ensure();
- PyErr_Fetch(&old_exc, &old_val, &old_tb);
- ctx = PyString_FromString(name);
- PyErr_Restore(old_exc, old_val, old_tb);
- if (!ctx)
- ctx = Py_None;
- PyErr_WriteUnraisable(ctx);
- PyGILState_Release(state);
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-traceback_utility_code = [
-"""
-static void __Pyx_AddTraceback(char *funcname); /*proto*/
-""","""
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-
-static void __Pyx_AddTraceback(char *funcname) {
- PyObject *py_srcfile = 0;
- PyObject *py_funcname = 0;
- PyObject *py_globals = 0;
- PyObject *empty_tuple = 0;
- PyObject *empty_string = 0;
- PyCodeObject *py_code = 0;
- PyFrameObject *py_frame = 0;
-
- py_srcfile = PyString_FromString(%(FILENAME)s);
- if (!py_srcfile) goto bad;
- py_funcname = PyString_FromString(funcname);
- if (!py_funcname) goto bad;
- py_globals = PyModule_GetDict(%(GLOBALS)s);
- if (!py_globals) goto bad;
- empty_tuple = PyTuple_New(0);
- if (!empty_tuple) goto bad;
- empty_string = PyString_FromString("");
- if (!empty_string) goto bad;
- py_code = PyCode_New(
- 0, /*int argcount,*/
- 0, /*int nlocals,*/
- 0, /*int stacksize,*/
- 0, /*int flags,*/
- empty_string, /*PyObject *code,*/
- empty_tuple, /*PyObject *consts,*/
- empty_tuple, /*PyObject *names,*/
- empty_tuple, /*PyObject *varnames,*/
- empty_tuple, /*PyObject *freevars,*/
- empty_tuple, /*PyObject *cellvars,*/
- py_srcfile, /*PyObject *filename,*/
- py_funcname, /*PyObject *name,*/
- %(LINENO)s, /*int firstlineno,*/
- empty_string /*PyObject *lnotab*/
- );
- if (!py_code) goto bad;
- py_frame = PyFrame_New(
- PyThreadState_Get(), /*PyThreadState *tstate,*/
- py_code, /*PyCodeObject *code,*/
- py_globals, /*PyObject *globals,*/
- 0 /*PyObject *locals*/
- );
- if (!py_frame) goto bad;
- py_frame->f_lineno = %(LINENO)s;
- PyTraceBack_Here(py_frame);
-bad:
- Py_XDECREF(py_srcfile);
- Py_XDECREF(py_funcname);
- Py_XDECREF(empty_tuple);
- Py_XDECREF(empty_string);
- Py_XDECREF(py_code);
- Py_XDECREF(py_frame);
-}
-""" % {
- 'FILENAME': Naming.filename_cname,
- 'LINENO': Naming.lineno_cname,
- 'GLOBALS': Naming.module_cname
-}]
-
-#------------------------------------------------------------------------------------
-
-set_vtable_utility_code = [
-"""
-static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
-""","""
-static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
- PyObject *pycobj = 0;
- int result;
-
- pycobj = PyCObject_FromVoidPtr(vtable, 0);
- if (!pycobj)
- goto bad;
- if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
- goto bad;
- result = 0;
- goto done;
-
-bad:
- result = -1;
-done:
- Py_XDECREF(pycobj);
- return result;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-get_vtable_utility_code = [
-"""
-static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
-""",r"""
-static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
- int result;
- PyObject *pycobj;
-
- pycobj = PyMapping_GetItemString(dict, "__pyx_vtable__");
- if (!pycobj)
- goto bad;
- *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
- if (!*(void **)vtabptr)
- goto bad;
- result = 0;
- goto done;
-
-bad:
- result = -1;
-done:
- Py_XDECREF(pycobj);
- return result;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-#init_intern_tab_utility_code = [
-#"""
-#static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
-#""","""
-#static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
-# while (t->p) {
-# *t->p = PyString_InternFromString(t->s);
-# if (!*t->p)
-# return -1;
-# ++t;
-# }
-# return 0;
-#}
-#"""]
-
-#init_intern_tab_utility_code = [
-#"""
-#static int __Pyx_InternStrings(PyObject **t[]); /*proto*/
-#""","""
-#static int __Pyx_InternStrings(PyObject **t[]) {
-# while (*t) {
-# PyString_InternInPlace(*t);
-# if (!**t)
-# return -1;
-# ++t;
-# }
-# return 0;
-#}
-#"""]
-
-#------------------------------------------------------------------------------------
-
-init_string_tab_utility_code = [
-"""
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
-""","""
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
- while (t->p) {
- *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
- if (!*t->p)
- return -1;
- if (t->i)
- PyString_InternInPlace(t->p);
- ++t;
- }
- return 0;
-}
-"""]
-
-#------------------------------------------------------------------------------------
-
-#get_exception_utility_code = [
-#"""
-#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-#""","""
-#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
-# PyThreadState *tstate = PyThreadState_Get();
-# PyObject *old_type, *old_value, *old_tb;
-# PyErr_Fetch(type, value, tb);
-# PyErr_NormalizeException(type, value, tb);
-# if (PyErr_Occurred())
-# goto bad;
-# if (!*tb) {
-# printf("no traceback\n");
-# *tb = Py_None;
-# Py_INCREF(*tb);
-# }
-##if 1
-# Py_INCREF(*type);
-# Py_INCREF(*value);
-# Py_INCREF(*tb);
-# old_type = tstate->exc_type;
-# old_value = tstate->exc_value;
-# old_tb = tstate->exc_traceback;
-# tstate->exc_type = *type;
-# tstate->exc_value = *value;
-# tstate->exc_traceback = *tb;
-# Py_XDECREF(old_type);
-# Py_XDECREF(old_value);
-# Py_XDECREF(old_tb);
-##endif
-# return 0;
-#bad:
-# Py_XDECREF(*type);
-# Py_XDECREF(*value);
-# Py_XDECREF(*tb);
-# return -1;
-#}
-#"""]
-
-#------------------------------------------------------------------------------------
-
-#get_exception_utility_code = [
-#"""
-#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-#""","""
-#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
-# PyErr_Fetch(type, value, tb);
-# PyErr_NormalizeException(type, value, tb);
-# if (PyErr_Occurred())
-# goto bad;
-# if (!*tb) {
-# *tb = Py_None;
-# Py_INCREF(*tb);
-# }
-# return 0;
-#bad:
-# Py_XDECREF(*type);
-# Py_XDECREF(*value);
-# Py_XDECREF(*tb);
-# return -1;
-#}
-#"""]
-
-#------------------------------------------------------------------------------------
-
-normalize_exception_utility_code = [
-"""
-static int __Pyx_NormalizeException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-""","""
-static int __Pyx_NormalizeException(PyObject **type, PyObject **value, PyObject **tb) {
- PyErr_NormalizeException(type, value, tb);
- if (PyErr_Occurred())
- goto bad;
- if (!*tb) {
- *tb = Py_None;
- Py_INCREF(*tb);
- }
- return 0;
-bad:
- Py_XDECREF(*type);
- Py_XDECREF(*value);
- Py_XDECREF(*tb);
- return -1;
-}
-"""]
-
-#------------------------------------------------------------------------------------
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py
deleted file mode 100644
index 0754fa24..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Pyrex - Compilation-wide options
-#
-
-intern_names = 1 # Intern global variable and attribute names
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py
deleted file mode 100644
index b7b9e4b5..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py
+++ /dev/null
@@ -1,2142 +0,0 @@
-#
-# Pyrex Parser
-#
-
-import os, re
-from string import join, replace
-from types import ListType, TupleType
-from Scanning import PyrexScanner
-import Nodes
-import ExprNodes
-from ModuleNode import ModuleNode
-from Errors import warning, error, InternalError
-
-
-class Ctx(object):
- # Parsing context
- level = 'other'
- visibility = 'private'
- extern_from = False
- cdef_flag = 0
- cplus_flag = 0
- typedef_flag = 0
- api = 0
- nogil = 0
-
- def __init__(self, **kwds):
- self.__dict__.update(kwds)
-
- def __call__(self, **kwds):
- ctx = Ctx()
- d = ctx.__dict__
- d.update(self.__dict__)
- d.update(kwds)
- return ctx
-
- def cplus_check(self, pos):
- #if self.visibility <> 'extern':
- # error(pos, "C++ declarations must be 'extern'")
- if self.cplus_flag and not self.extern_from:
- error(pos, "C++ declarations must be in an 'extern from' block")
-
-
-def p_ident(s, message = "Expected an identifier"):
- if s.sy == 'IDENT':
- name = s.systring
- s.next()
- return name
- else:
- s.error(message)
-
-def p_ident_list(s):
- names = []
- while s.sy == 'IDENT':
- names.append(s.systring)
- s.next()
- if s.sy <> ',':
- break
- s.next()
- return names
-
-#------------------------------------------
-#
-# Expressions
-#
-#------------------------------------------
-
-def p_binop_expr(s, ops, p_sub_expr):
- n1 = p_sub_expr(s)
- while s.sy in ops:
- op = s.sy
- pos = s.position()
- s.next()
- n2 = p_sub_expr(s)
- n1 = ExprNodes.binop_node(pos, op, n1, n2)
- return n1
-
-#test: and_test ('or' and_test)* | lambdef
-
-def p_simple_expr(s):
- return p_rassoc_binop_expr(s, ('or',), p_and_test)
-
-def p_rassoc_binop_expr(s, ops, p_subexpr):
- n1 = p_subexpr(s)
- if s.sy in ops:
- pos = s.position()
- op = s.sy
- s.next()
- n2 = p_rassoc_binop_expr(s, ops, p_subexpr)
- n1 = ExprNodes.binop_node(pos, op, n1, n2)
- return n1
-
-#and_test: not_test ('and' not_test)*
-
-def p_and_test(s):
- #return p_binop_expr(s, ('and',), p_not_test)
- return p_rassoc_binop_expr(s, ('and',), p_not_test)
-
-#not_test: 'not' not_test | comparison
-
-def p_not_test(s):
- if s.sy == 'not':
- pos = s.position()
- s.next()
- return ExprNodes.NotNode(pos, operand = p_not_test(s))
- else:
- return p_comparison(s)
-
-#comparison: expr (comp_op expr)*
-#comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
-
-def p_comparison(s):
- n1 = p_bit_expr(s)
- if s.sy in comparison_ops:
- pos = s.position()
- op = p_cmp_op(s)
- n2 = p_bit_expr(s)
- n1 = ExprNodes.PrimaryCmpNode(pos,
- operator = op, operand1 = n1, operand2 = n2)
- if s.sy in comparison_ops:
- n1.cascade = p_cascaded_cmp(s)
- return n1
-
-def p_cascaded_cmp(s):
- pos = s.position()
- op = p_cmp_op(s)
- n2 = p_bit_expr(s)
- result = ExprNodes.CascadedCmpNode(pos,
- operator = op, operand2 = n2)
- if s.sy in comparison_ops:
- result.cascade = p_cascaded_cmp(s)
- return result
-
-def p_cmp_op(s):
- if s.sy == 'not':
- s.next()
- s.expect('in')
- op = 'not_in'
- elif s.sy == 'is':
- s.next()
- if s.sy == 'not':
- s.next()
- op = 'is_not'
- else:
- op = 'is'
- else:
- op = s.sy
- s.next()
- if op == '<>':
- op = '!='
- return op
-
-comparison_ops = (
- '<', '>', '==', '>=', '<=', '<>', '!=',
- 'in', 'is', 'not'
-)
-
-#expr: xor_expr ('|' xor_expr)*
-
-def p_bit_expr(s):
- return p_binop_expr(s, ('|',), p_xor_expr)
-
-#xor_expr: and_expr ('^' and_expr)*
-
-def p_xor_expr(s):
- return p_binop_expr(s, ('^',), p_and_expr)
-
-#and_expr: shift_expr ('&' shift_expr)*
-
-def p_and_expr(s):
- return p_binop_expr(s, ('&',), p_shift_expr)
-
-#shift_expr: arith_expr (('<<'|'>>') arith_expr)*
-
-def p_shift_expr(s):
- return p_binop_expr(s, ('<<', '>>'), p_arith_expr)
-
-#arith_expr: term (('+'|'-') term)*
-
-def p_arith_expr(s):
- return p_binop_expr(s, ('+', '-'), p_term)
-
-#term: factor (('*'|'/'|'%') factor)*
-
-def p_term(s):
- return p_binop_expr(s, ('*', '/', '%'), p_factor)
-
-#factor: ('+'|'-'|'~'|'&'|typecast|sizeof) factor | power
-
-def p_factor(s):
- sy = s.sy
- if sy in ('+', '-', '~'):
- op = s.sy
- pos = s.position()
- s.next()
- return ExprNodes.unop_node(pos, op, p_factor(s))
- elif sy == '&':
- pos = s.position()
- s.next()
- arg = p_factor(s)
- return ExprNodes.AmpersandNode(pos, operand = arg)
- elif sy == "<":
- return p_typecast(s)
- elif sy == 'IDENT' and s.systring == "sizeof":
- return p_sizeof(s)
- else:
- return p_power(s)
-
-def p_typecast(s):
- # s.sy == "<"
- pos = s.position()
- s.next()
- base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, empty = 1)
- s.expect(">")
- operand = p_factor(s)
- return ExprNodes.TypecastNode(pos,
- base_type = base_type,
- declarator = declarator,
- operand = operand)
-
-def p_sizeof(s):
- # s.sy == ident "sizeof"
- pos = s.position()
- s.next()
- s.expect('(')
- if looking_at_type(s):
- base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, empty = 1)
- node = ExprNodes.SizeofTypeNode(pos,
- base_type = base_type, declarator = declarator)
- else:
- operand = p_simple_expr(s)
- node = ExprNodes.SizeofVarNode(pos, operand = operand)
- s.expect(')')
- return node
-
-#power: atom trailer* ('**' factor)*
-
-def p_power(s):
- n1 = p_primitive(s)
- if s.sy == '**':
- pos = s.position()
- s.next()
- n2 = p_factor(s)
- n1 = ExprNodes.binop_node(pos, '**', n1, n2)
- return n1
-
-def p_primitive(s):
- n = p_atom(s)
- while s.sy in ('(', '[', '.'):
- n = p_trailer(s, n)
- return n
-
-#trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
-
-def p_trailer(s, node1):
- pos = s.position()
- if s.sy == '(':
- return p_call(s, node1)
- elif s.sy == '[':
- return p_index(s, node1)
- else: # s.sy == '.'
- s.next()
- name = p_ident(s)
- return ExprNodes.AttributeNode(pos,
- obj = node1, attribute = name)
-
-# arglist: argument (',' argument)* [',']
-# argument: [test '='] test # Really [keyword '='] test
-
-def p_call(s, function):
- # s.sy == '('
- pos = s.position()
- s.next()
- positional_args = []
- keyword_args = []
- star_arg = None
- starstar_arg = None
- while s.sy not in ('*', '**', ')'):
- arg = p_simple_expr(s)
- if s.sy == '=':
- s.next()
- if not arg.is_name:
- s.error("Expected an identifier before '='",
- pos = arg.pos)
- keyword = ExprNodes.StringNode(arg.pos,
- value = arg.name)
- arg = p_simple_expr(s)
- keyword_args.append((keyword, arg))
- else:
- if keyword_args:
- s.error("Non-keyword arg following keyword arg",
- pos = arg.pos)
- positional_args.append(arg)
- if s.sy <> ',':
- break
- s.next()
- if s.sy == '*':
- s.next()
- star_arg = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- if s.sy == '**':
- s.next()
- starstar_arg = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- s.expect(')')
- if not (keyword_args or star_arg or starstar_arg):
- return ExprNodes.SimpleCallNode(pos,
- function = function,
- args = positional_args)
- else:
- arg_tuple = None
- keyword_dict = None
- if positional_args or not star_arg:
- arg_tuple = ExprNodes.TupleNode(pos,
- args = positional_args)
- if star_arg:
- star_arg_tuple = ExprNodes.AsTupleNode(pos, arg = star_arg)
- if arg_tuple:
- arg_tuple = ExprNodes.binop_node(pos,
- operator = '+', operand1 = arg_tuple,
- operand2 = star_arg_tuple)
- else:
- arg_tuple = star_arg_tuple
- if keyword_args:
- keyword_dict = ExprNodes.DictNode(pos,
- key_value_pairs = keyword_args)
- return ExprNodes.GeneralCallNode(pos,
- function = function,
- positional_args = arg_tuple,
- keyword_args = keyword_dict,
- starstar_arg = starstar_arg)
-
-#lambdef: 'lambda' [varargslist] ':' test
-
-#subscriptlist: subscript (',' subscript)* [',']
-
-def p_index(s, base):
- # s.sy == '['
- pos = s.position()
- s.next()
- subscripts = p_subscript_list(s)
- if len(subscripts) == 1 and len(subscripts[0]) == 2:
- start, stop = subscripts[0]
- result = ExprNodes.SliceIndexNode(pos,
- base = base, start = start, stop = stop)
- else:
- indexes = make_slice_nodes(pos, subscripts)
- if len(indexes) == 1:
- index = indexes[0]
- else:
- index = ExprNodes.TupleNode(pos, args = indexes)
- result = ExprNodes.IndexNode(pos,
- base = base, index = index)
- s.expect(']')
- return result
-
-def p_subscript_list(s):
- items = [p_subscript(s)]
- while s.sy == ',':
- s.next()
- if s.sy == ']':
- break
- items.append(p_subscript(s))
- return items
-
-#subscript: '.' '.' '.' | test | [test] ':' [test] [':' [test]]
-
-def p_subscript(s):
- # Parse a subscript and return a list of
- # 1, 2 or 3 ExprNodes, depending on how
- # many slice elements were encountered.
- pos = s.position()
- if s.sy == '.':
- expect_ellipsis(s)
- return [ExprNodes.EllipsisNode(pos)]
- else:
- start = p_slice_element(s, (':',))
- if s.sy <> ':':
- return [start]
- s.next()
- stop = p_slice_element(s, (':', ',', ']'))
- if s.sy <> ':':
- return [start, stop]
- s.next()
- step = p_slice_element(s, (':', ',', ']'))
- return [start, stop, step]
-
-def p_slice_element(s, follow_set):
- # Simple expression which may be missing iff
- # it is followed by something in follow_set.
- if s.sy not in follow_set:
- return p_simple_expr(s)
- else:
- return None
-
-def expect_ellipsis(s):
- s.expect('.')
- s.expect('.')
- s.expect('.')
-
-def make_slice_nodes(pos, subscripts):
- # Convert a list of subscripts as returned
- # by p_subscript_list into a list of ExprNodes,
- # creating SliceNodes for elements with 2 or
- # more components.
- result = []
- for subscript in subscripts:
- if len(subscript) == 1:
- result.append(subscript[0])
- else:
- result.append(make_slice_node(pos, *subscript))
- return result
-
-def make_slice_node(pos, start, stop = None, step = None):
- if not start:
- start = ExprNodes.NoneNode(pos)
- if not stop:
- stop = ExprNodes.NoneNode(pos)
- if not step:
- step = ExprNodes.NoneNode(pos)
- return ExprNodes.SliceNode(pos,
- start = start, stop = stop, step = step)
-
-#atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
-
-def p_atom(s):
- pos = s.position()
- sy = s.sy
- if sy == '(':
- s.next()
- if s.sy == ')':
- result = ExprNodes.TupleNode(pos, args = [])
- else:
- result = p_expr(s)
- s.expect(')')
- return result
- elif sy == '[':
- return p_list_maker(s)
- elif sy == '{':
- return p_dict_maker(s)
- elif sy == '`':
- return p_backquote_expr(s)
- elif sy == 'INT':
- value = s.systring
- s.next()
- return ExprNodes.IntNode(pos, value = value)
- elif sy == 'LONG':
- value = s.systring
- s.next()
- return ExprNodes.LongNode(pos, value = value)
- elif sy == 'FLOAT':
- value = s.systring
- s.next()
- return ExprNodes.FloatNode(pos, value = value)
- elif sy == 'IMAG':
- value = s.systring[:-1]
- s.next()
- return ExprNodes.ImagNode(pos, value = value)
- elif sy == 'STRING' or sy == 'BEGIN_STRING':
- kind, value = p_cat_string_literal(s)
- if kind == 'c':
- return ExprNodes.CharNode(pos, value = value)
- else:
- return ExprNodes.StringNode(pos, value = value)
- elif sy == 'IDENT':
- name = s.systring
- s.next()
- if name == "None":
- return ExprNodes.NoneNode(pos)
- elif name == "new" and s.sy == 'IDENT':
- return p_new_call(s)
- else:
- return p_name_atom(s, name)
- elif sy == 'NULL':
- s.next()
- return ExprNodes.NullNode(pos)
- else:
- s.error("Expected an identifier or literal")
-
-def p_new_call(s):
- node = p_primitive(s)
- if isinstance(node, ExprNodes.SimpleCallNode):
- node.is_new = 1
- else:
- error(s.position(), "'new' must be followed by a C++ constructor call")
- return node
-
-def p_name(s):
- if s.sy == 'IDENT':
- pos = s.position()
- name = s.systring
- s.next()
- return ExprNodes.NameNode(pos, name = name)
- else:
- s.error("Expected a variable name")
-
-def p_name_atom(s, name):
- pos = s.position()
- if not s.compile_time_expr:
- try:
- value = s.compile_time_env.lookup_here(name)
- except KeyError:
- pass
- else:
- rep = repr(value)
- if isinstance(value, int):
- return ExprNodes.IntNode(pos, value = rep)
- elif isinstance(value, long):
- return ExprNodes.LongNode(pos, value = rep)
- elif isinstance(value, float):
- return ExprNodes.FloatNode(pos, value = rep)
- elif isinstance(value, str):
- return ExprNodes.StringNode(pos, value = rep[1:-1])
- else:
- error(pos, "Invalid type for compile-time constant: %s"
- % value.__class__.__name__)
- return ExprNodes.NameNode(pos, name = name)
-
-def p_cat_string_literal(s):
- # A sequence of one or more adjacent string literals.
- # Returns (kind, value) where kind in ('', 'c', 'r')
- kind, value = p_string_literal(s)
- if kind <> 'c':
- strings = [value]
- while s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
- next_kind, next_value = p_string_literal(s)
- if next_kind == 'c':
- self.error(
- "Cannot concatenate char literal with another string or char literal")
- strings.append(next_value)
- value = ''.join(strings)
- return kind, value
-
-def p_opt_string_literal(s):
- if s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
- return p_string_literal(s)
- else:
- return None
-
-def p_string_literal(s):
- # A single string or char literal.
- # Returns (kind, value) where kind in ('', 'c', 'r')
- if s.sy == 'STRING':
- value = unquote(s.systring)
- s.next()
- return value
- # s.sy == 'BEGIN_STRING'
- pos = s.position()
- #is_raw = s.systring[:1].lower() == "r"
- kind = s.systring[:1].lower()
- if kind not in "cr":
- kind = ''
- chars = []
- while 1:
- s.next()
- sy = s.sy
- #print "p_string_literal: sy =", sy, repr(s.systring) ###
- if sy == 'CHARS':
- systr = s.systring
- if len(systr) == 1 and systr in "'\"\n":
- chars.append('\\')
- chars.append(systr)
- elif sy == 'ESCAPE':
- systr = s.systring
- if kind == 'r':
- if systr == '\\\n':
- chars.append(r'\\\n')
- elif systr == r'\"':
- chars.append(r'\\\"')
- elif systr == r'\\':
- chars.append(r'\\\\')
- else:
- chars.append('\\' + systr)
- else:
- c = systr[1]
- if c in "'\"\\abfnrtv01234567":
- chars.append(systr)
- elif c == 'x':
- chars.append('\\x0' + systr[2:])
- elif c == '\n':
- pass
- else:
- chars.append(r'\\' + systr[1:])
- elif sy == 'NEWLINE':
- chars.append(r'\n')
- elif sy == 'END_STRING':
- break
- elif sy == 'EOF':
- s.error("Unclosed string literal", pos = pos)
- else:
- s.error(
- "Unexpected token %r:%r in string literal" %
- (sy, s.systring))
- s.next()
- value = join(chars, '')
- #print "p_string_literal: value =", repr(value) ###
- return kind, value
-
-def unquote(s):
- is_raw = 0
- if s[:1].lower() == "r":
- is_raw = 1
- s = s[1:]
- q = s[:3]
- if q == '"""' or q == "'''":
- s = s[3:-3]
- else:
- s = s[1:-1]
- if is_raw:
- s = s.replace('\\', '\\\\')
- s = s.replace('\n', '\\\n')
- else:
- # Split into double quotes, newlines, escape sequences
- # and spans of regular chars
- l1 = re.split(r'((?:\\[0-7]{1,3})|(?:\\x[0-9A-Fa-f]{2})|(?:\\.)|(?:\\\n)|(?:\n)|")', s)
- print "unquote: l1 =", l1 ###
- l2 = []
- for item in l1:
- if item == '"' or item == '\n':
- l2.append('\\' + item)
- elif item == '\\\n':
- pass
- elif item[:1] == '\\':
- if len(item) == 2:
- if item[1] in '"\\abfnrtv':
- l2.append(item)
- else:
- l2.append(item[1])
- elif item[1:2] == 'x':
- l2.append('\\x0' + item[2:])
- else:
- # octal escape
- l2.append(item)
- else:
- l2.append(item)
- s = "".join(l2)
- return s
-
-def p_list_maker(s):
- # s.sy == '['
- pos = s.position()
- s.next()
- exprs = p_simple_expr_list(s)
- s.expect(']')
- return ExprNodes.ListNode(pos, args = exprs)
-
-#dictmaker: test ':' test (',' test ':' test)* [',']
-
-def p_dict_maker(s):
- # s.sy == '{'
- pos = s.position()
- s.next()
- items = []
- while s.sy <> '}':
- key = p_simple_expr(s)
- s.expect(':')
- value = p_simple_expr(s)
- items.append((key, value))
- if s.sy <> ',':
- break
- s.next()
- s.expect('}')
- return ExprNodes.DictNode(pos, key_value_pairs = items)
-
-def p_backquote_expr(s):
- # s.sy == '`'
- pos = s.position()
- s.next()
- arg = p_expr(s)
- s.expect('`')
- return ExprNodes.BackquoteNode(pos, arg = arg)
-
-#testlist: test (',' test)* [',']
-
-def p_simple_expr_list(s):
- exprs = []
- while s.sy not in expr_terminators:
- exprs.append(p_simple_expr(s))
- if s.sy <> ',':
- break
- s.next()
- return exprs
-
-def p_expr(s):
- pos = s.position()
- expr = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- exprs = [expr] + p_simple_expr_list(s)
- return ExprNodes.TupleNode(pos, args = exprs)
- else:
- return expr
-
-expr_terminators = (')', ']', '}', ':', '=', 'NEWLINE')
-
-#-------------------------------------------------------
-#
-# Statements
-#
-#-------------------------------------------------------
-
-def p_global_statement(s):
- # assume s.sy == 'global'
- pos = s.position()
- s.next()
- names = p_ident_list(s)
- return Nodes.GlobalNode(pos, names = names)
-
-inplace_operators = ('+=', '-=', '*=', '/=', '%=', '**=',
- '<<=', '>>=', '&=', '^=', '|=')
-
-def p_expression_or_assignment(s):
- pos = s.position()
- expr = p_expr(s)
- if s.sy in inplace_operators:
- return p_inplace_operation(s, expr)
- elif s.sy <> '=':
- if isinstance(expr, ExprNodes.StringNode):
- return Nodes.PassStatNode(expr.pos)
- else:
- return Nodes.ExprStatNode(expr.pos, expr = expr)
- else:
- expr_list = [expr]
- while s.sy == '=':
- s.next()
- expr_list.append(p_expr(s))
- expr_list_list = []
- flatten_parallel_assignments(expr_list, expr_list_list)
- nodes = []
- for expr_list in expr_list_list:
- lhs_list = expr_list[:-1]
- rhs = expr_list[-1]
- if len(lhs_list) == 1:
- node = Nodes.SingleAssignmentNode(rhs.pos,
- lhs = lhs_list[0], rhs = rhs)
- else:
- node = Nodes.CascadedAssignmentNode(rhs.pos,
- lhs_list = lhs_list, rhs = rhs)
- nodes.append(node)
- if len(nodes) == 1:
- return nodes[0]
- else:
- return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
-
-def p_inplace_operation(s, lhs):
- pos = s.position()
- op = s.sy
- s.next()
- rhs = p_expr(s)
- return Nodes.AugmentedAssignmentNode(pos, lhs = lhs, operator = op, rhs = rhs)
-
-def flatten_parallel_assignments(input, output):
- # The input is a list of expression nodes, representing
- # the LHSs and RHS of one (possibly cascaded) assignment
- # statement. If they are all sequence constructors with
- # the same number of arguments, rearranges them into a
- # list of equivalent assignments between the individual
- # elements. This transformation is applied recursively.
- size = find_parallel_assignment_size(input)
- if size >= 0:
- for i in range(size):
- new_exprs = [expr.args[i] for expr in input]
- flatten_parallel_assignments(new_exprs, output)
- else:
- output.append(input)
-
-def find_parallel_assignment_size(input):
- # The input is a list of expression nodes. If
- # they are all sequence constructors with the same number
- # of arguments, return that number, else return -1.
- # Produces an error message if they are all sequence
- # constructors but not all the same size.
- for expr in input:
- if not expr.is_sequence_constructor:
- return -1
- rhs = input[-1]
- rhs_size = len(rhs.args)
- for lhs in input[:-1]:
- lhs_size = len(lhs.args)
- if lhs_size <> rhs_size:
- error(lhs.pos, "Unpacking sequence of wrong size (expected %d, got %d)"
- % (lhs_size, rhs_size))
- return -1
- return rhs_size
-
-def p_print_statement(s):
- # s.sy == 'print'
- pos = s.position()
- s.next()
- if s.sy == '>>':
- s.error("'print >>' not yet implemented")
- args = []
- ewc = 0
- if s.sy not in ('NEWLINE', 'EOF'):
- args.append(p_simple_expr(s))
- while s.sy == ',':
- s.next()
- if s.sy in ('NEWLINE', 'EOF'):
- ewc = 1
- break
- args.append(p_simple_expr(s))
- return Nodes.PrintStatNode(pos,
- args = args, ends_with_comma = ewc)
-
-def p_del_statement(s):
- # s.sy == 'del'
- pos = s.position()
- s.next()
- args = p_simple_expr_list(s)
- return Nodes.DelStatNode(pos, args = args)
-
-def p_pass_statement(s, with_newline = 0):
- pos = s.position()
- s.expect('pass')
- if with_newline:
- s.expect_newline("Expected a newline")
- return Nodes.PassStatNode(pos)
-
-def p_break_statement(s):
- # s.sy == 'break'
- pos = s.position()
- s.next()
- return Nodes.BreakStatNode(pos)
-
-def p_continue_statement(s):
- # s.sy == 'continue'
- pos = s.position()
- s.next()
- return Nodes.ContinueStatNode(pos)
-
-def p_return_statement(s):
- # s.sy == 'return'
- pos = s.position()
- s.next()
- if s.sy not in statement_terminators:
- value = p_expr(s)
- else:
- value = None
- return Nodes.ReturnStatNode(pos, value = value)
-
-def p_raise_statement(s):
- # s.sy == 'raise'
- pos = s.position()
- s.next()
- exc_type = None
- exc_value = None
- exc_tb = None
- if s.sy not in statement_terminators:
- exc_type = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- exc_value = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- exc_tb = p_simple_expr(s)
- if exc_type or exc_value or exc_tb:
- return Nodes.RaiseStatNode(pos,
- exc_type = exc_type,
- exc_value = exc_value,
- exc_tb = exc_tb)
- else:
- return Nodes.ReraiseStatNode(pos)
-
-def p_import_statement(s):
- # s.sy in ('import', 'cimport')
- pos = s.position()
- kind = s.sy
- s.next()
- items = [p_dotted_name(s, as_allowed = 1)]
- while s.sy == ',':
- s.next()
- items.append(p_dotted_name(s, as_allowed = 1))
- stats = []
- for pos, target_name, dotted_name, as_name in items:
- if kind == 'cimport':
- stat = Nodes.CImportStatNode(pos,
- module_name = dotted_name,
- as_name = as_name)
- else:
- if as_name and "." in dotted_name:
- name_list = ExprNodes.ListNode(pos, args = [
- ExprNodes.StringNode(pos, value = "*")])
- else:
- name_list = None
- stat = Nodes.SingleAssignmentNode(pos,
- lhs = ExprNodes.NameNode(pos,
- name = as_name or target_name),
- rhs = ExprNodes.ImportNode(pos,
- module_name = ExprNodes.StringNode(pos,
- value = dotted_name),
- name_list = name_list))
- stats.append(stat)
- return Nodes.StatListNode(pos, stats = stats)
-
-def p_from_import_statement(s, ctx):
- # s.sy == 'from'
- pos = s.position()
- s.next()
- (dotted_name_pos, _, dotted_name, _) = \
- p_dotted_name(s, as_allowed = 0)
- if s.sy in ('import', 'cimport'):
- kind = s.sy
- s.next()
- else:
- s.error("Expected 'import' or 'cimport'")
- if kind == 'cimport' and ctx.level not in ('module', 'module_pxd'):
- s.error("cimport statement not allowed in this context")
- if s.sy == '*':
- s.error("'import *' not supported")
- is_cimport = kind == 'cimport'
- imported_names = [p_imported_name(s, is_cimport)]
- while s.sy == ',':
- s.next()
- imported_names.append(p_imported_name(s, is_cimport))
- if kind == 'cimport':
- for imp in imported_names:
- local_name = imp.as_name or imp.name
- s.add_type_name(local_name)
- return Nodes.FromCImportStatNode(pos,
- module_name = dotted_name,
- imported_names = imported_names)
- else:
- imported_name_strings = []
- items = []
- for imp in imported_names:
- imported_name_strings.append(
- ExprNodes.StringNode(imp.pos, value = imp.name))
- items.append(
- (imp.name,
- ExprNodes.NameNode(imp.pos,
- name = imp.as_name or imp.name)))
- import_list = ExprNodes.ListNode(
- imported_names[0].pos, args = imported_name_strings)
- return Nodes.FromImportStatNode(pos,
- module = ExprNodes.ImportNode(dotted_name_pos,
- module_name = ExprNodes.StringNode(dotted_name_pos,
- value = dotted_name),
- name_list = import_list),
- items = items)
-
-class ImportedName(object):
- # pos
- # name
- # as_name
- # kind 'class', 'struct', 'union', None
-
- def __init__(self, pos, name, as_name, kind):
- self.pos = pos
- self.name = name
- self.as_name = as_name
- self.kind = kind
-
-imported_name_kinds = ('class', 'struct', 'union')
-
-def p_imported_name(s, is_cimport):
- pos = s.position()
- kind = None
- if is_cimport and s.systring in imported_name_kinds:
- kind = s.systring
- s.next()
- name = p_ident(s)
- as_name = p_as_name(s)
- return ImportedName(pos, name, as_name, kind)
-
-def p_dotted_name(s, as_allowed):
- pos = s.position()
- target_name = p_ident(s)
- as_name = None
- names = [target_name]
- while s.sy == '.':
- s.next()
- names.append(p_ident(s))
- if as_allowed:
- as_name = p_as_name(s)
- return (pos, target_name, join(names, "."), as_name)
-
-def p_as_name(s):
- if s.sy == 'IDENT' and s.systring == 'as':
- s.next()
- return p_ident(s)
- else:
- return None
-
-def p_assert_statement(s):
- # s.sy == 'assert'
- pos = s.position()
- s.next()
- cond = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- value = p_simple_expr(s)
- else:
- value = None
- return Nodes.AssertStatNode(pos, cond = cond, value = value)
-
-statement_terminators = (';', 'NEWLINE', 'EOF')
-
-def p_if_statement(s):
- # s.sy == 'if'
- pos = s.position()
- s.next()
- if_clauses = [p_if_clause(s)]
- while s.sy == 'elif':
- s.next()
- if_clauses.append(p_if_clause(s))
- else_clause = p_else_clause(s)
- return Nodes.IfStatNode(pos,
- if_clauses = if_clauses, else_clause = else_clause)
-
-def p_if_clause(s):
- pos = s.position()
- test = p_simple_expr(s)
- body = p_suite(s)
- return Nodes.IfClauseNode(pos,
- condition = test, body = body)
-
-def p_else_clause(s):
- if s.sy == 'else':
- s.next()
- return p_suite(s)
- else:
- return None
-
-def p_while_statement(s):
- # s.sy == 'while'
- pos = s.position()
- s.next()
- test = p_simple_expr(s)
- body = p_suite(s)
- else_clause = p_else_clause(s)
- return Nodes.WhileStatNode(pos,
- condition = test, body = body,
- else_clause = else_clause)
-
-def p_for_statement(s):
- # s.sy == 'for'
- pos = s.position()
- s.next()
- expr = p_for_expr(s)
- if s.sy == 'in':
- return p_standard_for_statement(s, expr)
- elif s.sy in inequality_relations:
- return p_integer_for_statement(s, expr)
- elif s.sy == 'from':
- #warning(pos, "Old-style integer for-loop is deprecated, use 'for x < i < y' instead")
- return p_old_style_integer_for_statement(s, expr)
- else:
- s.error("Expected 'in' or an inequality relation")
-
-def p_standard_for_statement(s, target):
- # s.sy == 'in'
- s.next()
- iterator = p_for_iterator(s)
- body = p_suite(s)
- else_clause = p_else_clause(s)
- return Nodes.ForInStatNode(target.pos,
- target = target,
- iterator = iterator,
- body = body,
- else_clause = else_clause)
-
-def p_integer_for_statement(s, bound1):
- rel1 = s.sy
- s.next()
- name_pos = s.position()
- target = p_name(s)
- rel2_pos = s.position()
- rel2 = p_inequality_relation(s)
- bound2 = p_bit_expr(s)
- if rel1[0] <> rel2[0]:
- error(rel2_pos,
- "Relation directions in integer for-loop do not match")
- body = p_suite(s)
- else_clause = p_else_clause(s)
- return Nodes.IntegerForStatNode(bound1.pos,
- bound1 = bound1,
- relation1 = rel1,
- target = target,
- relation2 = rel2,
- bound2 = bound2,
- body = body,
- else_clause = else_clause)
-
-def p_old_style_integer_for_statement(s, target):
- # s.sy == 'for'
- s.next()
- bound1 = p_bit_expr(s)
- rel1 = p_inequality_relation(s)
- name2_pos = s.position()
- name2 = p_ident(s)
- rel2_pos = s.position()
- rel2 = p_inequality_relation(s)
- bound2 = p_bit_expr(s)
- if not target.is_name:
- error(target.pos,
- "Target of for-from statement must be a variable name")
- elif name2 <> target.name:
- error(name2_pos,
- "Variable name in for-from range does not match target")
- if rel1[0] <> rel2[0]:
- error(rel2_pos,
- "Relation directions in for-from do not match")
- body = p_suite(s)
- else_clause = p_else_clause(s)
- return Nodes.IntegerForStatNode(bound1.pos,
- bound1 = bound1,
- relation1 = rel1,
- target = target,
- relation2 = rel2,
- bound2 = bound2,
- body = body,
- else_clause = else_clause)
-
-def p_inequality_relation(s):
- if s.sy in inequality_relations:
- op = s.sy
- s.next()
- return op
- else:
- s.error("Expected one of '<', '<=', '>' '>='")
-
-inequality_relations = ('<', '<=', '>', '>=')
-
-def p_for_expr(s):
- # Target of standard for-statement or first bound of integer for-statement
- pos = s.position()
- expr = p_bit_expr(s)
- if s.sy == ',':
- s.next()
- exprs = [expr]
- while s.sy <> 'in':
- exprs.append(p_bit_expr(s))
- if s.sy <> ',':
- break
- s.next()
- return ExprNodes.TupleNode(pos, args = exprs)
- else:
- return expr
-
-def p_for_iterator(s):
- pos = s.position()
- expr = p_expr(s)
- return ExprNodes.IteratorNode(pos, sequence = expr)
-
-def p_try_statement(s):
- # s.sy == 'try'
- pos = s.position()
- s.next()
- body = p_suite(s)
- except_clauses = []
- else_clause = None
- if s.sy in ('except', 'else'):
- while s.sy == 'except':
- except_clauses.append(p_except_clause(s))
- if s.sy == 'else':
- s.next()
- else_clause = p_suite(s)
- return Nodes.TryExceptStatNode(pos,
- body = body, except_clauses = except_clauses,
- else_clause = else_clause)
- elif s.sy == 'finally':
- s.next()
- finally_clause = p_suite(s)
- return Nodes.TryFinallyStatNode(pos,
- body = body, finally_clause = finally_clause)
- else:
- s.error("Expected 'except' or 'finally'")
-
-def p_except_clause(s):
- # s.sy == 'except'
- pos = s.position()
- s.next()
- exc_type = None
- exc_value = None
- tb_value = None
- if s.sy <> ':':
- exc_type = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- exc_value = p_simple_expr(s)
- if s.sy == ',':
- s.next()
- tb_value = p_simple_expr(s)
- body = p_suite(s)
- return Nodes.ExceptClauseNode(pos,
- pattern = exc_type, exc_target = exc_value, tb_target = tb_value, body = body)
-
-def p_include_statement(s, ctx):
- pos = s.position()
- s.next() # 'include'
- _, include_file_name = p_string_literal(s)
- s.expect_newline("Syntax error in include statement")
- if s.compile_time_eval:
- include_file_path = s.context.find_include_file(include_file_name, pos)
- if include_file_path:
- s.included_files.append(include_file_name)
- f = open(include_file_path, "rU")
- s2 = PyrexScanner(f, include_file_path, parent_scanner = s)
- try:
- tree = p_statement_list(s2, ctx)
- finally:
- f.close()
- return tree
- else:
- return None
- else:
- return Nodes.PassStatNode(pos)
-
-def p_with_statement(s):
- pos = s.position()
- s.next() # 'with'
-# if s.sy == 'IDENT' and s.systring in ('gil', 'nogil'):
- if s.sy == 'IDENT' and s.systring == 'nogil':
- state = s.systring
- s.next()
- body = p_suite(s)
- return Nodes.GILStatNode(pos, state = state, body = body)
- else:
- s.error("Only 'with nogil' implemented")
-
-def p_simple_statement(s, ctx):
- if s.sy == 'global':
- node = p_global_statement(s)
- elif s.sy == 'print':
- node = p_print_statement(s)
- elif s.sy == 'del':
- node = p_del_statement(s)
- elif s.sy == 'break':
- node = p_break_statement(s)
- elif s.sy == 'continue':
- node = p_continue_statement(s)
- elif s.sy == 'return':
- node = p_return_statement(s)
- elif s.sy == 'raise':
- node = p_raise_statement(s)
- elif s.sy == 'cimport':
- if ctx.level not in ('module', 'module_pxd'):
- s.error("cimport statement not allowed in this context")
- node = p_import_statement(s)
- elif s.sy == 'import':
- node = p_import_statement(s)
- elif s.sy == 'from':
- node = p_from_import_statement(s, ctx)
- elif s.sy == 'assert':
- node = p_assert_statement(s)
- elif s.sy == 'pass':
- node = p_pass_statement(s)
- else:
- node = p_expression_or_assignment(s)
- return node
-
-def p_simple_statement_list(s, ctx):
- # Parse a series of simple statements on one line
- # separated by semicolons.
- stat = p_simple_statement(s, ctx)
- if s.sy == ';':
- stats = [stat]
- while s.sy == ';':
- s.next()
- if s.sy in ('NEWLINE', 'EOF'):
- break
- stats.append(p_simple_statement(s, ctx))
- stat = Nodes.StatListNode(stats[0].pos, stats = stats)
- s.expect_newline("Syntax error in simple statement list")
- return stat
-
-def p_compile_time_expr(s):
- old = s.compile_time_expr
- s.compile_time_expr = 1
- expr = p_expr(s)
- s.compile_time_expr = old
- return expr
-
-def p_DEF_statement(s):
- pos = s.position()
- denv = s.compile_time_env
- s.next() # 'DEF'
- name = p_ident(s)
- s.expect('=')
- expr = p_compile_time_expr(s)
- value = expr.compile_time_value(denv)
- #print "p_DEF_statement: %s = %r" % (name, value) ###
- denv.declare(name, value)
- s.expect_newline()
- return Nodes.PassStatNode(pos)
-
-def p_IF_statement(s, ctx):
- pos = s.position()
- saved_eval = s.compile_time_eval
- current_eval = saved_eval
- denv = s.compile_time_env
- result = None
- while 1:
- s.next() # 'IF' or 'ELIF'
- expr = p_compile_time_expr(s)
- s.compile_time_eval = current_eval and bool(expr.compile_time_value(denv))
- body = p_suite(s, ctx)
- if s.compile_time_eval:
- result = body
- current_eval = 0
- if s.sy <> 'ELIF':
- break
- if s.sy == 'ELSE':
- s.next()
- s.compile_time_eval = current_eval
- body = p_suite(s, ctx)
- if current_eval:
- result = body
- if not result:
- result = Nodes.PassStatNode(pos)
- s.compile_time_eval = saved_eval
- return result
-
-def p_statement(s, ctx):
- pos = s.position()
- cdef_flag = ctx.cdef_flag
- if s.sy == 'ctypedef':
- if ctx.level not in ('module', 'module_pxd'):
- s.error("ctypedef statement not allowed here")
- #if ctx.api:
- # error(s.pos, "'api' not allowed with 'ctypedef'")
- return p_ctypedef_statement(s, ctx)
- elif s.sy == 'DEF':
- return p_DEF_statement(s)
- elif s.sy == 'IF':
- return p_IF_statement(s, ctx)
- else:
- if s.sy == 'cdef':
- cdef_flag = 1
- s.next()
- if s.sy == '+':
- ctx = ctx(cplus_flag = 1)
- s.next()
- if cdef_flag:
- if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
- s.error('cdef statement not allowed here')
- return p_cdef_statement(s, ctx)
- else:
- if ctx.api:
- error(s.pos, "'api' not allowed with this statement")
- if s.sy == 'def':
- if ctx.level not in ('module', 'class', 'c_class', 'property'):
- s.error('def statement not allowed here')
- return p_def_statement(s)
- elif s.sy == 'class':
- if ctx.level <> 'module':
- s.error("class definition not allowed here")
- return p_class_statement(s)
- elif s.sy == 'include':
- #if ctx.level not in ('module', 'module_pxd'):
- # s.error("include statement not allowed here")
- return p_include_statement(s, ctx)
- elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property':
- return p_property_decl(s)
- elif s.sy == 'pass' and ctx.level <> 'property':
- return p_pass_statement(s, with_newline = 1)
- else:
- if ctx.level in ('c_class', 'c_class_pxd', 'property'):
- s.error("Executable statement not allowed here")
- if s.sy == 'if':
- return p_if_statement(s)
- elif s.sy == 'while':
- return p_while_statement(s)
- elif s.sy == 'for':
- return p_for_statement(s)
- elif s.sy == 'try':
- return p_try_statement(s)
- elif s.sy == 'with':
- return p_with_statement(s)
- else:
- return p_simple_statement_list(s, ctx)
-
-def p_statement_list(s, ctx):
- # Parse a series of statements separated by newlines.
- pos = s.position()
- stats = []
- while s.sy not in ('DEDENT', 'EOF'):
- stats.append(p_statement(s, ctx))
- if len(stats) == 1:
- return stats[0]
- else:
- return Nodes.StatListNode(pos, stats = stats)
-
-def p_suite(s, ctx = Ctx(), with_doc = 0, with_pseudo_doc = 0):
- pos = s.position()
- s.expect(':')
- doc = None
- stmts = []
- if s.sy == 'NEWLINE':
- s.next()
- s.expect_indent()
- if with_doc or with_pseudo_doc:
- doc = p_doc_string(s)
- body = p_statement_list(s, ctx)
- s.expect_dedent()
- else:
- if ctx.api:
- error(s.pos, "'api' not allowed with this statement")
- if ctx.level in ('module', 'class', 'function', 'other'):
- body = p_simple_statement_list(s, ctx)
- else:
- body = p_pass_statement(s)
- s.expect_newline("Syntax error in declarations")
- if with_doc:
- return doc, body
- else:
- return body
-
-def p_c_base_type(s, self_flag = 0):
- # If self_flag is true, this is the base type for the
- # self argument of a C method of an extension type.
- if s.sy == '(':
- return p_c_complex_base_type(s)
- else:
- return p_c_simple_base_type(s, self_flag)
-
-def p_calling_convention(s):
- if s.sy == 'IDENT' and s.systring in calling_convention_words:
- result = s.systring
- s.next()
- return result
- else:
- return ""
-
-calling_convention_words = ("__stdcall", "__cdecl", "__fastcall")
-
-def p_c_complex_base_type(s):
- # s.sy == '('
- pos = s.position()
- s.next()
- base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, empty = 1)
- s.expect(')')
- return Nodes.CComplexBaseTypeNode(pos,
- base_type = base_type, declarator = declarator)
-
-def p_c_simple_base_type(s, self_flag):
- #print "p_c_simple_base_type: self_flag =", self_flag
- is_basic = 0
- signed = 1
- longness = 0
- module_path = []
- pos = s.position()
- if looking_at_base_type(s):
- #print "p_c_simple_base_type: looking_at_base_type at", s.position()
- is_basic = 1
- signed, longness = p_sign_and_longness(s)
- if s.sy == 'IDENT' and s.systring in basic_c_type_names:
- name = s.systring
- s.next()
- else:
- name = 'int'
- elif s.looking_at_type_name() or looking_at_dotted_name(s):
- #print "p_c_simple_base_type: looking_at_type_name at", s.position()
- name = s.systring
- s.next()
- while s.sy == '.':
- module_path.append(name)
- s.next()
- name = p_ident(s)
- else:
- #print "p_c_simple_base_type: not looking at type at", s.position()
- name = None
- return Nodes.CSimpleBaseTypeNode(pos,
- name = name, module_path = module_path,
- is_basic_c_type = is_basic, signed = signed,
- longness = longness, is_self_arg = self_flag)
-
-def looking_at_type(s):
- return looking_at_base_type(s) or s.looking_at_type_name()
-
-def looking_at_base_type(s):
- #print "looking_at_base_type?", s.sy, s.systring, s.position()
- return s.sy == 'IDENT' and s.systring in base_type_start_words
-
-def looking_at_dotted_name(s):
- if s.sy == 'IDENT':
- name = s.systring
- s.next()
- result = s.sy == '.'
- s.put_back('IDENT', name)
- return result
- else:
- return 0
-
-basic_c_type_names = ("void", "char", "int", "float", "double") #,
- #"size_t", "Py_ssize_t")
-
-sign_and_longness_words = ("short", "long", "signed", "unsigned")
-
-base_type_start_words = \
- basic_c_type_names + sign_and_longness_words
-
-def p_sign_and_longness(s):
- signed = 1
- longness = 0
- while s.sy == 'IDENT' and s.systring in sign_and_longness_words:
- if s.systring == 'unsigned':
- signed = 0
- elif s.systring == 'signed':
- signed = 2
- elif s.systring == 'short':
- longness = -1
- elif s.systring == 'long':
- longness += 1
- s.next()
- return signed, longness
-
-def p_opt_cname(s):
- literal = p_opt_string_literal(s)
- if literal:
- _, cname = literal
- else:
- cname = None
- return cname
-
-def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, nonempty = 0,
- calling_convention_allowed = 0):
- # If empty is true, the declarator must be empty. If nonempty is true,
- # the declarator must be nonempty. Otherwise we don't care.
- # If cmethod_flag is true, then if this declarator declares
- # a function, it's a C method of an extension type.
- pos = s.position()
- if s.sy == '(':
- s.next()
- if s.sy == ')' or looking_at_type(s):
- base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None)
- result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
- else:
- result = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
- cmethod_flag = cmethod_flag, nonempty = nonempty,
- calling_convention_allowed = 1)
- s.expect(')')
- else:
- result = p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, nonempty)
- if not calling_convention_allowed and result.calling_convention and s.sy <> '(':
- error(s.position(), "%s on something that is not a function"
- % result.calling_convention)
- while s.sy in ('[', '('):
- pos = s.position()
- if s.sy == '[':
- result = p_c_array_declarator(s, result)
- else: # sy == '('
- s.next()
- result = p_c_func_declarator(s, pos, ctx, result, cmethod_flag)
- cmethod_flag = 0
- return result
-
-def p_c_array_declarator(s, base):
- pos = s.position()
- s.next() # '['
- if s.sy <> ']':
- dim = p_expr(s)
- else:
- dim = None
- s.expect(']')
- return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim)
-
-def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
- # Opening paren has already been skipped
- args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag,
- nonempty_declarators = 0)
- ellipsis = p_optional_ellipsis(s)
- s.expect(')')
- nogil = p_nogil(s)
- exc_val, exc_check = p_exception_value_clause(s)
- with_gil = p_with_gil(s)
- return Nodes.CFuncDeclaratorNode(pos,
- base = base, args = args, has_varargs = ellipsis,
- exception_value = exc_val, exception_check = exc_check,
- nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil)
-
-def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, nonempty):
- pos = s.position()
- calling_convention = p_calling_convention(s)
- if s.sy == '*':
- s.next()
- base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
- cmethod_flag = cmethod_flag, nonempty = nonempty)
- result = Nodes.CPtrDeclaratorNode(pos,
- base = base)
- elif s.sy == '**': # scanner returns this as a single token
- s.next()
- base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
- cmethod_flag = cmethod_flag, nonempty = nonempty)
- result = Nodes.CPtrDeclaratorNode(pos,
- base = Nodes.CPtrDeclaratorNode(pos,
- base = base))
- else:
- if s.sy == 'IDENT':
- name = s.systring
- if is_type:
- s.add_type_name(name)
- if empty:
- error(s.position(), "Declarator should be empty")
- s.next()
- cname = p_opt_cname(s)
- else:
- if nonempty:
- error(s.position(), "Empty declarator")
- name = ""
- cname = None
- result = Nodes.CNameDeclaratorNode(pos,
- name = name, cname = cname)
- result.calling_convention = calling_convention
- return result
-
-def p_nogil(s):
- if s.sy == 'IDENT' and s.systring == 'nogil':
- s.next()
- return 1
- else:
- return 0
-
-def p_with_gil(s):
- if s.sy == 'with':
- s.next()
- s.expect_keyword('gil')
- return 1
- else:
- return 0
-
-def p_exception_value_clause(s):
- exc_val = None
- exc_check = 0
- if s.sy == 'except':
- s.next()
- if s.sy == '*':
- exc_check = 1
- s.next()
- else:
- if s.sy == '?':
- exc_check = 1
- s.next()
- exc_val = p_simple_expr(s)
- return exc_val, exc_check
-
-c_arg_list_terminators = ('*', '**', '.', ')')
-
-def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0, nonempty_declarators = 0,
- kw_only = 0):
- # Comma-separated list of C argument declarations, possibly empty.
- # May have a trailing comma.
- args = []
- is_self_arg = cmethod_flag
- while s.sy not in c_arg_list_terminators:
- args.append(p_c_arg_decl(s, ctx, in_pyfunc, is_self_arg,
- nonempty = nonempty_declarators, kw_only = kw_only))
- if s.sy <> ',':
- break
- s.next()
- is_self_arg = 0
- return args
-
-def p_optional_ellipsis(s):
- if s.sy == '.':
- expect_ellipsis(s)
- return 1
- else:
- return 0
-
-def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0, kw_only = 0):
- pos = s.position()
- allow_none = None
- #not_none = 0
- default = None
- base_type = p_c_base_type(s, cmethod_flag)
- declarator = p_c_declarator(s, ctx, nonempty = nonempty)
- if s.sy in ('or', 'not'):
- or_not = s.sy
- s.next()
- if s.sy == 'IDENT' and s.systring == 'None':
- s.next()
- else:
- s.error("Expected 'None'")
- if not in_pyfunc:
- error(pos, "'%s None' only allowed in Python functions" % or_not)
- allow_none = or_not == 'or'
- if s.sy == '=':
- s.next()
- default = p_simple_expr(s)
- return Nodes.CArgDeclNode(pos,
- base_type = base_type,
- declarator = declarator,
- allow_none = allow_none,
- default = default,
- kw_only = kw_only)
-
-def p_api(s):
- if s.sy == 'IDENT' and s.systring == 'api':
- s.next()
- return 1
- else:
- return 0
-
-def p_cdef_statement(s, ctx):
- ctx = ctx(cdef_flag = 1)
- pos = s.position()
- ctx.visibility = p_visibility(s, ctx.visibility)
- ctx.api = ctx.api or p_api(s)
- if ctx.api:
- if ctx.visibility not in ('private', 'public'):
- error(pos, "Cannot combine 'api' with '%s'" % visibility)
- if ctx.visibility == 'extern' and s.sy == 'from':
- return p_cdef_extern_block(s, pos, ctx)
- if p_nogil(s):
- ctx.nogil = 1
- if s.sy == ':':
- return p_cdef_block(s, ctx)
- elif s.sy == 'class':
- if ctx.level not in ('module', 'module_pxd'):
- error(pos, "Extension type definition not allowed here")
- #if api:
- # error(pos, "'api' not allowed with extension class")
- return p_c_class_definition(s, pos, ctx)
- elif s.sy == 'IDENT' and s.systring in struct_union_or_enum:
- if ctx.level not in ('module', 'module_pxd'):
- error(pos, "C struct/union/enum definition not allowed here")
- #if ctx.visibility == 'public':
- # error(pos, "Public struct/union/enum definition not implemented")
- #if ctx.api:
- # error(pos, "'api' not allowed with '%s'" % s.systring)
- if s.systring == "enum":
- return p_c_enum_definition(s, pos, ctx)
- else:
- return p_c_struct_or_union_definition(s, pos, ctx)
- elif s.sy == 'pass':
- node = p_pass_statement(s)
- s.expect_newline('Expected a newline')
- return node
- else:
- return p_c_func_or_var_declaration(s, pos, ctx)
-
-def p_cdef_block(s, ctx):
- return p_suite(s, ctx(cdef_flag = 1))
-
-def p_cdef_extern_block(s, pos, ctx):
- include_file = None
- s.expect('from')
- if s.sy == '*':
- s.next()
- else:
- _, include_file = p_string_literal(s)
- ctx = ctx(cdef_flag = 1, visibility = 'extern', extern_from = True)
- if p_nogil(s):
- ctx.nogil = 1
- body = p_suite(s, ctx)
- return Nodes.CDefExternNode(pos,
- include_file = include_file,
- body = body)
-
-struct_union_or_enum = (
- "struct", "union", "enum"
-)
-
-def p_c_enum_definition(s, pos, ctx):
- # s.sy == ident 'enum'
- s.next()
- if s.sy == 'IDENT':
- name = s.systring
- s.next()
- s.add_type_name(name)
- cname = p_opt_cname(s)
- else:
- name = None
- cname = None
- items = None
- s.expect(':')
- items = []
- if s.sy <> 'NEWLINE':
- p_c_enum_line(s, items)
- else:
- s.next() # 'NEWLINE'
- s.expect_indent()
- while s.sy not in ('DEDENT', 'EOF'):
- p_c_enum_line(s, items)
- s.expect_dedent()
- return Nodes.CEnumDefNode(pos, name = name, cname = cname, items = items,
- typedef_flag = ctx.typedef_flag,
- visibility = ctx.visibility,
- in_pxd = ctx.level == 'module_pxd')
-
-def p_c_enum_line(s, items):
- if s.sy <> 'pass':
- p_c_enum_item(s, items)
- while s.sy == ',':
- s.next()
- if s.sy in ('NEWLINE', 'EOF'):
- break
- p_c_enum_item(s, items)
- else:
- s.next()
- s.expect_newline("Syntax error in enum item list")
-
-def p_c_enum_item(s, items):
- pos = s.position()
- name = p_ident(s)
- cname = p_opt_cname(s)
- value = None
- if s.sy == '=':
- s.next()
- value = p_simple_expr(s)
- items.append(Nodes.CEnumDefItemNode(pos,
- name = name, cname = cname, value = value))
-
-def p_c_struct_or_union_definition(s, pos, ctx):
- # s.sy == ident 'struct' or 'union'
- ctx.cplus_check(pos)
- kind = s.systring
- s.next()
- module_path, name = p_qualified_name(s)
- bases = []
- if s.sy == '(':
- s.next()
- while s.sy == 'IDENT':
- bases.append(p_qualified_name(s))
- if s.sy <> ',':
- break
- s.next()
- s.expect(')')
- if bases and not ctx.cplus_flag:
- error(s, "Only C++ struct may have bases")
- cname = p_opt_cname(s)
- s.add_type_name(name)
- attributes = None
- if s.sy == ':':
- s.next()
- s.expect('NEWLINE')
- s.expect_indent()
- attributes = []
- body_ctx = Ctx()
- while s.sy <> 'DEDENT':
- if s.sy <> 'pass':
- attributes.append(p_c_func_or_var_declaration(s,
- s.position(), body_ctx))
- else:
- s.next()
- s.expect_newline("Expected a newline")
- s.expect_dedent()
- else:
- s.expect_newline("Syntax error in struct or union definition")
- return Nodes.CStructOrUnionDefNode(pos,
- name = name, cname = cname, module_path = module_path,
- kind = kind, attributes = attributes,
- typedef_flag = ctx.typedef_flag,
- visibility = ctx.visibility,
- in_pxd = ctx.level == 'module_pxd',
- cplus_flag = ctx.cplus_flag,
- bases = bases)
-
-def p_visibility(s, prev_visibility):
- pos = s.position()
- visibility = prev_visibility
- if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'):
- visibility = s.systring
- if prev_visibility <> 'private' and visibility <> prev_visibility:
- s.error("Conflicting visibility options '%s' and '%s'"
- % (prev_visibility, visibility))
- s.next()
- return visibility
-
-def p_c_func_or_var_declaration(s, pos, ctx):
- cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
- base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, nonempty = 1)
- if s.sy == ':':
- if ctx.level not in ('module', 'c_class'):
- s.error("C function definition not allowed here")
- suite = p_suite(s, Ctx(level = 'function'), with_pseudo_doc = 1)
- result = Nodes.CFuncDefNode(pos,
- visibility = ctx.visibility,
- base_type = base_type,
- declarator = declarator,
- body = suite,
- api = ctx.api)
- else:
- #if api:
- # error(pos, "'api' not allowed with variable declaration")
- declarators = [declarator]
- while s.sy == ',':
- s.next()
- if s.sy == 'NEWLINE':
- break
- declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, nonempty = 1)
- declarators.append(declarator)
- s.expect_newline("Syntax error in C variable declaration")
- result = Nodes.CVarDefNode(pos,
- visibility = ctx.visibility,
- base_type = base_type,
- declarators = declarators,
- in_pxd = ctx.level == 'module_pxd',
- api = ctx.api)
- return result
-
-def p_ctypedef_statement(s, ctx):
- # s.sy == 'ctypedef'
- pos = s.position()
- s.next()
- visibility = p_visibility(s, ctx.visibility)
- api = p_api(s)
- ctx = ctx(typedef_flag = 1, visibility = visibility)
- if api:
- ctx.api = 1
- if s.sy == 'class':
- return p_c_class_definition(s, pos, ctx)
- elif s.sy == 'IDENT' and s.systring in ('struct', 'union', 'enum'):
- if s.systring == 'enum':
- return p_c_enum_definition(s, pos, ctx)
- else:
- return p_c_struct_or_union_definition(s, pos, ctx)
- else:
- base_type = p_c_base_type(s)
- declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1)
- s.expect_newline("Syntax error in ctypedef statement")
- return Nodes.CTypeDefNode(pos,
- base_type = base_type, declarator = declarator,
- visibility = ctx.visibility,
- in_pxd = ctx.level == 'module_pxd')
-
-def p_def_statement(s):
- # s.sy == 'def'
- pos = s.position()
- s.next()
- name = p_ident(s)
- #args = []
- s.expect('(');
- args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1)
- star_arg = None
- starstar_arg = None
- if s.sy == '*':
- s.next()
- if s.sy == 'IDENT':
- star_arg = p_py_arg_decl(s)
- if s.sy == ',':
- s.next()
- args.extend(p_c_arg_list(s, in_pyfunc = 1,
- nonempty_declarators = 1, kw_only = 1))
- elif s.sy <>')':
- s.error("Syntax error in Python function argument list")
- if s.sy == '**':
- s.next()
- starstar_arg = p_py_arg_decl(s)
- s.expect(')')
- if p_nogil(s):
- error(s.pos, "Python function cannot be declared nogil")
- doc, body = p_suite(s, Ctx(level = 'function'), with_doc = 1)
- return Nodes.DefNode(pos, name = name, args = args,
- star_arg = star_arg, starstar_arg = starstar_arg,
- doc = doc, body = body)
-
-def p_py_arg_decl(s):
- pos = s.position()
- name = p_ident(s)
- return Nodes.PyArgDeclNode(pos, name = name)
-
-def p_class_statement(s):
- # s.sy == 'class'
- pos = s.position()
- s.next()
- class_name = p_ident(s)
- if s.sy == '(':
- s.next()
- base_list = p_simple_expr_list(s)
- s.expect(')')
- else:
- base_list = []
- doc, body = p_suite(s, Ctx(level = 'class'), with_doc = 1)
- return Nodes.PyClassDefNode(pos,
- name = class_name,
- bases = ExprNodes.TupleNode(pos, args = base_list),
- doc = doc, body = body)
-
-def p_qualified_name(s):
- path = []
- name = p_ident(s)
- while s.sy == '.':
- s.next()
- path.append(name)
- name = p_ident(s)
- return path, name
-
-class CClassOptions:
-
- objstruct_cname = None
- typeobj_cname = None
- no_gc = 0
-
-
-def p_c_class_definition(s, pos, ctx):
- # s.sy == 'class'
- s.next()
- module_path, class_name = p_qualified_name(s)
- if module_path and s.sy == 'IDENT' and s.systring == 'as':
- s.next()
- as_name = p_ident(s)
- else:
- as_name = class_name
- s.add_type_name(as_name)
- options = CClassOptions()
- base_class_module = None
- base_class_name = None
- if s.sy == '(':
- s.next()
- base_class_path, base_class_name = p_qualified_name(s)
- if s.sy == ',':
- s.error("C class may only have one base class")
- s.expect(')')
- base_class_module = ".".join(base_class_path)
- if s.sy == '[':
- p_c_class_options(s, ctx, options)
- if s.sy == ':':
- if ctx.level == 'module_pxd':
- body_level = 'c_class_pxd'
- else:
- body_level = 'c_class'
- doc, body = p_suite(s, Ctx(level = body_level), with_doc = 1)
- else:
- s.expect_newline("Syntax error in C class definition")
- doc = None
- body = None
- if ctx.visibility == 'extern':
- if not module_path:
- error(pos, "Module name required for 'extern' C class")
- if options.typeobj_cname:
- error(pos, "Type object name specification not allowed for 'extern' C class")
- elif ctx.visibility == 'public':
- if not options.objstruct_cname:
- error(pos, "Object struct name specification required for 'public' C class")
- if not options.typeobj_cname:
- error(pos, "Type object name specification required for 'public' C class")
- else:
- if ctx.api:
- error(pos, "Only 'public' C class can be declared 'api'")
- return Nodes.CClassDefNode(pos,
- visibility = ctx.visibility,
- typedef_flag = ctx.typedef_flag,
- api = ctx.api,
- module_name = ".".join(module_path),
- class_name = class_name,
- as_name = as_name,
- base_class_module = base_class_module,
- base_class_name = base_class_name,
- options = options,
- in_pxd = ctx.level == 'module_pxd',
- doc = doc,
- body = body)
-
-def p_c_class_options(s, ctx, options):
- s.expect('[')
- while 1:
- if s.sy <> 'IDENT':
- break
- if s.systring == 'object':
- if ctx.visibility not in ('public', 'extern'):
- error(s.position(), "Object name option only allowed for 'public' or 'extern' C class")
- s.next()
- options.objstruct_cname = p_ident(s)
- elif s.systring == 'type':
- if ctx.visibility not in ('public', 'extern'):
- error(s.position(), "Type name option only allowed for 'public' or 'extern' C class")
- s.next()
- options.typeobj_cname = p_ident(s)
- elif s.systring == 'nogc':
- s.next()
- options.no_gc = 1
- else:
- s.error("Unrecognised C class option '%s'" % s.systring)
- if s.sy <> ',':
- break
- s.next()
- s.expect(']', "Expected a C class option")
-
-def p_property_decl(s):
- pos = s.position()
- s.next() # 'property'
- name = p_ident(s)
- doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1)
- return Nodes.PropertyNode(pos, name = name, doc = doc, body = body)
-
-def p_doc_string(s):
- if s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
- _, result = p_cat_string_literal(s)
- if s.sy <> 'EOF':
- s.expect_newline("Syntax error in doc string")
- return result
- else:
- return None
-
-def p_module(s, pxd):
- s.add_type_name("object")
- pos = s.position()
- doc = p_doc_string(s)
- if pxd:
- level = 'module_pxd'
- else:
- level = 'module'
- body = p_statement_list(s, Ctx(level = level))
- if s.sy <> 'EOF':
- s.error("Syntax error in statement [%s,%s]" % (
- repr(s.sy), repr(s.systring)))
- return ModuleNode(pos, doc = doc, body = body)
-
-#----------------------------------------------
-#
-# Debugging
-#
-#----------------------------------------------
-
-def print_parse_tree(f, node, level, key = None):
- ind = " " * level
- if node:
- f.write(ind)
- if key:
- f.write("%s: " % key)
- t = type(node)
- if t == TupleType:
- f.write("(%s @ %s\n" % (node[0], node[1]))
- for i in xrange(2, len(node)):
- print_parse_tree(f, node[i], level+1)
- f.write("%s)\n" % ind)
- return
- elif isinstance(node, Node):
- try:
- tag = node.tag
- except AttributeError:
- tag = node.__class__.__name__
- f.write("%s @ %s\n" % (tag, node.pos))
- for name, value in node.__dict__.items():
- if name <> 'tag' and name <> 'pos':
- print_parse_tree(f, value, level+1, name)
- return
- elif t == ListType:
- f.write("[\n")
- for i in xrange(len(node)):
- print_parse_tree(f, node[i], level+1)
- f.write("%s]\n" % ind)
- return
- f.write("%s%s\n" % (ind, node))
-
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py
deleted file mode 100644
index 7d4f244a..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py
+++ /dev/null
@@ -1,974 +0,0 @@
-#
-# Pyrex - Types
-#
-
-import string
-import Naming
-
-class BaseType:
- #
- # Base class for all Pyrex types including pseudo-types.
-
- def cast_code(self, expr_code):
- return "((%s)%s)" % (self.declaration_code(""), expr_code)
-
- def base_declaration_code(self, base_code, entity_code):
- if entity_code:
- return "%s %s" % (base_code, entity_code)
- else:
- return base_code
-
-
-class PyrexType(BaseType):
- #
- # Base class for all non-pseudo Pyrex types.
- #
- # is_pyobject boolean Is a Python object type
- # is_extension_type boolean Is a Python extension type
- # is_numeric boolean Is a C numeric type
- # is_int boolean Is a C integer type
- # is_float boolean Is a C floating point type
- # is_void boolean Is the C void type
- # is_array boolean Is a C array type
- # is_ptr boolean Is a C pointer type
- # is_null_ptr boolean Is the type of NULL
- # is_cfunction boolean Is a C function type
- # is_struct_or_union boolean Is a C struct or union type
- # is_enum boolean Is a C enum type
- # is_typedef boolean Is a typedef type
- # is_string boolean Is a C char * type
- # is_returncode boolean Is used only to signal exceptions
- # is_sequence boolean Is a sequence type
- # is_builtin boolean Is a built-in Python type
- # is_error boolean Is the dummy error type
- # has_attributes boolean Has C dot-selectable attributes
- # default_value string Initial value
- # parsetuple_format string Format char for PyArg_ParseTuple
- # pymemberdef_typecode string Type code for PyMemberDef struct
- #
- # declaration_code(entity_code,
- # for_display = 0, dll_linkage = None, pyrex = 0)
- # Returns a code fragment for the declaration of an entity
- # of this type, given a code fragment for the entity.
- # * If for_display, this is for reading by a human in an error
- # message; otherwise it must be valid C code.
- # * If dll_linkage is not None, it must be 'DL_EXPORT' or
- # 'DL_IMPORT', and will be added to the base type part of
- # the declaration.
- # * If pyrex = 1, this is for use in a 'cdef extern'
- # statement of a Pyrex include file.
- #
- # assignable_from(src_type)
- # Tests whether a variable of this type can be
- # assigned a value of type src_type.
- #
- # same_as(other_type)
- # Tests whether this type represents the same type
- # as other_type.
- #
- # as_argument_type():
- # Coerces array type into pointer type for use as
- # a formal argument type.
- #
-
- is_pyobject = 0
- is_extension_type = 0
- is_numeric = 0
- is_int = 0
- is_float = 0
- is_void = 0
- is_array = 0
- is_ptr = 0
- is_null_ptr = 0
- is_cfunction = 0
- is_struct_or_union = 0
- is_enum = 0
- is_typedef = 0
- is_string = 0
- is_returncode = 0
- is_sequence = 0
- is_builtin = 0
- is_error = 0
- has_attributes = 0
- default_value = ""
- parsetuple_format = ""
- pymemberdef_typecode = None
-
- def resolve(self):
- # If a typedef, returns the base type.
- return self
-
- def literal_code(self, value):
- # Returns a C code fragment representing a literal
- # value of this type.
- return str(value)
-
- def __str__(self):
- return string.strip(self.declaration_code("", for_display = 1))
-
- def same_as(self, other_type, **kwds):
- return self.same_as_resolved_type(other_type.resolve(), **kwds)
-
- def same_as_resolved_type(self, other_type):
- return self is other_type or other_type is error_type
-
- def subtype_of(self, other_type):
- return self.subtype_of_resolved_type(other_type.resolve())
-
- def subtype_of_resolved_type(self, other_type):
- return self.same_as(other_type)
-
- def assignable_from(self, src_type):
- return self.assignable_from_resolved_type(src_type.resolve())
-
- def assignable_from_resolved_type(self, src_type):
- return self.same_as(src_type)
-
- def as_argument_type(self):
- return self
-
- def is_complete(self):
- # A type is incomplete if it is an unsized array,
- # a struct whose attributes are not defined, etc.
- return 1
-
-
-class TypeWrapper(BaseType):
- # Base class for pseudo-types that delegate most
- # attribute lookups to another type.
- #
- # delegate_type PyrexType
-
- def __init__(self, base_type):
- self.delegate_type = base_type
-
- def __getattr__(self, name):
- return getattr(self.delegate_type, name)
-
- def define(self, base_type):
- self.delegate_type = base_type
-
- def resolve(self):
- return self.delegate_type.resolve()
-
-
-class CTypedefType(TypeWrapper):
- #
- # Pseudo-type defined with a ctypedef statement in a
- # 'cdef extern from' block. Delegates most attribute
- # lookups to the base type. ANYTHING NOT DEFINED
- # HERE IS DELEGATED!
- #
- # qualified_name string
- # typedef_cname string
- # typedef_base_type PyrexType
-
- is_typedef = 1
-
- def __init__(self, cname, base_type):
- TypeWrapper.__init__(self, base_type)
- self.typedef_cname = cname
- self.typedef_base_type = base_type
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- name = self.declaration_name(for_display, pyrex)
- return self.base_declaration_code(name, entity_code)
-
- def declaration_name(self, for_display = 0, pyrex = 0):
- if pyrex or for_display:
- return self.qualified_name
- else:
- return self.typedef_cname
-
- def as_argument_type(self):
- return self
-
- def __repr__(self):
- return "<CTypedefType %s>" % self.typedef_cname
-
- def __str__(self):
- return self.declaration_name(for_display = 1)
-
-
-class PyObjectType(PyrexType):
- #
- # Base class for all Python object types (reference-counted).
- #
-
- is_pyobject = 1
- default_value = "0"
- parsetuple_format = "O"
- pymemberdef_typecode = "T_OBJECT"
-
- def __str__(self):
- return "Python object"
-
- def __repr__(self):
- return "<PyObjectType>"
-
- def assignable_from(self, src_type):
- return 1 # Conversion will be attempted
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- if pyrex or for_display:
- return self.base_declaration_code("object", entity_code)
- else:
- return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
-
-
-class PyExtensionType(PyObjectType):
- #
- # A Python extension type.
- #
- # name string
- # scope CClassScope Attribute namespace
- # visibility string
- # typedef_flag boolean
- # base_type PyExtensionType or None
- # module_name string or None Qualified name of defining module
- # objstruct_cname string Name of PyObject struct
- # typeobj_cname string or None C code fragment referring to type object
- # typeptr_cname string or None Name of pointer to external type object
- # vtabslot_cname string Name of C method table member
- # vtabstruct_cname string Name of C method table struct
- # vtabptr_cname string Name of pointer to C method table
- # vtable_cname string Name of C method table definition
-
- is_extension_type = 1
- has_attributes = 1
-
- def __init__(self, name, typedef_flag, base_type):
- self.name = name
- self.scope = None
- self.typedef_flag = typedef_flag
- self.base_type = base_type
- self.module_name = None
- self.objstruct_cname = None
- self.typeobj_cname = None
- self.typeptr_cname = None
- self.vtabslot_cname = None
- self.vtabstruct_cname = None
- self.vtabptr_cname = None
- self.vtable_cname = None
- if base_type and base_type.is_sequence:
- self.is_sequence = 1
-
- def set_scope(self, scope):
- self.scope = scope
- if scope:
- scope.parent_type = self
-
- def subtype_of_resolved_type(self, other_type):
- if other_type.is_extension_type:
- return self is other_type or (
- self.base_type and self.base_type.subtype_of(other_type))
- else:
- return other_type is py_object_type
-
- def typeobj_is_available(self):
- # Do we have a pointer to the type object?
- return self.typeptr_cname
-
- def typeobj_is_imported(self):
- # If we don't know the C name of the type object but we do
- # know which module it's defined in, it will be imported.
- return self.typeobj_cname is None and self.module_name is not None
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- if pyrex or for_display:
- return self.base_declaration_code(self.name, entity_code)
- else:
- if self.typedef_flag:
- base_format = "%s"
- else:
- base_format = "struct %s"
- base = public_decl(base_format % self.objstruct_cname, dll_linkage)
- return "%s *%s" % (base, entity_code)
-
- def attributes_known(self):
- return self.scope is not None
-
- def is_defined(self):
- scope = self.scope
- return scope and (scope.defined or scope.implemented)
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return "<PyExtensionType %s%s>" % (self.scope.class_name,
- ("", " typedef")[self.typedef_flag])
-
-
-class CType(PyrexType):
- #
- # Base class for all C types (non-reference-counted).
- #
- # to_py_function string C function for converting to Python object
- # from_py_function string C function for constructing from Python object
- #
-
- to_py_function = None
- from_py_function = None
-
-
-class CVoidType(CType):
- is_void = 1
-
- def __repr__(self):
- return "<CVoidType>"
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- base = public_decl("void", dll_linkage)
- return self.base_declaration_code(base, entity_code)
-
- def is_complete(self):
- return 0
-
-
-class CNumericType(CType):
- #
- # Base class for all C numeric types.
- #
- # rank integer Relative size
- # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
- # name string or None to construct from sign and rank
- #
-
- is_numeric = 1
- default_value = "0"
-
- parsetuple_formats = ( # rank -> format
- "BHIk?K???", # unsigned
- "bhil?Lfd?", # assumed signed
- "bhil?Lfd?", # explicitly signed
- )
-
- sign_words = ("unsigned ", "", "signed ")
-
- def __init__(self, rank, signed, name, pymemberdef_typecode = None):
- self.rank = rank
- self.signed = signed
- self.name = name
- ptf = self.parsetuple_formats[signed][rank]
- if ptf == '?':
- ptf = None
- self.parsetuple_format = ptf
- self.pymemberdef_typecode = pymemberdef_typecode
-
- def sign_and_name(self):
- return self.name
-
- def __repr__(self):
- return "<CNumericType %s>" % self.sign_and_name()
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- base = public_decl(self.sign_and_name(), dll_linkage)
- return self.base_declaration_code(base, entity_code)
-
-
-class CIntType(CNumericType):
-
- is_int = 1
- typedef_flag = 0
- to_py_function = "PyInt_FromLong"
- from_py_function = "PyInt_AsLong"
-
- def __init__(self, rank, signed, name, pymemberdef_typecode = None, is_returncode = 0):
- CNumericType.__init__(self, rank, signed, name, pymemberdef_typecode)
- self.is_returncode = is_returncode
-
- def assignable_from_resolved_type(self, src_type):
- return src_type.is_int or src_type.is_enum or src_type is error_type
-
-
-class CAnonEnumType(CIntType):
-
- is_enum = 1
-
-
-class CUIntType(CIntType):
-
- to_py_function = "PyLong_FromUnsignedLong"
- from_py_function = "PyInt_AsUnsignedLongMask"
-
-
-class CULongType(CIntType):
-
- to_py_function = "PyLong_FromUnsignedLong"
- from_py_function = "PyInt_AsUnsignedLongMask"
-
-
-class CLongLongType(CIntType):
-
- to_py_function = "PyLong_FromLongLong"
- from_py_function = "PyInt_AsUnsignedLongLongMask"
-
-
-class CULongLongType(CIntType):
-
- to_py_function = "PyLong_FromUnsignedLongLong"
- from_py_function = "PyInt_AsUnsignedLongLongMask"
-
-
-class CPySSizeTType(CIntType):
-
- to_py_function = "PyInt_FromSsize_t"
- from_py_function = "PyInt_AsSsize_t"
-
-
-class CFloatType(CNumericType):
-
- is_float = 1
- to_py_function = "PyFloat_FromDouble"
- from_py_function = "PyFloat_AsDouble"
-
- def __init__(self, rank, name, pymemberdef_typecode = None):
- CNumericType.__init__(self, rank, 1, name, pymemberdef_typecode)
-
- def assignable_from_resolved_type(self, src_type):
- return src_type.is_numeric or src_type is error_type
-
-
-class CArrayType(CType):
- # base_type CType Element type
- # size integer or None Number of elements
-
- is_array = 1
-
- def __init__(self, base_type, size):
- self.base_type = base_type
- self.size = size
- if base_type is c_char_type:
- self.is_string = 1
-
- def __repr__(self):
- return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
-
- def same_as_resolved_type(self, other_type):
- return ((other_type.is_array and
- self.base_type.same_as(other_type.base_type))
- or other_type is error_type)
-
- def assignable_from_resolved_type(self, src_type):
- # Can't assign to a variable of an array type
- return 0
-
- def element_ptr_type(self):
- return c_ptr_type(self.base_type)
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- if self.size is not None:
- dimension_code = self.size
- else:
- dimension_code = ""
- if entity_code.startswith("*"):
- entity_code = "(%s)" % entity_code
- return self.base_type.declaration_code(
- "%s[%s]" % (entity_code, dimension_code),
- for_display, dll_linkage, pyrex)
-
- def as_argument_type(self):
- return c_ptr_type(self.base_type)
-
- def is_complete(self):
- return self.size is not None
-
-
-class CPtrType(CType):
- # base_type CType Referenced type
-
- is_ptr = 1
- default_value = "0"
-
- def __init__(self, base_type):
- self.base_type = base_type
-
- def __repr__(self):
- return "<CPtrType %s>" % repr(self.base_type)
-
- def same_as_resolved_type(self, other_type):
- return ((other_type.is_ptr and
- self.base_type.same_as(other_type.base_type))
- or other_type is error_type)
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- #print "CPtrType.declaration_code: pointer to", self.base_type ###
- return self.base_type.declaration_code(
- "*%s" % entity_code,
- for_display, dll_linkage, pyrex)
-
- def assignable_from_resolved_type(self, other_type):
- if other_type is error_type:
- return 1
- if other_type.is_null_ptr:
- return 1
- if self.base_type.is_cfunction:
- if other_type.is_ptr:
- other_type = other_type.base_type.resolve()
- if other_type.is_cfunction:
- return self.base_type.pointer_assignable_from_resolved_type(other_type)
- else:
- return 0
- if other_type.is_array or other_type.is_ptr:
- return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
- return 0
-
-
-class CNullPtrType(CPtrType):
-
- is_null_ptr = 1
-
-
-class CFuncType(CType):
- # return_type CType
- # args [CFuncTypeArg]
- # has_varargs boolean
- # exception_value string
- # exception_check boolean True if PyErr_Occurred check needed
- # calling_convention string Function calling convention
- # nogil boolean Can be called without gil
- # with_gil boolean Acquire gil around function body
-
- is_cfunction = 1
- is_overloaded = 0
-
- def __init__(self, return_type, args, has_varargs = 0,
- exception_value = None, exception_check = 0, calling_convention = "",
- nogil = 0, with_gil = 0):
- self.return_type = return_type
- self.args = args
- self.has_varargs = has_varargs
- self.exception_value = exception_value
- self.exception_check = exception_check
- self.calling_convention = calling_convention
- self.nogil = nogil
- self.with_gil = with_gil
-
- def __repr__(self):
- arg_reprs = map(repr, self.args)
- if self.has_varargs:
- arg_reprs.append("...")
- return "<CFuncType %s %s[%s]>" % (
- repr(self.return_type),
- self.calling_convention_prefix(),
- string.join(arg_reprs, ","))
-
- def callable_with(self, actual_arg_types):
- formal_arg_types = self.args
- nf = len(formal_arg_types)
- na = len(actual_arg_types)
- if not (nf == na or self.has_varargs and nf >= na):
- return False
- for formal_type, actual_type in zip(formal_arg_types, actual_arg_types):
- if not formal_type.assignable_from(actual_type):
- return False
- return True
-
- def calling_convention_prefix(self):
- cc = self.calling_convention
- if cc:
- return cc + " "
- else:
- return ""
-
- def same_c_signature_as(self, other_type, as_cmethod = 0):
- return self.same_c_signature_as_resolved_type(
- other_type.resolve(), as_cmethod)
-
- def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
- #print "CFuncType.same_c_signature_as_resolved_type:", \
- # self, other_type, "as_cmethod =", as_cmethod ###
- if other_type is error_type:
- return 1
- if not other_type.is_cfunction:
- return 0
- nargs = len(self.args)
- if nargs <> len(other_type.args):
- return 0
- # When comparing C method signatures, the first argument
- # is exempt from compatibility checking (the proper check
- # is performed elsewhere).
- for i in range(as_cmethod, nargs):
- if not self.args[i].type.same_as(
- other_type.args[i].type):
- return 0
- if self.has_varargs <> other_type.has_varargs:
- return 0
- if not self.return_type.same_as(other_type.return_type):
- return 0
- if not self.same_calling_convention_as(other_type):
- return 0
- return 1
-
- def same_calling_convention_as(self, other):
- return self.calling_convention == other.calling_convention
-
- def same_exception_signature_as(self, other_type):
- return self.same_exception_signature_as_resolved_type(
- other_type.resolve())
-
- def same_exception_signature_as_resolved_type(self, other_type):
- return self.exception_value == other_type.exception_value \
- and self.exception_check == other_type.exception_check
-
- def same_as_resolved_type(self, other_type, as_cmethod = 0):
- return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
- and self.same_exception_signature_as_resolved_type(other_type) \
- and self.nogil == other_type.nogil
-
- def pointer_assignable_from_resolved_type(self, other_type):
- return self.same_c_signature_as_resolved_type(other_type) \
- and self.same_exception_signature_as_resolved_type(other_type) \
- and not (self.nogil and not other_type.nogil)
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- arg_decl_list = []
- for arg in self.args:
- arg_decl_list.append(
- arg.type.declaration_code("", for_display, pyrex = pyrex))
- if self.has_varargs:
- arg_decl_list.append("...")
- arg_decl_code = string.join(arg_decl_list, ",")
- if not arg_decl_code and not pyrex:
- arg_decl_code = "void"
- trailer = ""
- if (pyrex or for_display) and not self.return_type.is_pyobject:
- if self.exception_value and self.exception_check:
- trailer = " except? %s" % self.exception_value
- elif self.exception_value:
- trailer = " except %s" % self.exception_value
- elif self.exception_check:
- trailer = " except *"
- if self.nogil:
- trailer += " nogil"
- cc = self.calling_convention_prefix()
- if (not entity_code and cc) or entity_code.startswith("*"):
- entity_code = "(%s%s)" % (cc, entity_code)
- cc = ""
- return self.return_type.declaration_code(
- "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
- for_display, dll_linkage, pyrex)
-
- def function_header_code(self, func_name, arg_code):
- return "%s%s(%s)" % (self.calling_convention_prefix(),
- func_name, arg_code)
-
- def signature_string(self):
- s = self.declaration_code("")
- return s
-
-
-class COverloadedFuncType(CType):
- # return_type CType
- # signatures [CFuncType]
-
- is_cfunction = 1
- is_overloaded = 1
-
- def __init__(self, return_type, signatures):
- self.return_type = return_type
- self.signatures = signatures
-
- def __str__(self):
- return "COverloadedFuncType(%s, [%s])" % (self.return_type,
- ", ".join(map(str, self.signatures)))
-
-
-class CFuncTypeArg:
- # name string
- # cname string
- # type PyrexType
- # pos source file position
-
- def __init__(self, name, type, pos):
- self.name = name
- self.cname = Naming.var_prefix + name
- self.type = type
- self.pos = pos
-
- def __repr__(self):
- return "%s:%s" % (self.name, repr(self.type))
-
- def declaration_code(self, for_display = 0):
- return self.type.declaration_code(self.cname, for_display)
-
-
-class CStructOrUnionType(CType):
- # name string
- # cname string
- # kind string "struct" or "union"
- # scope StructOrUnionScope, or None if incomplete
- # typedef_flag boolean
- # cplus_constructor_type COverloadedFuncType
-
- is_struct_or_union = 1
- has_attributes = 1
-
- def __init__(self, name, kind, scope, typedef_flag, cname):
- self.name = name
- self.cname = cname
- self.kind = kind
- self.typedef_flag = typedef_flag
- self.set_scope(scope)
-
- def __repr__(self):
- return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
- ("", " typedef")[self.typedef_flag])
-
- def set_scope(self, scope):
- self.scope = scope
- if scope and scope.is_cplus:
- self.cplus_constructor_type = COverloadedFuncType(self,
- scope.cplus_constructors)
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- if pyrex:
- return self.base_declaration_code(self.name, entity_code)
- else:
- if for_display:
- base = self.name
- elif self.typedef_flag:
- base = self.cname
- else:
- base = "%s %s" % (self.kind, self.cname)
- return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
-
- def is_complete(self):
- return self.scope is not None
-
- def attributes_known(self):
- return self.is_complete()
-
-
-class CEnumType(CType):
- # name string
- # cname string or None
- # typedef_flag boolean
-
- is_enum = 1
- signed = 1
- rank = -1 # Ranks below any integer type
- to_py_function = "PyInt_FromLong"
- from_py_function = "PyInt_AsLong"
-
- def __init__(self, name, cname, typedef_flag):
- self.name = name
- self.cname = cname
- self.values = []
- self.typedef_flag = typedef_flag
-
- def __str__(self):
- return self.name
-
- def __repr__(self):
- return "<CEnumType %s %s%s>" % (self.name, self.cname,
- ("", " typedef")[self.typedef_flag])
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- if pyrex:
- return self.base_declaration_code(self.cname, entity_code)
- else:
- if self.typedef_flag:
- base = self.cname
- else:
- base = "enum %s" % self.cname
- return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
-
-
-class CStringType:
- # Mixin class for C string types.
-
- is_string = 1
-
- to_py_function = "PyString_FromString"
- from_py_function = "PyString_AsString"
-
- def literal_code(self, value):
- return '"%s"' % value
-
-
-class CCharArrayType(CStringType, CArrayType):
- # C 'char []' type.
-
- parsetuple_format = "s"
- pymemberdef_typecode = "T_STRING_INPLACE"
-
- def __init__(self, size):
- CArrayType.__init__(self, c_char_type, size)
-
-
-class CCharPtrType(CStringType, CPtrType):
- # C 'char *' type.
-
- parsetuple_format = "s"
- pymemberdef_typecode = "T_STRING"
-
- def __init__(self):
- CPtrType.__init__(self, c_char_type)
-
-
-class ErrorType(PyrexType):
- # Used to prevent propagation of error messages.
-
- is_error = 1
- exception_value = "0"
- exception_check = 0
- to_py_function = "dummy"
- from_py_function = "dummy"
- parsetuple_format = "E"
-
- def declaration_code(self, entity_code,
- for_display = 0, dll_linkage = None, pyrex = 0):
- return "<error>"
-
- def same_as_resolved_type(self, other_type):
- return 1
-
-
-py_object_type = PyObjectType()
-py_type_type = TypeWrapper(None) # Bootstrapping placeholder, filled later
-
-c_void_type = CVoidType()
-c_void_ptr_type = CPtrType(c_void_type)
-c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
-
-c_uchar_type = CIntType(0, 0, "unsigned char", "T_UBYTE")
-c_ushort_type = CIntType(1, 0, "unsigned short", "T_USHORT")
-c_uint_type = CUIntType(2, 0, "unsigned int", "T_UINT")
-c_ulong_type = CULongType(3, 0, "unsigned long", "T_ULONG")
-c_size_t_type = CPySSizeTType(4, 0, "size_t")
-c_ulonglong_type = CULongLongType(5, 0, "unsigned PY_LONG_LONG", "T_ULONGLONG")
-
-c_char_type = CIntType(0, 1, "char", "T_CHAR")
-c_short_type = CIntType(1, 1, "short", "T_SHORT")
-c_int_type = CIntType(2, 1, "int", "T_INT")
-c_long_type = CIntType(3, 1, "long", "T_LONG")
-c_longlong_type = CLongLongType(5, 1, "PY_LONG_LONG", "T_LONGLONG")
-
-c_schar_type = CIntType(0, 2, "signed char", "T_CHAR")
-c_sshort_type = CIntType(1, 2, "signed short", "T_SHORT")
-c_sint_type = CIntType(2, 2, "signed int", "T_INT")
-c_slong_type = CIntType(3, 2, "signed long", "T_LONG")
-c_py_ssize_t_type = CPySSizeTType(4, 2, "Py_ssize_t")
-c_slonglong_type = CLongLongType(5, 2, "signed PY_LONG_LONG", "T_LONGLONG")
-
-c_float_type = CFloatType(6, "float", "T_FLOAT")
-c_double_type = CFloatType(7, "double", "T_DOUBLE")
-c_longdouble_type = CFloatType(8, "long double")
-
-c_null_ptr_type = CNullPtrType(c_void_type)
-c_char_array_type = CCharArrayType(None)
-c_char_ptr_type = CCharPtrType()
-c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
-c_int_ptr_type = CPtrType(c_int_type)
-
-c_returncode_type = CIntType(2, 1, "int", "T_INT", is_returncode = 1)
-
-c_anon_enum_type = CAnonEnumType(-1, 1, "<enum>")
-
-error_type = ErrorType()
-
-# Signedness values
-UNSIGNED = 0
-NOSIGN = 1
-SIGNED = 2
-
-# Longness values
-SHORT = -1
-NOLEN = 0
-LONG = 1
-LONGLONG = 2
-
-modifiers_and_name_to_type = {
- #(signedness, longness, name)
- (UNSIGNED, NOLEN, "char"): c_uchar_type,
- (UNSIGNED, SHORT, "int"): c_ushort_type,
- (UNSIGNED, NOLEN, "int"): c_uint_type,
- (UNSIGNED, LONG, "int"): c_ulong_type,
- (UNSIGNED, LONGLONG, "int"): c_ulonglong_type,
- (NOSIGN, NOLEN, "void"): c_void_type,
- (NOSIGN, NOLEN, "char"): c_char_type,
- (NOSIGN, SHORT, "int"): c_short_type,
- (NOSIGN, NOLEN, "int"): c_int_type,
- #(NOSIGN, NOLEN, "size_t"): c_size_t_type,
- #(NOSIGN, NOLEN, "Py_ssize_t"): c_py_ssize_t_type,
- (NOSIGN, LONG, "int"): c_long_type,
- (NOSIGN, LONGLONG, "int"): c_longlong_type,
- (NOSIGN, NOLEN, "float"): c_float_type,
- (NOSIGN, NOLEN, "double"): c_double_type,
- (NOSIGN, LONG, "double"): c_longdouble_type,
- (NOSIGN, NOLEN, "object"): py_object_type,
- (SIGNED, NOLEN, "char"): c_schar_type,
- (SIGNED, SHORT, "int"): c_sshort_type,
- (SIGNED, NOLEN, "int"): c_sint_type,
- (SIGNED, LONG, "int"): c_slong_type,
- (SIGNED, LONGLONG, "int"): c_slonglong_type,
-}
-
-def widest_numeric_type(type1, type2):
- # Given two numeric types, return the narrowest type
- # encompassing both of them.
- if type1.is_enum and type2.is_enum:
- widest_type = c_int_type
- elif type1.rank < type2.rank:
- widest_type = type2
- elif type1.rank > type2.rank:
- widest_type = type1
- elif type1.signed < type2.signed:
- widest_type = type1
- else:
- widest_type = type2
- return widest_type
-
-def simple_c_type(signed, longness, name):
- # Find type descriptor for simple type given name and modifiers.
- # Returns None if arguments don't make sense.
- return modifiers_and_name_to_type.get((signed, longness, name))
-
-def c_array_type(base_type, size):
- # Construct a C array type.
- if base_type is c_char_type:
- return CCharArrayType(size)
- else:
- return CArrayType(base_type, size)
-
-def c_ptr_type(base_type):
- # Construct a C pointer type.
- if base_type is c_char_type:
- return c_char_ptr_type
- else:
- return CPtrType(base_type)
-
-def public_decl(base, dll_linkage):
- if dll_linkage:
- return "%s(%s)" % (dll_linkage, base)
- else:
- return base
-
-def same_type(type1, type2):
- return type1.same_as(type2)
-
-def assignable_from(type1, type2):
- return type1.assignable_from(type2)
-
-def typecast(to_type, from_type, expr_code):
- # Return expr_code cast to a C type which can be
- # assigned to to_type, assuming its existing C type
- # is from_type.
- if to_type is from_type or \
- same_type(to_type, from_type) or \
- (not to_type.is_pyobject and assignable_from(to_type, from_type)):
- return expr_code
- else:
- return to_type.cast_code(expr_code)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py
deleted file mode 100644
index 1fc92f99..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#
-# Pyrex Scanner
-#
-
-#import pickle
-import cPickle as pickle
-
-import os
-import platform
-import stat
-import sys
-from time import time
-
-from Pyrex import Plex
-from Pyrex.Plex import Scanner
-from Pyrex.Plex.Errors import UnrecognizedInput
-from Errors import CompileError, error
-from Lexicon import string_prefixes, make_lexicon
-
-plex_version = getattr(Plex, '_version', None)
-#print "Plex version:", plex_version ###
-
-debug_scanner = 0
-trace_scanner = 0
-scanner_debug_flags = 0
-scanner_dump_file = None
-binary_lexicon_pickle = 1
-notify_lexicon_unpickling = 0
-notify_lexicon_pickling = 1
-
-lexicon = None
-
-#-----------------------------------------------------------------
-
-def hash_source_file(path):
- # Try to calculate a hash code for the given source file.
- # Returns an empty string if the file cannot be accessed.
- #print "Hashing", path ###
- try:
- from hashlib import md5
- except ImportError:
- from md5 import new as md5
- try:
- try:
- f = open(path, "rU")
- text = f.read()
- except IOError, e:
- print "Unable to hash scanner source file (%s)" % e
- return ""
- finally:
- f.close()
- # Normalise spaces/tabs. We don't know what sort of
- # space-tab substitution the file may have been
- # through, so we replace all spans of spaces and
- # tabs by a single space.
- import re
- text = re.sub("[ \t]+", " ", text)
- hash = md5(text).hexdigest()
- return hash
-
-def open_pickled_lexicon(expected_hash):
- # Try to open pickled lexicon file and verify that
- # it matches the source file. Returns the opened
- # file if successful, otherwise None. ???
- f = None
- result = None
- if os.path.exists(lexicon_pickle):
- try:
- f = open(lexicon_pickle, "rb")
- actual_hash = pickle.load(f)
- if actual_hash == expected_hash:
- result = f
- f = None
- else:
- print "Lexicon hash mismatch:" ###
- print " expected", expected_hash ###
- print " got ", actual_hash ###
- except IOError, e:
- print "Warning: Unable to read pickled lexicon", lexicon_pickle
- print e
- if f:
- f.close()
- return result
-
-def try_to_unpickle_lexicon():
- global lexicon, lexicon_pickle, lexicon_hash
- dir = os.path.dirname(__file__)
- source_file = os.path.join(dir, "Lexicon.py")
- lexicon_hash = hash_source_file(source_file)
- lexicon_pickle = os.path.join(dir, "Lexicon.pickle")
- f = open_pickled_lexicon(expected_hash = lexicon_hash)
- if f:
- if notify_lexicon_unpickling:
- t0 = time()
- print "Unpickling lexicon..."
- lexicon = pickle.load(f)
- f.close()
- if notify_lexicon_unpickling:
- t1 = time()
- print "Done (%.2f seconds)" % (t1 - t0)
-
-def create_new_lexicon():
- global lexicon
- t0 = time()
- print "Creating lexicon..."
- lexicon = make_lexicon()
- t1 = time()
- print "Done (%.2f seconds)" % (t1 - t0)
-
-def pickle_lexicon():
- f = None
- try:
- f = open(lexicon_pickle, "wb")
- except IOError:
- print "Warning: Unable to save pickled lexicon in", lexicon_pickle
- if f:
- if notify_lexicon_pickling:
- t0 = time()
- print "Pickling lexicon..."
- pickle.dump(lexicon_hash, f, binary_lexicon_pickle)
- pickle.dump(lexicon, f, binary_lexicon_pickle)
- f.close()
- if notify_lexicon_pickling:
- t1 = time()
- print "Done (%.2f seconds)" % (t1 - t0)
-
-def get_lexicon():
- global lexicon
- if not lexicon and plex_version is None:
- try_to_unpickle_lexicon()
- if not lexicon:
- create_new_lexicon()
- if plex_version is None:
- pickle_lexicon()
- return lexicon
-
-#------------------------------------------------------------------
-
-reserved_words = [
- "global", "include", "ctypedef", "cdef", "def", "class",
- "print", "del", "pass", "break", "continue", "return",
- "raise", "import", "exec", "try", "except", "finally",
- "while", "if", "elif", "else", "for", "in", "assert",
- "and", "or", "not", "is", "in", "lambda", "from",
- "NULL", "cimport", "with", "DEF", "IF", "ELIF", "ELSE"
-]
-
-class Method:
-
- def __init__(self, name):
- self.name = name
- self.__name__ = name # for Plex tracing
-
- def __call__(self, stream, text):
- return getattr(stream, self.name)(text)
-
-#------------------------------------------------------------------
-
-def build_resword_dict():
- d = {}
- for word in reserved_words:
- d[word] = 1
- return d
-
-#------------------------------------------------------------------
-
-class CompileTimeScope(object):
-
- def __init__(self, outer = None):
- self.entries = {}
- self.outer = outer
-
- def declare(self, name, value):
- self.entries[name] = value
-
- def lookup_here(self, name):
- return self.entries[name]
-
- def lookup(self, name):
- try:
- return self.lookup_here(name)
- except KeyError:
- outer = self.outer
- if outer:
- return outer.lookup(name)
- else:
- raise
-
-def initial_compile_time_env():
- benv = CompileTimeScope()
- names = ('UNAME_SYSNAME', 'UNAME_NODENAME', 'UNAME_RELEASE',
- 'UNAME_VERSION', 'UNAME_MACHINE')
- for name, value in zip(names, platform.uname()):
- benv.declare(name, value)
- import __builtin__
- names = ('False', 'True',
- 'abs', 'bool', 'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate',
- 'float', 'hash', 'hex', 'int', 'len', 'list', 'long', 'map', 'max', 'min',
- 'oct', 'ord', 'pow', 'range', 'reduce', 'repr', 'round', 'slice', 'str',
- 'sum', 'tuple', 'xrange', 'zip')
- for name in names:
- benv.declare(name, getattr(__builtin__, name))
- denv = CompileTimeScope(benv)
- return denv
-
-#------------------------------------------------------------------
-
-class PyrexScanner(Scanner):
- # context Context Compilation context
- # type_names set Identifiers to be treated as type names
- # included_files [string] Files included with 'include' statement
- # compile_time_env dict Environment for conditional compilation
- # compile_time_eval boolean In a true conditional compilation context
- # compile_time_expr boolean In a compile-time expression context
-
- resword_dict = build_resword_dict()
-
- def __init__(self, file, filename, parent_scanner = None,
- scope = None, context = None):
- Scanner.__init__(self, get_lexicon(), file, filename)
- if parent_scanner:
- self.context = parent_scanner.context
- self.type_names = parent_scanner.type_names
- self.included_files = parent_scanner.included_files
- self.compile_time_env = parent_scanner.compile_time_env
- self.compile_time_eval = parent_scanner.compile_time_eval
- self.compile_time_expr = parent_scanner.compile_time_expr
- else:
- self.context = context
- self.type_names = scope.type_names
- self.included_files = scope.pyrex_include_files
- self.compile_time_env = initial_compile_time_env()
- self.compile_time_eval = 1
- self.compile_time_expr = 0
- self.trace = trace_scanner
- self.indentation_stack = [0]
- self.indentation_char = None
- self.bracket_nesting_level = 0
- self.begin('INDENT')
- self.sy = ''
- self.next()
-
- def current_level(self):
- return self.indentation_stack[-1]
-
- def open_bracket_action(self, text):
- self.bracket_nesting_level = self.bracket_nesting_level + 1
- return text
-
- def close_bracket_action(self, text):
- self.bracket_nesting_level = self.bracket_nesting_level - 1
- return text
-
- def newline_action(self, text):
- if self.bracket_nesting_level == 0:
- self.begin('INDENT')
- self.produce('NEWLINE', '')
-
- string_states = {
- "'": 'SQ_STRING',
- '"': 'DQ_STRING',
- "'''": 'TSQ_STRING',
- '"""': 'TDQ_STRING'
- }
-
- def begin_string_action(self, text):
- if text[:1] in string_prefixes:
- text = text[1:]
- self.begin(self.string_states[text])
- self.produce('BEGIN_STRING')
-
- def end_string_action(self, text):
- self.begin('')
- self.produce('END_STRING')
-
- def unclosed_string_action(self, text):
- self.end_string_action(text)
- self.error("Unclosed string literal")
-
- def indentation_action(self, text):
- self.begin('')
- # Indentation within brackets should be ignored.
- #if self.bracket_nesting_level > 0:
- # return
- # Check that tabs and spaces are being used consistently.
- if text:
- c = text[0]
- #print "Scanner.indentation_action: indent with", repr(c) ###
- if self.indentation_char is None:
- self.indentation_char = c
- #print "Scanner.indentation_action: setting indent_char to", repr(c)
- else:
- if self.indentation_char <> c:
- self.error("Mixed use of tabs and spaces")
- if text.replace(c, "") <> "":
- self.error("Mixed use of tabs and spaces")
- # Figure out how many indents/dedents to do
- current_level = self.current_level()
- new_level = len(text)
- #print "Changing indent level from", current_level, "to", new_level ###
- if new_level == current_level:
- return
- elif new_level > current_level:
- #print "...pushing level", new_level ###
- self.indentation_stack.append(new_level)
- self.produce('INDENT', '')
- else:
- while new_level < self.current_level():
- #print "...popping level", self.indentation_stack[-1] ###
- self.indentation_stack.pop()
- self.produce('DEDENT', '')
- #print "...current level now", self.current_level() ###
- if new_level <> self.current_level():
- self.error("Inconsistent indentation")
-
- def eof_action(self, text):
- while len(self.indentation_stack) > 1:
- self.produce('DEDENT', '')
- self.indentation_stack.pop()
- self.produce('EOF', '')
-
- def next(self):
- try:
- sy, systring = self.read()
- except UnrecognizedInput:
- self.error("Unrecognized character")
- if sy == 'IDENT' and systring in self.resword_dict:
- sy = systring
- self.sy = sy
- self.systring = systring
- if debug_scanner:
- _, line, col = self.position()
- if not self.systring or self.sy == self.systring:
- t = self.sy
- else:
- t = "%s %s" % (self.sy, self.systring)
- print "--- %3d %2d %s" % (line, col, t)
-
- def put_back(self, sy, systring):
- self.unread(self.sy, self.systring)
- self.sy = sy
- self.systring = systring
-
- def unread(self, token, value):
- # This method should be added to Plex
- self.queue.insert(0, (token, value))
-
- def add_type_name(self, name):
- self.type_names[name] = 1
-
- def looking_at_type_name(self):
- return self.sy == 'IDENT' and self.systring in self.type_names
-
- def error(self, message, pos = None):
- if pos is None:
- pos = self.position()
- if self.sy == 'INDENT':
- error(pos, "Possible inconsistent indentation")
- raise error(pos, message)
-
- def expect(self, what, message = None):
- if self.sy == what:
- self.next()
- else:
- self.expected(what, message)
-
- def expect_keyword(self, what, message = None):
- if self.sy == 'IDENT' and self.systring == what:
- self.next()
- else:
- self.expected(what, message)
-
- def expected(self, what, message):
- if message:
- self.error(message)
- else:
- self.error("Expected '%s'" % what)
-
- def expect_indent(self):
- self.expect('INDENT',
- "Expected an increase in indentation level")
-
- def expect_dedent(self):
- self.expect('DEDENT',
- "Expected a decrease in indentation level")
-
- def expect_newline(self, message = "Expected a newline"):
- # Expect either a newline or end of file
- if self.sy <> 'EOF':
- self.expect('NEWLINE', message)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py
deleted file mode 100644
index b56b8531..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py
+++ /dev/null
@@ -1,1342 +0,0 @@
-#
-# Pyrex - Symbol Table
-#
-
-from Errors import warning, error, InternalError
-import Options
-import Naming
-import PyrexTypes
-from PyrexTypes import \
- py_object_type, py_type_type, \
- c_int_type, c_char_array_type, \
- CEnumType, CStructOrUnionType, PyExtensionType
-from TypeSlots import \
- pyfunction_signature, pymethod_signature, \
- get_special_method_signature, get_property_accessor_signature
-
-class Entry:
- # A symbol table entry in a Scope or ModuleNamespace.
- #
- # name string Python name of entity
- # cname string C name of entity
- # type PyrexType Type of entity
- # ctype PyrexType Declared C type, if different from Pyrex type
- # doc string Doc string
- # init string Initial value
- # visibility 'private' or 'public' or 'extern'
- # is_builtin boolean Is an entry in the Python builtins dict
- # is_cglobal boolean Is a C global variable
- # is_pyglobal boolean Is a Python module-level variable or
- # class attribute during class construction
- # is_variable boolean Is a variable
- # is_cfunction boolean Is a C function
- # is_cmethod boolean Is a C method of an extension type
- # is_builtin_method boolean Is a method corresponding to a Python/C API func
- # is_type boolean Is a type definition
- # is_const boolean Is a constant
- # is_property boolean Is a property of an extension type:
- # #doc_cname string or None C const holding the docstring
- # getter_cname string C func for getting property
- # setter_cname string C func for setting or deleting property
- # is_self_arg boolean Is the "self" arg of an exttype method
- # is_readonly boolean Can't be assigned to
- # func_cname string C func implementing Python func
- # pos position Source position where declared
- # namespace_cname string If is_pyglobal, the C variable
- # holding its home namespace
- # pymethdef_cname string PyMethodDef structure
- # signature Signature Arg & return types for Python func
- # init_to_none boolean True if initial value should be None
- # as_variable Entry Alternative interpretation of extension
- # type name or builtin C function as a variable
- # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
- # in_cinclude boolean Suppress C declaration code
- # enum_values [Entry] For enum types, list of values
- # qualified_name string "modname.funcname" or "modname.classname"
- # or "modname.classname.funcname"
- # is_declared_generic boolean Is declared as PyObject * even though its
- # type is an extension type
- # as_module None Module scope, if a cimported module
- # is_inherited boolean Is an inherited attribute of an extension type
- # #interned_cname string C name of interned name string
- # pystring_cname string C name of Python version of string literal
- # #is_interned boolean For string const entries, value is interned
- # used boolean
- # is_special boolean Is a special method or property accessor
- # of an extension type
- # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
- # api boolean Generate C API for C class or function
- # utility_code string Utility code needed when this entry is used
-
- borrowed = 0
- init = ""
- visibility = 'private'
- ctype = None
- is_builtin = 0
- is_cglobal = 0
- is_pyglobal = 0
- is_variable = 0
- is_cfunction = 0
- is_cmethod = 0
- is_builtin_method = 0
- is_type = 0
- is_const = 0
- is_property = 0
- doc_cname = None
- getter_cname = None
- setter_cname = None
- is_self_arg = 0
- is_declared_generic = 0
- is_readonly = 0
- func_cname = None
- doc = None
- init_to_none = 0
- as_variable = None
- xdecref_cleanup = 0
- in_cinclude = 0
- as_module = None
- is_inherited = 0
- #interned_cname = None
- pystring_cname = None
- is_interned = 0
- used = 0
- is_special = 0
- defined_in_pxd = 0
- api = 0
- utility_code = None
-
- def __init__(self, name, cname, type, pos = None, init = None):
- self.name = name
- self.cname = cname
- self.type = type
- self.pos = pos
- self.init = init
-
- def redeclared(self, pos):
- error(pos, "'%s' does not match previous declaration" % self.name)
- error(self.pos, "Previous declaration is here")
-
-
-class Scope:
- # name string Unqualified name
- # outer_scope Scope or None Enclosing scope
- # entries {string : Entry} Python name to entry, non-types
- # const_entries [Entry] Constant entries
- # type_entries [Entry] Struct/union/enum/typedef/exttype entries
- # sue_entries [Entry] Struct/union/enum entries
- # arg_entries [Entry] Function argument entries
- # var_entries [Entry] User-defined variable entries
- # pyfunc_entries [Entry] Python function entries
- # cfunc_entries [Entry] C function entries
- # c_class_entries [Entry] All extension type entries
- # temp_entries [Entry] Temporary variable entries
- # free_temp_entries [Entry] Temp variables currently unused
- # temp_counter integer Counter for naming temp vars
- # cname_to_entry {string : Entry} Temp cname to entry mapping
- # pow_function_used boolean The C pow() function is used
- # return_type PyrexType or None Return type of function owning scope
- # is_py_class_scope boolean Is a Python class scope
- # is_c_class_scope boolean Is an extension type scope
- # scope_prefix string Disambiguator for C names
- # in_cinclude boolean Suppress C declaration code
- # qualified_name string "modname" or "modname.classname"
- # #pystring_entries [Entry] String const entries newly used as
- # # Python strings in this scope
- # nogil boolean In a nogil section
- # is_cplus boolean Is a C++ struct namespace
- # reraise_used boolean Reraise statement encountered
-
- is_py_class_scope = 0
- is_c_class_scope = 0
- scope_prefix = ""
- in_cinclude = 0
- nogil = 0
- return_type = None
- reraise_used = 0
-
- def __init__(self, name, outer_scope, parent_scope):
- # The outer_scope is the next scope in the lookup chain.
- # The parent_scope is used to derive the qualified name of this scope.
- self.name = name
- self.outer_scope = outer_scope
- self.parent_scope = parent_scope
- mangled_name = "%d%s_" % (len(name), name)
- qual_scope = self.qualifying_scope()
- if qual_scope:
- self.qualified_name = qual_scope.qualify_name(name)
- self.scope_prefix = qual_scope.scope_prefix + mangled_name
- else:
- self.qualified_name = name
- self.scope_prefix = mangled_name
- self.entries = {}
- self.const_entries = []
- self.type_entries = []
- self.sue_entries = []
- self.arg_entries = []
- self.var_entries = []
- self.pyfunc_entries = []
- self.cfunc_entries = []
- self.c_class_entries = []
- self.defined_c_classes = []
- self.imported_c_classes = {}
- self.temp_entries = []
- self.free_temp_entries = []
- self.temp_counter = 1
- self.cname_to_entry = {}
- self.pow_function_used = 0
- #self.pystring_entries = []
-
- def __str__(self):
- return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
-
-# def intern(self, name):
-# return self.global_scope().intern(name)
-
- def qualifying_scope(self):
- return self.parent_scope
-
- def mangle(self, prefix, name = None):
- if name:
- return "%s%s%s" % (prefix, self.scope_prefix, name)
- else:
- return self.parent_scope.mangle(prefix, self.name)
-
- def mangle_internal(self, name):
- # Mangle an internal name so as not to clash with any
- # user-defined name in this scope.
- prefix = "%s%s_" % (Naming.pyrex_prefix, name)
- return self.mangle(prefix)
- #return self.parent_scope.mangle(prefix, self.name)
-
- def global_scope(self):
- # Return the module-level scope containing this scope.
- return self.outer_scope.global_scope()
-
- def declare(self, name, cname, type, pos):
- # Create new entry, and add to dictionary if
- # name is not None. Reports an error if already
- # declared.
- dict = self.entries
- if name and dict.has_key(name):
- error(pos, "'%s' already declared" % name)
- entry = Entry(name, cname, type, pos = pos)
- entry.in_cinclude = self.in_cinclude
- if name:
- entry.qualified_name = self.qualify_name(name)
- dict[name] = entry
- return entry
-
- def qualify_name(self, name):
- return "%s.%s" % (self.qualified_name, name)
-
- def declare_const(self, name, type, value, pos, cname = None):
- # Add an entry for a named constant.
- if not cname:
- if self.in_cinclude:
- cname = name
- else:
- cname = self.mangle(Naming.enum_prefix, name)
- entry = self.declare(name, cname, type, pos)
- entry.is_const = 1
- entry.value = value
- return entry
-
- def declare_type(self, name, type, pos,
- cname = None, visibility = 'private', defining = 1):
- # Add an entry for a type definition.
- if not cname:
- cname = name
- entry = self.declare(name, cname, type, pos)
- entry.visibility = visibility
- entry.is_type = 1
- if defining:
- self.type_entries.append(entry)
- return entry
-
- def declare_typedef(self, name, base_type, pos, cname = None,
- visibility = 'private'):
- if not cname:
- if self.in_cinclude or visibility == 'public':
- cname = name
- else:
- cname = self.mangle(Naming.type_prefix, name)
- type = PyrexTypes.CTypedefType(cname, base_type)
- entry = self.declare_type(name, type, pos, cname, visibility)
- type.qualified_name = entry.qualified_name
- return entry
-
- def declare_struct_or_union(self, name, kind, scope,
- typedef_flag, pos, cname = None, visibility = 'private'):
- # Add an entry for a struct or union definition.
- if not cname:
- if self.in_cinclude or visibility == 'public':
- cname = name
- else:
- cname = self.mangle(Naming.type_prefix, name)
- entry = self.lookup_here(name)
- if not entry:
- type = CStructOrUnionType(name, kind, scope, typedef_flag, cname)
- entry = self.declare_type(name, type, pos, cname,
- visibility = visibility, defining = scope is not None)
- self.sue_entries.append(entry)
- else:
- if not (entry.is_type and entry.type.is_struct_or_union
- and entry.type.kind == kind):
- entry.redeclared(pos)
- elif scope and entry.type.scope:
- error(pos, "'%s' already defined" % name)
- else:
- self.check_previous_typedef_flag(entry, typedef_flag, pos)
- self.check_previous_visibility(entry, visibility, pos)
- if scope:
- entry.pos = pos
- entry.type.set_scope(scope)
- self.type_entries.append(entry)
- if not scope and not entry.type.scope:
- self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
- return entry
-
- def check_previous_typedef_flag(self, entry, typedef_flag, pos):
- if typedef_flag <> entry.type.typedef_flag:
- error(pos, "'%s' previously declared using '%s'" % (
- entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
-
- def check_previous_visibility(self, entry, visibility, pos):
- if entry.visibility <> visibility:
- error(pos, "'%s' previously declared as '%s'" % (
- entry.name, entry.visibility))
-
- def declare_enum(self, name, pos, cname, typedef_flag,
- visibility = 'private'):
- if name:
- if not cname:
- if self.in_cinclude or visibility == 'public':
- cname = name
- else:
- cname = self.mangle(Naming.type_prefix, name)
- type = CEnumType(name, cname, typedef_flag)
- else:
- type = PyrexTypes.c_anon_enum_type
- entry = self.declare_type(name, type, pos, cname = cname,
- visibility = visibility)
- entry.enum_values = []
- self.sue_entries.append(entry)
- return entry
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', is_cdef = 0):
- # Add an entry for a variable.
- if not cname:
- if visibility <> 'private':
- cname = name
- else:
- cname = self.mangle(Naming.var_prefix, name)
- entry = self.declare(name, cname, type, pos)
- entry.is_variable = 1
- entry.visibility = visibility
- return entry
-
- def declare_builtin(self, name, pos):
- return self.outer_scope.declare_builtin(name, pos)
-
- def declare_pyfunction(self, name, pos):
- # Add an entry for a Python function.
- entry = self.declare_var(name, py_object_type, pos)
- entry.signature = pyfunction_signature
- self.pyfunc_entries.append(entry)
- return entry
-
- def register_pyfunction(self, entry):
- self.pyfunc_entries.append(entry)
-
- def declare_cfunction(self, name, type, pos,
- cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
- # Add an entry for a C function.
- entry = self.lookup_here(name)
- if entry:
- if visibility <> 'private' and visibility <> entry.visibility:
- error(pos, "Function '%s' previously declared as '%s'" % (
- name, entry.visibility))
- if not entry.type.same_as(type):
- error(pos, "Function signature does not match previous declaration")
- else:
- if not cname:
- if api or visibility <> 'private':
- cname = name
- else:
- cname = self.mangle(Naming.func_prefix, name)
- entry = self.add_cfunction(name, type, pos, cname, visibility)
- entry.func_cname = cname
- if in_pxd and visibility <> 'extern':
- entry.defined_in_pxd = 1
- if api:
- entry.api = 1
- if not defining and not in_pxd and visibility <> 'extern':
- error(pos, "Non-extern C function declared but not defined")
- return entry
-
- def add_cfunction(self, name, type, pos, cname, visibility = 'private'):
- # Add a C function entry without giving it a func_cname.
- entry = self.declare(name, cname, type, pos)
- entry.is_cfunction = 1
- entry.visibility = visibility
- self.cfunc_entries.append(entry)
- return entry
-
- def attach_var_entry_to_c_class(self, entry):
- # The name of an extension class has to serve as both a type name and a
- # variable name holding the type object. It is represented in the symbol
- # table by a type entry with a variable entry attached to it. For the
- # variable entry, we use a read-only C global variable whose name is an
- # expression that refers to the type object.
- var_entry = Entry(name = entry.name,
- #type = py_object_type,
- type = py_type_type,
- pos = entry.pos,
- #cname = "((PyObject*)%s)" % entry.type.typeptr_cname
- cname = entry.type.typeptr_cname)
- var_entry.is_variable = 1
- var_entry.is_cglobal = 1
- var_entry.is_readonly = 1
- entry.as_variable = var_entry
-
- def find(self, name, pos):
- # Look up name, report error if not found.
- entry = self.lookup(name)
- if entry:
- return entry
- else:
- error(pos, "'%s' is not declared" % name)
-
- def find_imported_module(self, path, pos):
- # Look up qualified name, must be a module, report error if not found.
- # Path is a list of names.
- scope = self
- for name in path:
- entry = scope.find(name, pos)
- if not entry:
- return None
- if entry.as_module:
- scope = entry.as_module
- else:
- error(pos, "'%s' is not a cimported module" % scope.qualified_name)
- return None
- return scope
-
- def find_qualified_name(self, module_and_name, pos):
- # Look up qualified name, report error if not found.
- # module_and_name = [path, name] where path is a list of names.
- module_path, name = module_and_name
- scope = self.find_imported_module(module_path, pos)
- if scope:
- entry = scope.lookup_here(name)
- if not entry:
- mess = "'%s' is not declared" % name
- if module_path:
- mess = "%s in module '%s'" % (mess, ".".join(module_path))
- error(pos, mess)
- return entry
-
- def lookup(self, name):
- # Look up name in this scope or an enclosing one.
- # Return None if not found.
- return (self.lookup_here(name)
- or (self.outer_scope and self.outer_scope.lookup(name))
- or None)
-
- def lookup_here(self, name):
- # Look up in this scope only, return None if not found.
- return self.entries.get(name, None)
-
- def lookup_target(self, name):
- # Look up name in this scope only. Declare as Python
- # variable if not found.
- entry = self.lookup_here(name)
- if not entry:
- entry = self.declare_var(name, py_object_type, None)
- return entry
-
-# def add_string_const(self, value):
-# # Add an entry for a string constant.
-# cname = self.new_const_cname()
-# entry = Entry("", cname, c_char_array_type, init = value)
-# entry.used = 1
-# self.const_entries.append(entry)
-# return entry
-
-# def get_string_const(self, value):
-# # Get entry for string constant. Returns an existing
-# # one if possible, otherwise creates a new one.
-# genv = self.global_scope()
-# entry = genv.string_to_entry.get(value)
-# if not entry:
-# entry = self.add_string_const(value)
-# genv.string_to_entry[value] = entry
-# return entry
-
-# def add_py_string(self, entry):
-# # If not already done, allocate a C name for a Python version of
-# # a string literal, and add it to the list of Python strings to
-# # be created at module init time. If the string resembles a
-# # Python identifier, it will be interned.
-# if not entry.pystring_cname:
-# value = entry.init
-# if identifier_pattern.match(value):
-# entry.pystring_cname = self.intern(value)
-# entry.is_interned = 1
-# else:
-# entry.pystring_cname = entry.cname + "p"
-# self.pystring_entries.append(entry)
-# self.global_scope().all_pystring_entries.append(entry)
-
-# def new_const_cname(self):
-# # Create a new globally-unique name for a constant.
-# return self.global_scope().new_const_cname()
-
- def allocate_temp(self, type):
- # Allocate a temporary variable of the given type from the
- # free list if available, otherwise create a new one.
- # Returns the cname of the variable.
- for entry in self.free_temp_entries:
- if entry.type == type:
- self.free_temp_entries.remove(entry)
- return entry.cname
- n = self.temp_counter
- self.temp_counter = n + 1
- cname = "%s%d" % (Naming.pyrex_prefix, n)
- entry = Entry("", cname, type)
- entry.used = 1
- if type.is_pyobject:
- entry.init = "0"
- self.cname_to_entry[entry.cname] = entry
- self.temp_entries.append(entry)
- return entry.cname
-
- def allocate_temp_pyobject(self):
- # Allocate a temporary PyObject variable.
- return self.allocate_temp(py_object_type)
-
- def release_temp(self, cname):
- # Release a temporary variable for re-use.
- if not cname: # can happen when type of an expr is void
- return
- entry = self.cname_to_entry[cname]
- if entry in self.free_temp_entries:
- raise InternalError("Temporary variable %s released more than once"
- % cname)
- self.free_temp_entries.append(entry)
-
- def temps_in_use(self):
- # Return a new list of temp entries currently in use.
- return [entry for entry in self.temp_entries
- if entry not in self.free_temp_entries]
-
-# def use_utility_code(self, new_code):
-# self.global_scope().use_utility_code(new_code)
-
- def generate_library_function_declarations(self, code):
- # Generate extern decls for C library funcs used.
- #if self.pow_function_used:
- # code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
- pass
-
- def defines_any(self, names):
- # Test whether any of the given names are
- # defined in this scope.
- for name in names:
- if name in self.entries:
- return 1
- return 0
-
-
-class BuiltinScope(Scope):
- # The builtin namespace.
- #
- # type_names {string : 1} Set of type names (used during parsing)
-
- def __init__(self):
- Scope.__init__(self, "__builtin__", None, None)
- self.type_names = {}
-
- def declare_builtin(self, name, pos):
- entry = self.declare(name, name, py_object_type, pos)
- entry.is_builtin = 1
- return entry
-
- def declare_builtin_constant(self, name, type, cname, ctype = None):
- entry = self.declare(name, cname, type, None)
- if ctype:
- entry.ctype = ctype
- entry.is_variable = 1
- entry.is_cglobal = 1
- entry.is_readonly = 1
- return entry
-
- def declare_builtin_c_type(self, name, type):
- entry = self.declare_type(name, type, pos = None)
- self.type_names[name] = 1
- return entry
-
- def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
- utility_code = None):
- # If python_equiv == "*", the Python equivalent has the same name
- # as the entry, otherwise it has the name specified by python_equiv.
- entry = self.declare_cfunction(name, type, None, cname)
- entry.utility_code = utility_code
- if python_equiv:
- if python_equiv == "*":
- python_equiv = name
- var_entry = Entry(python_equiv, python_equiv, py_object_type)
- var_entry.is_variable = 1
- var_entry.is_builtin = 1
- entry.as_variable = var_entry
- return entry
-
- def declare_builtin_class(self, name, objstruct_cname, typeobj_cname):
- type = PyExtensionType(name, typedef_flag = 1, base_type = None)
- type.module_name = "__builtin__"
- type.typeptr_cname = "(&%s)" % typeobj_cname
- type.objstruct_cname = objstruct_cname
- type.is_builtin = 1
- scope = CClassScope(name = name, outer_scope = self, visibility = "extern")
- type.set_scope(scope)
- entry = self.declare_type(name, type, pos = None, visibility = "extern",
- defining = 0)
- self.attach_var_entry_to_c_class(entry)
- self.type_names[name] = 1
- return entry
-
- def find_type(self, name):
- # Used internally during initialisation, always succeeds
- entry = self.lookup_here(name)
- return entry.type
-
-
-class ModuleScope(Scope):
- # module_name string Python name of the module
- # module_cname string C name of Python module object
- # #module_dict_cname string C name of module dict object
- # method_table_cname string C name of method table
- # doc string Module doc string
- # python_include_files [string] Standard Python headers to be included
- # include_files [string] Other C headers to be included
- # context Context
- # pxd_file_loaded boolean Corresponding .pxd file has been processed
- # cimported_modules [ModuleScope] Modules imported with cimport
- # types_imported {PyrexType : 1} Set of types for which import code generated
- # type_names {string : 1} Set of type names (used during parsing)
- # pyrex_include_files [string] Pyrex sources included with 'include'
- # gil_used boolean True if GIL is acquired/released anywhere
-
- gil_used = 0
-
- def __init__(self, name, parent_module, context):
- outer_scope = context.find_submodule("__builtin__")
- Scope.__init__(self, name, outer_scope, parent_module)
- self.module_name = name
- self.context = context
- self.module_cname = Naming.module_cname
- self.module_dict_cname = Naming.moddict_cname
- self.method_table_cname = Naming.methtable_cname
- self.doc = ""
- self.python_include_files = ["Python.h", "structmember.h"]
- self.include_files = []
- self.type_names = self.outer_scope.type_names.copy()
- self.pxd_file_loaded = 0
- self.cimported_modules = []
- self.types_imported = {}
- self.pyrex_include_files = []
-
-# def qualifying_scope(self):
-# return self.parent_module
-
- def global_scope(self):
- return self
-
- def declare_builtin(self, name, pos):
- entry = Scope.declare_builtin(self, name, pos)
- #entry.interned_cname = self.intern(name)
- return entry
-
-# def intern(self, name):
-# intern_map = self.intern_map
-# cname = intern_map.get(name)
-# if not cname:
-# cname = Naming.interned_prefix + name
-# intern_map[name] = cname
-# self.interned_names.append(name)
-# return cname
-
- def add_include_file(self, filename):
- if filename not in self.python_include_files \
- and filename not in self.include_files:
- self.include_files.append(filename)
-
- def add_imported_module(self, scope):
- #print "add_imported_module:", scope, "to", self ###
- if scope not in self.cimported_modules:
- self.cimported_modules.append(scope)
-
- def add_imported_entry(self, name, entry, pos):
- if entry not in self.entries:
- self.entries[name] = entry
- else:
- error(pos, "'%s' already declared" % name)
-
- def declare_module(self, name, scope, pos):
- # Declare a cimported module. This is represented as a
- # Python module-level variable entry with a module
- # scope attached to it. Reports an error and returns
- # None if previously declared as something else.
- entry = self.lookup_here(name)
- if entry:
- if entry.is_pyglobal and entry.as_module is scope:
- return entry # Already declared as the same module
- if not (entry.is_pyglobal and not entry.as_module):
- #error(pos, "'%s' redeclared" % name)
- entry.redeclared(pos)
- return None
- else:
- entry = self.declare_var(name, py_object_type, pos)
- #print "declare_module:", scope, "in", self ###
- entry.as_module = scope
- #self.cimported_modules.append(scope)
- return entry
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', is_cdef = 0):
- # Add an entry for a global variable. If it is a Python
- # object type, and not declared with cdef, it will live
- # in the module dictionary, otherwise it will be a C
- # global variable.
- entry = Scope.declare_var(self, name, type, pos,
- cname, visibility, is_cdef)
- if not visibility in ('private', 'public', 'extern'):
- error(pos, "Module-level variable cannot be declared %s" % visibility)
- if not is_cdef:
- if not (type.is_pyobject and not type.is_extension_type):
- raise InternalError(
- "Non-cdef global variable is not a generic Python object")
- entry.is_pyglobal = 1
- entry.namespace_cname = self.module_cname
- #if Options.intern_names:
- # entry.interned_cname = self.intern(name)
- else:
- entry.is_cglobal = 1
- self.var_entries.append(entry)
- return entry
-
- def declare_global(self, name, pos):
- entry = self.lookup_here(name)
- if not entry:
- self.declare_var(name, py_object_type, pos)
-
- def add_default_value(self, type):
- # Add an entry for holding a function argument
- # default value.
- cname = "%s%d" % (Naming.default_prefix, self.default_counter)
- self.default_counter += 1
- entry = Entry("", cname, type)
- self.default_entries.append(entry)
- return entry
-
-# def new_const_cname(self):
-# # Create a new globally-unique name for a constant.
-# n = self.const_counter
-# self.const_counter = n + 1
-# return "%s%d" % (Naming.const_prefix, n)
-
-# def use_utility_code(self, new_code):
-# # Add string to list of utility code to be included,
-# # if not already there (tested using 'is').
-# for old_code in self.utility_code_used:
-# if old_code is new_code:
-# return
-# self.utility_code_used.append(new_code)
-
- def declare_c_class(self, name, pos, defining = 0, implementing = 0,
- module_name = None, base_type = None, visibility = 'private',
- typedef_flag = 0, api = 0, options = None):
- #
- # Look for previous declaration as a type
- #
- #print "declare_c_class:", name, "in", self ###
- entry = self.lookup_here(name)
- if entry:
- type = entry.type
- if not (entry.is_type and type.is_extension_type):
- entry = None # Will cause redeclaration and produce an error
- else:
- scope = type.scope
- defined = scope and scope.defined
- definitive = defining or (implementing and not defined)
- self.check_previous_typedef_flag(entry, typedef_flag, pos)
- if base_type or definitive:
- if type.base_type and base_type is not type.base_type:
- error(pos, "Base type does not match previous declaration")
- type.base_type = base_type
- #
- # Make a new entry if needed
- #
- if not entry:
- type = PyExtensionType(name, typedef_flag, base_type)
- if visibility == 'extern':
- type.module_name = module_name
- else:
- type.module_name = self.qualified_name
- type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
- entry = self.declare_type(name, type, pos, visibility = visibility,
- defining = 0)
- if options and options.objstruct_cname:
- type.objstruct_cname = options.objstruct_cname
- elif not entry.in_cinclude:
- type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
- else:
- error(entry.pos,
- "Object name required for 'public' or 'extern' C class")
- self.attach_var_entry_to_c_class(entry)
- self.c_class_entries.append(entry)
- #
- # Check for re-definition and create scope if needed
- #
- scope = type.scope
- if not scope:
- if defining or implementing:
- scope = CClassScope(name = name, outer_scope = self,
- visibility = visibility, no_gc = options.no_gc)
- if base_type:
- scope.declare_inherited_c_attributes(base_type.scope)
- type.set_scope(scope)
- self.type_entries.append(entry)
- else:
- self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
- else:
- if defining and scope.defined:
- error(pos, "C class '%s' already defined" % name)
- elif implementing and scope.implemented:
- error(pos, "C class '%s' already implemented" % name)
- scope.outer_scope = self
- #
- # Fill in options, checking for compatibility with any previous declaration
- #
- if defining:
- entry.defined_in_pxd = 1
- if implementing: # So that filenames in runtime exceptions refer to
- entry.pos = pos # the .pyx file and not the .pxd file
- if visibility <> 'private' and entry.visibility <> visibility:
- error(pos, "Class '%s' previously declared as '%s'"
- % (name, entry.visibility))
- if api:
- entry.api = 1
- if options:
- if options.objstruct_cname:
- if type.objstruct_cname and type.objstruct_cname <> options.objstruct_cname:
- error(pos, "Object struct name differs from previous declaration")
- type.objstruct_cname = options.objstruct_cname
- if options.typeobj_cname:
- if type.typeobj_cname and type.typeobj_cname <> options.typeobj_cname:
- error(pos, "Type object name differs from previous declaration")
- type.typeobj_cname = options.typeobj_cname
- #
- # Return new or existing entry
- #
- return entry
-
- def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
- if typedef_flag and not self.in_cinclude:
- error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
-
- def allocate_vtable_names(self, entry):
- # If extension type has a vtable, allocate vtable struct and
- # slot names for it.
- type = entry.type
- if type.base_type and type.base_type.vtabslot_cname:
- #print "...allocating vtabslot_cname because base type has one" ###
- type.vtabslot_cname = "%s.%s" % (
- Naming.obj_base_cname, type.base_type.vtabslot_cname)
- elif type.scope and type.scope.cfunc_entries:
- #print "...allocating vtabslot_cname because there are C methods" ###
- type.vtabslot_cname = Naming.vtabslot_cname
- if type.vtabslot_cname:
- #print "...allocating other vtable related cnames" ###
- type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
- type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
-
- def check_c_classes(self):
- # Performs post-analysis checking and finishing up of extension types
- # being implemented in this module. This is called only for the main
- # .pyx file scope and its associated .pxd scope, not for cimported .pxd
- # scopes.
- #
- # Checks all extension types declared in this scope to
- # make sure that:
- #
- # * The extension type is implemented
- # * All required object and type names have been specified or generated
- # * All non-inherited C methods are implemented
- #
- # Also allocates a name for the vtable if needed.
- #
- debug_check_c_classes = 0
- if debug_check_c_classes:
- print "Scope.check_c_classes: checking scope", self.qualified_name
- for entry in self.c_class_entries:
- if debug_check_c_classes:
- print "...entry", entry.name, entry
- print "......type =", entry.type
- print "......visibility =", entry.visibility
- type = entry.type
- name = entry.name
- visibility = entry.visibility
- # Check defined
- if not type.scope:
- error(entry.pos, "C class '%s' is declared but not defined" % name)
- # Generate typeobj_cname
- if visibility <> 'extern' and not type.typeobj_cname:
- type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
- ## Generate typeptr_cname
- #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
- # Check C methods defined
- if type.scope:
- for method_entry in type.scope.cfunc_entries:
- if not method_entry.is_inherited and not method_entry.func_cname:
- error(method_entry.pos, "C method '%s' is declared but not defined" %
- method_entry.name)
- # Allocate vtable name if necessary
- if type.vtabslot_cname:
- #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
- type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
-
-
-class DefinitionScope(ModuleScope):
- # Scope for the definition part of a module (.pxd).
- #
- # parent_module Scope Parent in the import namespace
- # module_entries {string : Entry} For cimport statements
-
- def __init__(self, name, parent_module, context):
- ModuleScope.__init__(self, name, parent_module, context)
- self.parent_module = parent_module
- self.module_entries = {}
-
- def find_module(self, module_name, pos):
- # Find a module in the import namespace, interpreting
- # relative imports relative to this module's parent.
- # Finds and parses the module's .pxd file if the module
- # has not been referenced before.
- return self.global_scope().context.find_module(
- module_name, relative_to = self.parent_module, pos = pos)
-
- def find_submodule(self, name):
- # Find and return the definition scope for a submodule of this module,
- # creating a new empty one if necessary. Doesn't parse .pxd.
- scope = self.lookup_submodule(name)
- if not scope:
- scope = DefinitionScope(name,
- parent_module = self, context = self.context)
- self.module_entries[name] = scope
- return scope
-
- def lookup_submodule(self, name):
- # Return scope for submodule of this module, or None.
- return self.module_entries.get(name, None)
-
-
-class ImplementationScope(ModuleScope):
- # This scope is used to keep the names declared only in the implementation
- # part of a module from being seen by other modules that cimport this
- # module. Also holds information that is only relevant for the
- # implementation part. When declaring or looking up a name, this scope
- # behaves as though it and its corresponding definition_scope were a single
- # scope.
- #
- # definition_scope ModuleScope Scope holding definitions from corresponding .pxd
- # doc_cname string C name of module doc string
- # default_counter string Counter for naming default values
- # #const_counter integer Counter for naming constants
- # #utility_code_used [string] Utility code to be included
- # default_entries [Entry] Function argument default entries
- # #string_to_entry {string : Entry} Map string const to entry
- # #intern_map {string : string} Mapping from Python names to interned strs
- # #interned_names [string] Interned names pending generation of declarations
- # #all_pystring_entries [Entry] Python string consts from all scopes
-
- def __init__(self, def_scope):
- ModuleScope.__init__(self, def_scope.name, def_scope.parent_scope,
- def_scope.context)
- self.definition_scope = def_scope
- self.doc_cname = Naming.moddoc_cname
- self.type_names = def_scope.type_names.copy()
- self.default_counter = 1
- #self.const_counter = 1
- #self.utility_code_used = []
- self.default_entries = []
- #self.string_to_entry = {}
- #self.intern_map = {}
- #self.interned_names = []
- #self.all_pystring_entries = []
-
- def lookup_here(self, name):
- entry = Scope.lookup_here(self, name)
- if not entry:
- entry = self.definition_scope.lookup_here(name)
- return entry
-
- def find_module(self, module_name, pos):
- return self.definition_scope.find_module(module_name, pos)
-
- def check_c_classes(self):
- self.definition_scope.check_c_classes()
- ModuleScope.check_c_classes(self)
-
-
-class LocalScope(Scope):
-
- def __init__(self, name, outer_scope):
- Scope.__init__(self, name, outer_scope, outer_scope)
-
- def mangle(self, prefix, name):
- return prefix + name
-
- def declare_arg(self, name, type, pos, readonly = 0):
- # Add an entry for an argument of a function.
- #print "LocalScope.declare_arg:", name, "readonly =", readonly ###
- cname = self.mangle(Naming.var_prefix, name)
- entry = self.declare(name, cname, type, pos)
- entry.is_variable = 1
- entry.is_readonly = readonly
- if type.is_pyobject:
- entry.init = "0"
- #entry.borrowed = 1 # Not using borrowed arg refs for now
- self.arg_entries.append(entry)
- return entry
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', is_cdef = 0):
- # Add an entry for a local variable.
- if visibility in ('public', 'readonly'):
- error(pos, "Local variable cannot be declared %s" % visibility)
- entry = Scope.declare_var(self, name, type, pos,
- cname, visibility, is_cdef)
- entry.init_to_none = type.is_pyobject
- self.var_entries.append(entry)
- return entry
-
- def declare_global(self, name, pos):
- # Pull entry from global scope into local scope.
- if self.lookup_here(name):
- error(pos, "'%s' already declared")
- else:
- entry = self.global_scope().lookup_target(name)
- self.entries[name] = entry
-
-
-class StructOrUnionScope(Scope):
- # Namespace of a C struct or union.
- #
- # cplus_constructors [CFuncType] C++ constructor signatures
-
- def __init__(self, is_cplus = False, base_scopes = []):
- Scope.__init__(self, "?", None, None)
- self.base_scopes = base_scopes
- self.is_cplus = is_cplus
- if is_cplus:
- constructors = []
- for base in base_scopes:
- constructors.extend(base.cplus_constructors)
- self.cplus_constructors = constructors
-
- def lookup_here(self, name):
- entry = Scope.lookup_here(self, name)
- if not entry:
- for base in self.base_scopes:
- entry = base.lookup_here(name)
- if entry:
- break
- return entry
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', **kwds):
- # Add an entry for an attribute.
- if not cname:
- cname = name
- entry = self.declare(name, cname, type, pos)
- entry.is_variable = 1
- self.var_entries.append(entry)
- if type.is_pyobject:
- error(pos,
- "C struct/union member cannot be a Python object")
- if visibility <> 'private':
- error(pos,
- "C struct/union member cannot be declared %s" % visibility)
- return entry
-
- def declare_cfunction(self, name, type, pos, **kwds):
- #print "StructOrUnionScope.declare_cfunction:", name ###
- if not self.is_cplus:
- error(pos, "C struct/union member cannot be a function")
- # Define it anyway to suppress further errors
- elif name == "__init__":
- type.pos = pos
- self.cplus_constructors.append(type)
- return
- #kwds['defining'] = 1
- #Scope.declare_cfunction(self, name, type, pos, *args, **kwds)
- self.declare_var(name, type, pos, **kwds)
-
-
-class ClassScope(Scope):
- # Abstract base class for namespace of
- # Python class or extension type.
- #
- # class_name string Pyrex name of the class
- # scope_prefix string Additional prefix for names
- # declared in the class
- # doc string or None Doc string
-
- def __init__(self, name, outer_scope):
- Scope.__init__(self, name, outer_scope, outer_scope)
- self.class_name = name
- self.doc = None
-
- def add_string_const(self, value):
- return self.outer_scope.add_string_const(value)
-
-
-class PyClassScope(ClassScope):
- # Namespace of a Python class.
- #
- # class_dict_cname string C variable holding class dict
- # class_obj_cname string C variable holding class object
-
- is_py_class_scope = 1
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', is_cdef = 0):
- # Add an entry for a class attribute.
- entry = Scope.declare_var(self, name, type, pos,
- cname, visibility, is_cdef)
- entry.is_pyglobal = 1
- entry.namespace_cname = self.class_obj_cname
- #if Options.intern_names:
- # entry.interned_cname = self.intern(name)
- return entry
-
- def allocate_temp(self, type):
- return self.outer_scope.allocate_temp(type)
-
- def release_temp(self, cname):
- self.outer_scope.release_temp(cname)
-
- #def recycle_pending_temps(self):
- # self.outer_scope.recycle_pending_temps()
-
- def add_default_value(self, type):
- return self.outer_scope.add_default_value(type)
-
-
-class CClassScope(ClassScope):
- # Namespace of an extension type.
- #
- # parent_type CClassType
- # #typeobj_cname string or None
- # #objstruct_cname string
- # method_table_cname string
- # member_table_cname string
- # getset_table_cname string
- # has_pyobject_attrs boolean Any PyObject attributes?
- # pyattr_entries [Entry]
- # public_attr_entries boolean public/readonly attrs
- # property_entries [Entry]
- # defined boolean Defined in .pxd file
- # implemented boolean Defined in .pyx file
- # inherited_var_entries [Entry] Adapted var entries from base class
- # no_gc boolean No GC even if there are Python attributes
-
- is_c_class_scope = 1
-
- def __init__(self, name, outer_scope, visibility, no_gc = 0):
- ClassScope.__init__(self, name, outer_scope)
- if visibility <> 'extern':
- self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
- self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
- self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
- self.has_pyobject_attrs = 0
- self.pyattr_entries = []
- self.public_attr_entries = []
- self.property_entries = []
- self.inherited_var_entries = []
- self.defined = 0
- self.implemented = 0
- self.no_gc = no_gc
-
- def needs_gc(self):
- # If the type or any of its base types have Python-valued
- # C attributes, then it needs to participate in GC.
- return self.has_pyobject_attrs or \
- (self.parent_type.base_type and \
- self.parent_type.base_type.scope.needs_gc())
-
- def declare_builtin_var(self, name, type, cname):
- entry = self.declare(name, cname or name, type, None)
- entry.is_variable = 1
- return entry
-
- def declare_var(self, name, type, pos,
- cname = None, visibility = 'private', is_cdef = 0):
- # Add an entry for an attribute.
- if self.defined:
- error(pos,
- "C attributes cannot be added in implementation part of"
- " extension type")
- if get_special_method_signature(name):
- error(pos,
- "The name '%s' is reserved for a special method."
- % name)
- if not cname:
- cname = name
- entry = self.declare(name, cname, type, pos)
- entry.visibility = visibility
- entry.is_variable = 1
- self.var_entries.append(entry)
- if type.is_pyobject and name <> "__weakref__":
- self.has_pyobject_attrs = 1
- self.pyattr_entries.append(entry)
- if visibility not in ('private', 'public', 'readonly'):
- error(pos,
- "Attribute of extension type cannot be declared %s" % visibility)
- if visibility in ('public', 'readonly'):
- if type.pymemberdef_typecode:
- self.public_attr_entries.append(entry)
- if name == "__weakref__":
- error(pos, "Special attribute __weakref__ cannot be exposed to Python")
- else:
- error(pos,
- "C attribute of type '%s' cannot be accessed from Python" % type)
- if visibility == 'public' and type.is_extension_type:
- error(pos,
- "Non-generic Python attribute cannot be exposed for writing from Python")
- return entry
-
- def declare_pyfunction(self, name, pos):
- # Add an entry for a method.
- if name == "__new__":
- error(pos, "__new__ method of extension type will change semantics "
- "in a future version of Pyrex. Use __cinit__ instead.")
- name = "__cinit__"
- entry = self.lookup_here(name)
- if entry and entry.is_builtin_method:
- self.overriding_builtin_method(name, pos)
- else:
- entry = self.declare(name, name, py_object_type, pos)
- special_sig = get_special_method_signature(name)
- if special_sig:
- entry.is_special = 1
- entry.signature = special_sig
- # Special methods don't get put in the method table
- else:
- entry.signature = pymethod_signature
- self.pyfunc_entries.append(entry)
- return entry
-
- def overriding_builtin_method(self, name, pos):
- error(pos, "Cannot override builtin method '%s' of class '%s'" % (
- name, self.parent_type.base_type.name))
-
- def lookup_here(self, name):
- if name == "__new__":
- name = "__cinit__"
- return ClassScope.lookup_here(self, name)
-
- def declare_builtin_method(self, name, type, cname):
- entry = ClassScope.add_cfunction(self, name, type, None, cname)
- entry.is_builtin_method = 1
- return entry
-
- def declare_cfunction(self, name, type, pos,
- cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
- if get_special_method_signature(name):
- error(pos, "Special methods must be declared with 'def', not 'cdef'")
- args = type.args
- if not args:
- error(pos, "C method has no self argument")
- elif not args[0].type.same_as(self.parent_type):
- error(pos, "Self argument of C method does not match parent type")
- entry = self.lookup_here(name)
- if entry:
- if not entry.is_cfunction:
- entry.redeclared(pos)
- elif entry.is_builtin_method:
- self.overriding_builtin_method(name, pos)
- else:
- if defining and entry.func_cname:
- error(pos, "'%s' already defined" % name)
- if not entry.type.same_as(type, as_cmethod = 1):
- error(pos, "Signature does not match previous declaration")
- error(entry.pos, "Previous declaration is here")
- else:
- if self.defined:
- error(pos,
- "C method '%s' not previously declared in definition part of"
- " extension type" % name)
- entry = self.add_cfunction(name, type, pos, cname or name, visibility)
- if defining:
- entry.func_cname = self.mangle(Naming.func_prefix, name)
- return entry
-
- def add_cfunction(self, name, type, pos, cname, visibility):
- # Add a cfunction entry without giving it a func_cname.
- entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility)
- entry.is_cmethod = 1
- return entry
-
- def declare_property(self, name, doc, pos):
- entry = self.declare(name, name, py_object_type, pos)
- entry.is_property = 1
- entry.doc = doc
- entry.scope = PropertyScope(name,
- outer_scope = self.global_scope(), parent_scope = self)
- entry.scope.parent_type = self.parent_type
- self.property_entries.append(entry)
- return entry
-
- def declare_inherited_c_attributes(self, base_scope):
- # Declare entries for all the C attributes of an
- # inherited type, with cnames modified appropriately
- # to work with this type.
- def adapt(cname):
- return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
- for base_entry in \
- base_scope.inherited_var_entries + base_scope.var_entries:
- entry = self.declare(base_entry.name, adapt(base_entry.cname),
- base_entry.type, None)
- entry.is_variable = 1
- self.inherited_var_entries.append(entry)
- for base_entry in base_scope.cfunc_entries:
- cname = base_entry.cname
- if base_entry.is_builtin_method:
- self.entries[base_entry.name] = base_entry
- else:
- entry = self.add_cfunction(base_entry.name, base_entry.type,
- base_entry.pos, adapt(base_entry.cname), base_entry.visibility)
- entry.is_inherited = 1
-
-
-class PropertyScope(Scope):
- # Scope holding the __get__, __set__ and __del__ methods for
- # a property of an extension type.
- #
- # parent_type PyExtensionType The type to which the property belongs
-
- def declare_pyfunction(self, name, pos):
- # Add an entry for a method.
- entry = self.declare(name, name, py_object_type, pos)
- signature = get_property_accessor_signature(name)
- if signature:
- entry.is_special = 1
- entry.signature = signature
- else:
- error(pos, "Only __get__, __set__ and __del__ methods allowed "
- "in a property declaration")
- entry.signature = pymethod_signature
- return entry
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py
deleted file mode 100644
index 9cb858e3..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py
+++ /dev/null
@@ -1,629 +0,0 @@
-#
-# Pyrex - Tables describing slots in the type object
-# and associated know-how.
-#
-
-import Naming
-import PyrexTypes
-
-class Signature:
- # Method slot signature descriptor.
- #
- # has_dummy_arg boolean
- # has_generic_args boolean
- # fixed_arg_format string
- # ret_format string
- # error_value string
- #
- # The formats are strings made up of the following
- # characters:
- #
- # 'O' Python object
- # 'T' Python object of the type of 'self'
- # 't' Python type object
- # 'v' void
- # 'p' void *
- # 'P' void **
- # 'i' int
- # 'I' int *
- # 'l' long
- # 'Z' Py_ssize_t
- # 's' char *
- # 'S' char **
- # 'r' int used only to signal exception
- # '-' dummy 'self' argument (not used)
- # '*' rest of args passed as generic Python
- # arg tuple and kw dict (must be last
- # char in format string)
-
- format_map = {
- 'O': PyrexTypes.py_object_type,
- 't': PyrexTypes.py_type_type,
- 'v': PyrexTypes.c_void_type,
- 'p': PyrexTypes.c_void_ptr_type,
- 'P': PyrexTypes.c_void_ptr_ptr_type,
- 'b': PyrexTypes.c_int_type, # boolean - no error value
- 'i': PyrexTypes.c_int_type,
- 'I': PyrexTypes.c_int_ptr_type,
- 'l': PyrexTypes.c_long_type,
- 'Z': PyrexTypes.c_py_ssize_t_type,
- 's': PyrexTypes.c_char_ptr_type,
- 'S': PyrexTypes.c_char_ptr_ptr_type,
- 'r': PyrexTypes.c_returncode_type,
- # 'T', '-' and '*' are handled otherwise
- # and are not looked up in here
- }
-
- error_value_map = {
- 'O': "0",
- 't': "0",
- 'i': "-1",
- 'l': "-1",
- 'r': "-1",
- 'Z': "-1",
- }
-
- def __init__(self, arg_format, ret_format):
- self.has_dummy_arg = 0
- self.has_generic_args = 0
- if arg_format[:1] == '-':
- self.has_dummy_arg = 1
- arg_format = arg_format[1:]
- if arg_format[-1:] == '*':
- self.has_generic_args = 1
- arg_format = arg_format[:-1]
- self.fixed_arg_format = arg_format
- self.ret_format = ret_format
- self.error_value = self.error_value_map.get(ret_format, None)
-
- def num_fixed_args(self):
- return len(self.fixed_arg_format)
-
- def is_self_arg(self, i):
- return self.fixed_arg_format[i] == 'T'
-
- def fixed_arg_type(self, i):
- return self.format_map[self.fixed_arg_format[i]]
-
- def return_type(self):
- return self.format_map[self.ret_format]
-
- def exception_value(self):
- return self.error_value_map.get(self.ret_format)
-
- def function_type(self, self_type = None):
- # Construct a C function type descriptor for this signature
- args = []
- #for i in xrange(self.num_fixed_args()):
- # arg_type = self.fixed_arg_type(i)
- for c in self.fixed_arg_format:
- if c == "T":
- assert self_type is not None
- arg_type = self_type
- else:
- arg_type = self.format_map[c]
- args.append(PyrexTypes.CFuncTypeArg("", arg_type, None))
- ret_type = self.return_type()
- exc_value = self.exception_value()
- return PyrexTypes.CFuncType(ret_type, args, exception_value = exc_value)
-
-
-class SlotDescriptor:
- # Abstract base class for type slot descriptors.
- #
- # slot_name string Member name of the slot in the type object
- # is_initialised_dynamically Is initialised by code in the module init function
- # flag Py_TPFLAGS_XXX value indicating presence of slot
-
- def __init__(self, slot_name, dynamic = 0, flag = None):
- self.slot_name = slot_name
- self.is_initialised_dynamically = dynamic
- self.flag = flag
-
- def generate(self, scope, code):
- if self.is_initialised_dynamically:
- value = 0
- else:
- value = self.slot_code(scope)
- flag = self.flag
- if flag:
- code.putln("#if Py_TPFLAGS_DEFAULT & %s" % flag)
- code.putln("%s, /*%s*/" % (value, self.slot_name))
- if flag:
- code.putln("#endif")
-
- # Some C implementations have trouble statically
- # initialising a global with a pointer to an extern
- # function, so we initialise some of the type slots
- # in the module init function instead.
-
- def generate_dynamic_init_code(self, scope, code):
- if self.is_initialised_dynamically:
- value = self.slot_code(scope)
- if value <> "0":
- code.putln("%s.%s = %s;" % (
- scope.parent_type.typeobj_cname,
- self.slot_name,
- value
- )
- )
-
-
-class FixedSlot(SlotDescriptor):
- # Descriptor for a type slot with a fixed value.
- #
- # value string
-
- def __init__(self, slot_name, value):
- SlotDescriptor.__init__(self, slot_name)
- self.value = value
-
- def slot_code(self, scope):
- return self.value
-
-
-class EmptySlot(FixedSlot):
- # Descriptor for a type slot whose value is always 0.
-
- def __init__(self, slot_name):
- FixedSlot.__init__(self, slot_name, "0")
-
-
-class GCDependentSlot(SlotDescriptor):
- # Descriptor for a slot whose value depends on whether
- # the type participates in GC.
-
- def __init__(self, slot_name, no_gc_value, gc_value, dynamic = 0):
- SlotDescriptor.__init__(self, slot_name, dynamic)
- self.no_gc_value = no_gc_value
- self.gc_value = gc_value
-
- def slot_code(self, scope):
- if scope.has_pyobject_attrs:
- return self.gc_value
- else:
- return self.no_gc_value
-
-
-class MethodSlot(SlotDescriptor):
- # Type slot descriptor for a user-definable method.
- #
- # signature Signature
- # method_name string The __xxx__ name of the method
- # default string or None Default value of the slot
-
- def __init__(self, signature, slot_name, method_name, default = None, flag = None):
- SlotDescriptor.__init__(self, slot_name, flag = flag)
- self.signature = signature
- self.slot_name = slot_name
- self.method_name = method_name
- self.default = default
- method_name_to_slot[method_name] = self
-
- def slot_code(self, scope):
- entry = scope.lookup_here(self.method_name)
- if entry:
- return entry.func_cname
- else:
- return "0"
-
-
-class InternalMethodSlot(SlotDescriptor):
- # Type slot descriptor for a method which is always
- # synthesized by Pyrex.
- #
- # slot_name string Member name of the slot in the type object
-
- def __init__(self, slot_name):
- SlotDescriptor.__init__(self, slot_name)
-
- def slot_code(self, scope):
- return scope.mangle_internal(self.slot_name)
-
-
-class PyAttrDependentSlot(InternalMethodSlot):
- # Type slot for a method that is synthesized only
- # when the extension type has Python-valued attributes.
-
- def slot_code(self, scope):
- if scope.pyattr_entries:
- return InternalMethodSlot.slot_code(self, scope)
- else:
- return "0"
-
-
-class SyntheticSlot(InternalMethodSlot):
- # Type slot descriptor for a synthesized method which
- # dispatches to one or more user-defined methods depending
- # on its arguments. If none of the relevant methods are
- # defined, the method will not be synthesized and an
- # alternative default value will be placed in the type
- # slot.
-
- def __init__(self, slot_name, user_methods, default_value):
- InternalMethodSlot.__init__(self, slot_name)
- self.user_methods = user_methods
- self.default_value = default_value
-
- def slot_code(self, scope):
- if scope.defines_any(self.user_methods):
- return InternalMethodSlot.slot_code(self, scope)
- else:
- return self.default_value
-
-
-class TypeFlagsSlot(SlotDescriptor):
- # Descriptor for the type flags slot.
-
- def slot_code(self, scope):
- value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE"
- if scope.pyattr_entries and not scope.no_gc:
- value += "|Py_TPFLAGS_HAVE_GC"
- return value
-
-
-class DocStringSlot(SlotDescriptor):
- # Descriptor for the docstring slot.
-
- def slot_code(self, scope):
- if scope.doc is not None:
- return '"%s"' % scope.doc
- else:
- return "0"
-
-
-class SuiteSlot(SlotDescriptor):
- # Descriptor for a substructure of the type object.
- #
- # sub_slots [SlotDescriptor]
-
- def __init__(self, sub_slots, slot_type, slot_name):
- SlotDescriptor.__init__(self, slot_name)
- self.sub_slots = sub_slots
- self.slot_type = slot_type
- substructures.append(self)
-
- def substructure_cname(self, scope):
- return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
-
- def slot_code(self, scope):
- return "&%s" % self.substructure_cname(scope)
-
- def generate_substructure(self, scope, code):
- code.putln("")
- code.putln(
- "static %s %s = {" % (
- self.slot_type,
- self.substructure_cname(scope)))
- for slot in self.sub_slots:
- slot.generate(scope, code)
- code.putln("};")
-
-substructures = [] # List of all SuiteSlot instances
-
-class MethodTableSlot(SlotDescriptor):
- # Slot descriptor for the method table.
-
- def slot_code(self, scope):
- return scope.method_table_cname
-
-
-class MemberTableSlot(SlotDescriptor):
- # Slot descriptor for the table of Python-accessible attributes.
-
- def slot_code(self, scope):
- if scope.public_attr_entries:
- return scope.member_table_cname
- else:
- return "0"
-
-
-class GetSetSlot(SlotDescriptor):
- # Slot descriptor for the table of attribute get & set methods.
-
- def slot_code(self, scope):
- if scope.property_entries:
- return scope.getset_table_cname
- else:
- return "0"
-
-
-class BaseClassSlot(SlotDescriptor):
- # Slot descriptor for the base class slot.
-
- def __init__(self, name):
- SlotDescriptor.__init__(self, name, dynamic = 1)
-
- def generate_dynamic_init_code(self, scope, code):
- base_type = scope.parent_type.base_type
- if base_type:
- code.putln("%s.%s = %s;" % (
- scope.parent_type.typeobj_cname,
- self.slot_name,
- base_type.typeptr_cname))
-
-
-# The following dictionary maps __xxx__ method names to slot descriptors.
-
-method_name_to_slot = {}
-
-## The following slots are (or could be) initialised with an
-## extern function pointer.
-#
-#slots_initialised_from_extern = (
-# "tp_free",
-#)
-
-#------------------------------------------------------------------------------------------
-#
-# Utility functions for accessing slot table data structures
-#
-#------------------------------------------------------------------------------------------
-
-def get_special_method_signature(name):
- # Given a method name, if it is a special method,
- # return its signature, else return None.
- slot = method_name_to_slot.get(name)
- if slot:
- return slot.signature
- else:
- return None
-
-def get_property_accessor_signature(name):
- # Return signature of accessor for an extension type
- # property, else None.
- return property_accessor_signatures.get(name)
-
-#------------------------------------------------------------------------------------------
-#
-# Signatures for generic Python functions and methods.
-#
-#------------------------------------------------------------------------------------------
-
-pyfunction_signature = Signature("-*", "O")
-pymethod_signature = Signature("T*", "O")
-
-#------------------------------------------------------------------------------------------
-#
-# Signatures for the various kinds of function that
-# can appear in the type object and its substructures.
-#
-#------------------------------------------------------------------------------------------
-
-unaryfunc = Signature("T", "O") # typedef PyObject * (*unaryfunc)(PyObject *);
-binaryfunc = Signature("OO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
-ibinaryfunc = Signature("TO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
-ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
-iternaryfunc = Signature("TOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
-callfunc = Signature("T*", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
-inquiry = Signature("T", "i") # typedef int (*inquiry)(PyObject *);
-lenfunc = Signature("T", "Z") # typedef Py_ssize_t (*lenfunc)(PyObject *);
- # typedef int (*coercion)(PyObject **, PyObject **);
-intargfunc = Signature("Ti", "O") # typedef PyObject *(*intargfunc)(PyObject *, int);
-ssizeargfunc = Signature("TZ", "O") # typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
-intintargfunc = Signature("Tii", "O") # typedef PyObject *(*intintargfunc)(PyObject *, int, int);
-ssizessizeargfunc = Signature("TZZ", "O") # typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
-intobjargproc = Signature("TiO", 'r') # typedef int(*intobjargproc)(PyObject *, int, PyObject *);
-ssizeobjargproc = Signature("TZO", 'r') # typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
-intintobjargproc = Signature("TiiO", 'r') # typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
-ssizessizeobjargproc = Signature("TZZO", 'r') # typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
-intintargproc = Signature("Tii", 'r')
-ssizessizeargproc = Signature("TZZ", 'r')
-objargfunc = Signature("TO", "O")
-objobjargproc = Signature("TOO", 'r') # typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
-getreadbufferproc = Signature("TiP", 'i') # typedef int (*getreadbufferproc)(PyObject *, int, void **);
-getwritebufferproc = Signature("TiP", 'i') # typedef int (*getwritebufferproc)(PyObject *, int, void **);
-getsegcountproc = Signature("TI", 'i') # typedef int (*getsegcountproc)(PyObject *, int *);
-getcharbufferproc = Signature("TiS", 'i') # typedef int (*getcharbufferproc)(PyObject *, int, const char **);
-readbufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
-writebufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
-segcountproc = Signature("TZ", "Z") # typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
-writebufferproc = Signature("TZS", "Z") # typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
-objargproc = Signature("TO", 'r') # typedef int (*objobjproc)(PyObject *, PyObject *);
- # typedef int (*visitproc)(PyObject *, void *);
- # typedef int (*traverseproc)(PyObject *, visitproc, void *);
-
-destructor = Signature("T", "v") # typedef void (*destructor)(PyObject *);
-# printfunc = Signature("TFi", 'r') # typedef int (*printfunc)(PyObject *, FILE *, int);
- # typedef PyObject *(*getattrfunc)(PyObject *, char *);
-getattrofunc = Signature("TO", "O") # typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
- # typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
-setattrofunc = Signature("TOO", 'r') # typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
-delattrofunc = Signature("TO", 'r')
-cmpfunc = Signature("TO", "i") # typedef int (*cmpfunc)(PyObject *, PyObject *);
-reprfunc = Signature("T", "O") # typedef PyObject *(*reprfunc)(PyObject *);
-hashfunc = Signature("T", "l") # typedef long (*hashfunc)(PyObject *);
- # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
-richcmpfunc = Signature("OOi", "O") # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
-getiterfunc = Signature("T", "O") # typedef PyObject *(*getiterfunc) (PyObject *);
-iternextfunc = Signature("T", "O") # typedef PyObject *(*iternextfunc) (PyObject *);
-descrgetfunc = Signature("TOO", "O") # typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
-descrsetfunc = Signature("TOO", 'r') # typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
-descrdelfunc = Signature("TO", 'r')
-initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
- # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
- # typedef PyObject *(*allocfunc)(struct _typeobject *, int);
-
-#------------------------------------------------------------------------------------------
-#
-# Signatures for accessor methods of properties.
-#
-#------------------------------------------------------------------------------------------
-
-property_accessor_signatures = {
- '__get__': Signature("T", "O"),
- '__set__': Signature("TO", 'r'),
- '__del__': Signature("T", 'r')
-}
-
-#------------------------------------------------------------------------------------------
-#
-# Descriptor tables for the slots of the various type object
-# substructures, in the order they appear in the structure.
-#
-#------------------------------------------------------------------------------------------
-
-PyNumberMethods = (
- MethodSlot(binaryfunc, "nb_add", "__add__"),
- MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
- MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
- MethodSlot(binaryfunc, "nb_divide", "__div__"),
- MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
- MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
- MethodSlot(ternaryfunc, "nb_power", "__pow__"),
- MethodSlot(unaryfunc, "nb_negative", "__neg__"),
- MethodSlot(unaryfunc, "nb_positive", "__pos__"),
- MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
- MethodSlot(inquiry, "nb_nonzero", "__nonzero__"),
- MethodSlot(unaryfunc, "nb_invert", "__invert__"),
- MethodSlot(binaryfunc, "nb_lshift", "__lshift__"),
- MethodSlot(binaryfunc, "nb_rshift", "__rshift__"),
- MethodSlot(binaryfunc, "nb_and", "__and__"),
- MethodSlot(binaryfunc, "nb_xor", "__xor__"),
- MethodSlot(binaryfunc, "nb_or", "__or__"),
- EmptySlot("nb_coerce"),
- MethodSlot(unaryfunc, "nb_int", "__int__"),
- MethodSlot(unaryfunc, "nb_long", "__long__"),
- MethodSlot(unaryfunc, "nb_float", "__float__"),
- MethodSlot(unaryfunc, "nb_oct", "__oct__"),
- MethodSlot(unaryfunc, "nb_hex", "__hex__"),
-
- # Added in release 2.0
- MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
- MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
- MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
- MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__"),
- MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
- MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
- MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
- MethodSlot(ibinaryfunc, "nb_inplace_rshift", "__irshift__"),
- MethodSlot(ibinaryfunc, "nb_inplace_and", "__iand__"),
- MethodSlot(ibinaryfunc, "nb_inplace_xor", "__ixor__"),
- MethodSlot(ibinaryfunc, "nb_inplace_or", "__ior__"),
-
- # Added in release 2.2
- # The following require the Py_TPFLAGS_HAVE_CLASS flag
- MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"),
- MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"),
- MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"),
- MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
- MethodSlot(unaryfunc, "nb_index", "__index__", flag = "Py_TPFLAGS_HAVE_INDEX")
-)
-
-PySequenceMethods = (
- MethodSlot(lenfunc, "sq_length", "__len__"),
- EmptySlot("sq_concat"), # nb_add used instead
- EmptySlot("sq_repeat"), # nb_multiply used instead
- SyntheticSlot("sq_item", ["__getitem__"], "0"), #EmptySlot("sq_item"), # mp_subscript used instead
- MethodSlot(ssizessizeargfunc, "sq_slice", "__getslice__"),
- EmptySlot("sq_ass_item"), # mp_ass_subscript used instead
- SyntheticSlot("sq_ass_slice", ["__setslice__", "__delslice__"], "0"),
- MethodSlot(cmpfunc, "sq_contains", "__contains__"),
- EmptySlot("sq_inplace_concat"), # nb_inplace_add used instead
- EmptySlot("sq_inplace_repeat"), # nb_inplace_multiply used instead
-)
-
-PyMappingMethods = (
- MethodSlot(lenfunc, "mp_length", "__len__"),
- MethodSlot(objargfunc, "mp_subscript", "__getitem__"),
- SyntheticSlot("mp_ass_subscript", ["__setitem__", "__delitem__"], "0"),
-)
-
-PyBufferProcs = (
- MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__"),
- MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__"),
- MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__"),
- MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__"),
-)
-
-#------------------------------------------------------------------------------------------
-#
-# The main slot table. This table contains descriptors for all the
-# top-level type slots, beginning with tp_dealloc, in the order they
-# appear in the type object.
-#
-#------------------------------------------------------------------------------------------
-
-slot_table = (
- InternalMethodSlot("tp_dealloc"),
- EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"),
- EmptySlot("tp_getattr"),
- EmptySlot("tp_setattr"),
- MethodSlot(cmpfunc, "tp_compare", "__cmp__"),
- MethodSlot(reprfunc, "tp_repr", "__repr__"),
-
- SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"),
- SuiteSlot(PySequenceMethods, "PySequenceMethods", "tp_as_sequence"),
- SuiteSlot(PyMappingMethods, "PyMappingMethods", "tp_as_mapping"),
-
- MethodSlot(hashfunc, "tp_hash", "__hash__"),
- MethodSlot(callfunc, "tp_call", "__call__"),
- MethodSlot(reprfunc, "tp_str", "__str__"),
-
- SyntheticSlot("tp_getattro", ["__getattr__"], "0"), #"PyObject_GenericGetAttr"),
- SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"),
-
- SuiteSlot(PyBufferProcs, "PyBufferProcs", "tp_as_buffer"),
-
- TypeFlagsSlot("tp_flags"),
- DocStringSlot("tp_doc"),
-
- PyAttrDependentSlot("tp_traverse"),
- PyAttrDependentSlot("tp_clear"),
-
- # Later -- synthesize a method to split into separate ops?
- MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"),
-
- EmptySlot("tp_weaklistoffset"),
-
- MethodSlot(getiterfunc, "tp_iter", "__iter__"),
- MethodSlot(iternextfunc, "tp_iternext", "__next__"),
-
- MethodTableSlot("tp_methods"),
- MemberTableSlot("tp_members"),
- GetSetSlot("tp_getset"),
-
- BaseClassSlot("tp_base"), #EmptySlot("tp_base"),
- EmptySlot("tp_dict"),
-
- SyntheticSlot("tp_descr_get", ["__get__"], "0"),
- SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"),
-
- EmptySlot("tp_dictoffset"),
-
- MethodSlot(initproc, "tp_init", "__init__"),
- EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
- InternalMethodSlot("tp_new"),
- # Some versions of Python 2.2 inherit the wrong value for tp_free when the
- # type has GC but the base type doesn't, so we explicitly set it ourselves
- # in that case.
- GCDependentSlot("tp_free", "0", "_PyObject_GC_Del", dynamic = 1),
-
- EmptySlot("tp_is_gc"),
- EmptySlot("tp_bases"),
- EmptySlot("tp_mro"),
- EmptySlot("tp_cache"),
- EmptySlot("tp_subclasses"),
- EmptySlot("tp_weaklist"),
-)
-
-#------------------------------------------------------------------------------------------
-#
-# Descriptors for special methods which don't appear directly
-# in the type object or its substructures. These methods are
-# called from slot functions synthesized by Pyrex.
-#
-#------------------------------------------------------------------------------------------
-
-MethodSlot(initproc, "", "__cinit__")
-MethodSlot(destructor, "", "__dealloc__")
-MethodSlot(objobjargproc, "", "__setitem__")
-MethodSlot(objargproc, "", "__delitem__")
-MethodSlot(ssizessizeobjargproc, "", "__setslice__")
-MethodSlot(ssizessizeargproc, "", "__delslice__")
-MethodSlot(getattrofunc, "", "__getattr__")
-MethodSlot(setattrofunc, "", "__setattr__")
-MethodSlot(delattrofunc, "", "__delattr__")
-MethodSlot(descrgetfunc, "", "__get__")
-MethodSlot(descrsetfunc, "", "__set__")
-MethodSlot(descrdelfunc, "", "__delete__")
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py
deleted file mode 100644
index 3f085698..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py
+++ /dev/null
@@ -1 +0,0 @@
-version = '0.9.9'
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py
+++ /dev/null