Started piping variable declarations through code.globalstate, pxd code compiles
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 1 Aug 2008 21:33:52 +0000 (23:33 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Fri, 1 Aug 2008 21:33:52 +0000 (23:33 +0200)
Cython/Compiler/Code.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Symtab.py
Cython/Includes/numpy.pxd

index d1373f65c7d957129d6a07c88061460e0c101d94..684e419dd6aaeb57a88fc7ab471d8f229aeec4c7 100644 (file)
@@ -137,15 +137,81 @@ class GlobalState(object):
     # input_file_contents dict         contents (=list of lines) of any file that was used as input
     #                                  to create this output C code.  This is
     #                                  used to annotate the comments.
+    #
     # used_utility_code set(string|int) Ids of used utility code (to avoid reinsertion)
     # utilprotowriter CCodeWriter
     # utildefwriter   CCodeWriter
+    #
+    # declared_cnames  {string:Entry}  used in a transition phase to merge pxd-declared
+    #                                  constants etc. into the pyx-declared ones (i.e,
+    #                                  check if constants are already added).
+    #                                  In time, hopefully the literals etc. will be
+    #                                  supplied directly instead.
 
-    def __init__(self):
+    
+    # interned_strings
+    # consts
+    # py_string_decls
+    # interned_nums
+    # cached_builtins
+
+    def __init__(self, rootwriter):
         self.filename_table = {}
         self.filename_list = []
         self.input_file_contents = {}
         self.used_utility_code = set()
+        self.declared_cnames = {}
+
+    def initwriters(self, rootwriter):
+        self.utilprotowriter = rootwriter.new_writer()
+        self.utildefwriter = rootwriter.new_writer()
+        self.decls_writer = rootwriter.new_writer()
+
+    #
+    # Global constants, interned objects, etc.
+    #
+    def insert_global_var_declarations_into(self, code):
+        code.insert(self.decls_writer)
+
+    # The functions below are there in a transition phase only
+    # and will be deprecated. They are called from Nodes.BlockNode.
+    # The copy&paste duplication is intentional in order to be able
+    # to see quickly how BlockNode worked, until this is replaced.
+    def should_declare(self, cname, entry):
+        if cname in self.declared_cnames:
+            other = self.declared_cnames[cname]
+            assert entry.type == other.type
+            assert entry.init == other.init
+            return False
+        else:
+            self.declared_cnames[cname] = entry
+            return True
+
+    def add_const_definition(self, entry):
+        if self.should_declare(entry.cname, entry):
+            self.decls_writer.put_var_declaration(entry, static = 1)
+
+    def add_interned_string_decl(self, entry):
+        if self.should_declare(entry.cname, entry):
+            self.decls_writer.put_var_declaration(entry, static = 1)
+        if self.should_declare(entry.pystring_cname, entry):
+            self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname)
+
+    def add_py_string_decl(self, entry):
+        if self.should_declare(entry.pystring_cname, entry):
+            self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname)
+        
+    def add_interned_num_decl(self, entry):
+        if self.should_declare(entry.cname, entry):
+            self.decls_writer.putln("static PyObject *%s;" % entry.cname)
+
+    def add_cached_builtin_decl(self, entry):
+        if self.should_declare(entry.cname, entry):
+            self.decls_writer.putln("static PyObject *%s;" % entry.cname)
+
+    #
+    # File name state
+    #
 
     def lookup_filename(self, filename):
         try:
@@ -164,9 +230,14 @@ class GlobalState(object):
                     u'*/', u'*[inserted by cython to avoid comment closer]/'
                     ).encode('ASCII', 'replace') # + Py2 auto-decode to unicode
                  for line in source_desc.get_lines()]
+            if len(F) == 0: F.append(u'')
             self.input_file_contents[source_desc] = F
             return F
 
