- def add_string_const(self, value, identifier = False):
- # Add an entry for a string constant.
- if identifier:
- cname = self.new_string_const_cname(value)
- else:
- cname = self.new_const_cname()
- if value.is_unicode:
- c_type = PyrexTypes.c_utf8_char_array_type
- value = value.utf8encode()
- else:
- c_type = PyrexTypes.c_char_array_type
- value = value.byteencode()
- entry = Entry("", cname, c_type, init = value)
- entry.used = 1
- self.const_entries.append(entry)
- return entry
-
- def get_string_const(self, value, identifier = False):
- # Get entry for string constant. Returns an existing
- # one if possible, otherwise creates a new one.
- genv = self.global_scope()
- if identifier:
- string_map = genv.identifier_to_entry
- else:
- string_map = genv.string_to_entry
- entry = string_map.get(value)
- if not entry:
- entry = self.add_string_const(value, identifier)
- entry.is_identifier = identifier
- string_map[value] = entry
- return entry
-
- def add_py_string(self, entry, identifier = None):
- # 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 entry.pystring_cname:
- return
- value = entry.init
- entry.pystring_cname = Naming.py_const_prefix + entry.cname[len(Naming.const_prefix):]
- self.pystring_entries.append(entry)
- self.global_scope().all_pystring_entries.append(entry)
- if identifier or (identifier is None and possible_identifier(value)):
- entry.is_interned = 1
- self.global_scope().new_interned_string_entries.append(entry)
-
- def add_py_num(self, value):
- # Add an entry for an int constant.
- cname = "%s%s" % (Naming.interned_num_prefix, value)
- cname = cname.replace('-', 'neg_').replace('.','_')
- entry = Entry("", cname, py_object_type, init = value)
- entry.used = 1
- entry.is_interned = 1
- self.const_entries.append(entry)
- self.interned_nums.append(entry)
- return entry
-
- def get_py_num(self, value, longness):
- # Get entry for int constant. Returns an existing
- # one if possible, otherwise creates a new one.
- if longness or Utils.long_literal(value):
- value += "L"
- genv = self.global_scope()
- entry = genv.num_to_entry.get(value)
- if not entry:
- entry = genv.add_py_num(value)
- genv.num_to_entry[value] = entry
- genv.pynum_entries.append(entry)
- return entry
-
- def get_py_obj(self, obj, c_prefix=''):
- # Get entry for a generic constant. Returns an existing
- # one if possible, otherwise creates a new one.
- genv = self.global_scope()
- entry = genv.obj_to_entry.get(obj)
- if not entry:
- entry = genv.add_py_num(obj, c_prefix)
- genv.obj_to_entry[obj] = entry
- return entry
-
- def new_string_const_cname(self, value):
- # Create a new globally-unique nice name for a string constant.
- if len(value) < 20 and nice_identifier(value):
- return "%s%s" % (Naming.const_prefix, value)
- else:
- return self.global_scope().new_const_cname()
-
- 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" % (self.temp_prefix, n)
- entry = Entry("", cname, type)
- entry.used = 1
- if type.is_pyobject or type == PyrexTypes.c_py_ssize_t_type:
- 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, name=None):
- self.global_scope().use_utility_code(new_code, name)