summaryrefslogtreecommitdiffstats
path: root/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2021-03-26 13:52:33 +0100
committerSlávek Banko <slavek.banko@axis.cz>2021-03-26 13:52:33 +0100
commit0f27805eedcc40ae34009aa31a4dc08cb949f867 (patch)
tree8b1c8995d7fdab97acde4bd7c63f96d378c34d02 /debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
parentbad411472a12b93f8bfca6b7ca52d89488a8d8ce (diff)
downloadextra-dependencies-0f27805eedcc40ae34009aa31a4dc08cb949f867.tar.gz
extra-dependencies-0f27805eedcc40ae34009aa31a4dc08cb949f867.zip
DEB pyrex: Added to repository.
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py')
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py546
1 files changed, 546 insertions, 0 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
new file mode 100644
index 00000000..a47692bb
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
@@ -0,0 +1,546 @@
+##########################################################################
+#
+# 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
+