+    #
+    # Utility code state
+    #
+    
     def use_utility_code(self, codetup, name=None):
         """
         Adds the given utility code to the C file if needed.
@@ -266,11 +337,9 @@ class CCodeWriter(object):
         self.bol = 1
         if create_from is None:
             # Root CCodeWriter
-            self.globalstate = GlobalState()
-            # These needs to be constructed after all state is set, as
-            # the construction copies over the state
-            self.globalstate.utilprotowriter = self.new_writer()
-            self.globalstate.utildefwriter = self.new_writer()
+            self.globalstate = GlobalState(self)
+            self.globalstate.initwriters(self)
+            # ^^^ need seperate step because this will reference self.globalstate
         else:
             # Use same global state
             self.globalstate = create_from.globalstate
@@ -400,7 +469,6 @@ class CCodeWriter(object):
             return
         assert isinstance(source_desc, SourceDescriptor)
         contents = self.globalstate.commented_file_contents(source_desc)
-
         lines = contents[max(0,line-3):line] # line numbers start at 1
         lines[-1] += u'             # <<<<<<<<<<<<<<'
         lines += contents[line:line+2]
index 3cb98283bb4fcd02563e94aab697c3a840b4f945..a08e102adf3e0b1d714330ce7cfbcf2f06f62bbc 100644 (file)
@@ -248,6 +248,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         self.generate_interned_num_decls(env, code)
         self.generate_interned_string_decls(env, code)
         self.generate_py_string_decls(env, code)
+
+        code.globalstate.insert_global_var_declarations_into(code)
+        
         self.generate_cached_builtins_decls(env, code)
         self.body.generate_function_definitions(env, code, options.transforms)
         code.mark_pos(None)
@@ -1447,6 +1450,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 "};")
 
     def generate_py_string_table(self, env, code):
+#        raise Exception()
         entries = env.all_pystring_entries
         if entries:
             code.putln("")
index 204962c8b6b4b44ef7c04f5d51c739343b9719b0..92d74e1b75bd148aed5d6353bce670fe15408a82 100644 (file)
@@ -199,21 +199,15 @@ class BlockNode:
 
     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)
+                    code.globalstate.add_const_definition(entry)
 
     def generate_interned_string_decls(self, env, code):
         entries = env.global_scope().new_interned_string_entries
         if entries:
-            code.putln("")
             for entry in entries:
-                code.put_var_declaration(entry, static = 1)
-            code.putln("")
-            for entry in entries:
-                code.putln(
-                    "static PyObject *%s;" % entry.pystring_cname)
+                code.globalstate.add_interned_string_decl(entry)
             del entries[:]
 
     def generate_py_string_decls(self, env, code):
@@ -221,11 +215,9 @@ class BlockNode:
             return # earlier error
         entries = env.pystring_entries
         if entries:
-            code.putln("")
             for entry in entries:
                 if not entry.is_interned:
-                    code.putln(
-                        "static PyObject *%s;" % entry.pystring_cname)
+                    code.globalstate.add_py_string_decl(entry)
 
     def generate_interned_num_decls(self, env, code):
         #  Flush accumulated interned nums from the global scope
@@ -233,18 +225,14 @@ class BlockNode:
         genv = env.global_scope()
         entries = genv.interned_nums
         if entries:
-            code.putln("")
             for entry in entries:
-                code.putln(
-                    "static PyObject *%s;" % entry.cname)
+                code.globalstate.add_interned_num_decl(entry)
             del entries[:]
 
     def generate_cached_builtins_decls(self, env, code):
         entries = env.global_scope().undeclared_cached_builtins
-        if len(entries) > 0:
-            code.putln("")
         for entry in entries:
-            code.putln("static PyObject *%s;" % entry.cname)
+            code.globalstate.add_cached_builtin_decl(entry)
         del entries[:]
         
 
index eb5dbbc504672c100f4c53fb61039982c8b00bb0..075c05176af30e55c9a823af9e97129f0a880ada 100644 (file)
@@ -732,6 +732,8 @@ class BuiltinScope(Scope):
         "True":   ["Py_True", py_object_type],
     }
 
+const_counter = 1 # As a temporary solution for compiling code in pxds
+
 class ModuleScope(Scope):
     # module_name          string             Python name of the module
     # module_cname         string             C name of Python module object
@@ -739,7 +741,7 @@ class ModuleScope(Scope):
     # method_table_cname   string             C name of method table
     # doc                  string             Module doc string
     # doc_cname            string             C name of module doc string
-    # const_counter        integer            Counter for naming constants
+    # const_counter        integer            Counter for naming constants (PS: MOVED TO GLOBAL)
     # utility_code_list    [((string, string), string)] Queuing utility codes for forwarding to Code.py
     # default_entries      [Entry]            Function argument default entries
     # python_include_files [string]           Standard  Python headers to be included
@@ -773,7 +775,6 @@ class ModuleScope(Scope):
         self.method_table_cname = Naming.methtable_cname
         self.doc = ""
         self.doc_cname = Naming.moddoc_cname
-        self.const_counter = 1
         self.utility_code_list = []
         self.default_entries = []
         self.module_entries = {}
@@ -927,10 +928,11 @@ class ModuleScope(Scope):
         return entry
         
     def new_const_cname(self):
+        global const_counter
         # Create a new globally-unique name for a constant.
         prefix=''
-        n = self.const_counter
-        self.const_counter = n + 1
+        n = const_counter
+        const_counter = n + 1
         return "%s%s%d" % (Naming.const_prefix, prefix, n)
     
     def use_utility_code(self, new_code, name=None):
index 5a9db9cda1fd9412b0a1c209be213ef3e8fa80ec..f22806fe73f59729c685e2b32735fb3bbd8f8a02 100644 (file)
@@ -17,7 +17,7 @@ cdef extern from "numpy/arrayobject.h":
             object weakreflist
 
         def __getbuffer__(self, Py_buffer* info, int flags):
-       
+            print "hello" + str(43) + "asdf" + "three"
             pass