cython-devel

changeset 2226:fa120664cec4

fix compile time constants in array size declarations (e.g. int a[enum_val+1])
author Stefan Behnel <scoder@users.berlios.de>
date Fri Apr 10 21:21:02 2009 +0200 (4 years ago)
parents a8780285a470
children 7d847f9b2c4a
files Cython/Compiler/ExprNodes.py Cython/Compiler/Nodes.py
line diff
1.1 --- a/Cython/Compiler/ExprNodes.py Fri Apr 10 20:50:48 2009 +0200 1.2 +++ b/Cython/Compiler/ExprNodes.py Fri Apr 10 21:21:02 2009 +0200 1.3 @@ -230,15 +230,23 @@ 1.4 # C type of the result_code expression). 1.5 return self.result_ctype or self.type 1.6 1.7 - def get_constant_result_code(self): 1.8 + def get_constant_c_result_code(self): 1.9 # Return the constant value of this node as a result code 1.10 - # string, or None if the node is not constant. 1.11 - return None 1.12 - 1.13 - def calculate_constant_result(self): 1.14 - # Calculate the constant result of this expression and store 1.15 - # it in ``self.constant_result``. Does nothing by default, 1.16 - # thus leaving ``self.constant_result`` unknown. 1.17 + # string, or None if the node is not constant. This method 1.18 + # can be called when the constant result code is required 1.19 + # before the code generation phase. 1.20 + # 1.21 + # The return value is a string that can represent a simple C 1.22 + # value, a constant C name or a constant C expression. If the 1.23 + # node type depends on Python code, this must return None. 1.24 + return None 1.25 + 1.26 + def calculate_constant_result(self): 1.27 + # Calculate the constant compile time result value of this 1.28 + # expression and store it in ``self.constant_result``. Does 1.29 + # nothing by default, thus leaving ``self.constant_result`` 1.30 + # unknown. If valid, the result can be an arbitrary Python 1.31 + # value. 1.32 # 1.33 # This must only be called when it is assured that all 1.34 # sub-expressions have a valid constant_result value. The 1.35 @@ -619,7 +627,7 @@ 1.36 def check_const(self): 1.37 pass 1.38 1.39 - def get_constant_result_code(self): 1.40 + def get_constant_c_result_code(self): 1.41 return self.calculate_result_code() 1.42 1.43 def calculate_result_code(self): 1.44 @@ -648,7 +656,7 @@ 1.45 value = "NULL" 1.46 constant_result = 0 1.47 1.48 - def get_constant_result_code(self): 1.49 + def get_constant_c_result_code(self): 1.50 return self.value 1.51 1.52 1.53 @@ -695,9 +703,9 @@ 1.54 if self.type.is_pyobject: 1.55 self.result_code = code.get_py_num(self.value, self.longness) 1.56 else: 1.57 - self.result_code = self.get_constant_result_code() 1.58 - 1.59 - def get_constant_result_code(self): 1.60 + self.result_code = self.get_constant_c_result_code() 1.61 + 1.62 + def get_constant_c_result_code(self): 1.63 return str(self.value) + self.unsigned + self.longness 1.64 1.65 def calculate_result_code(self): 1.66 @@ -784,7 +792,7 @@ 1.67 else: 1.68 self.result_code = code.get_string_const(self.value) 1.69 1.70 - def get_constant_result_code(self): 1.71 + def get_constant_c_result_code(self): 1.72 return None # FIXME 1.73 1.74 def calculate_result_code(self): 1.75 @@ -825,7 +833,7 @@ 1.76 else: 1.77 self.result_code = code.get_string_const(self.value) 1.78 1.79 - def get_constant_result_code(self): 1.80 + def get_constant_c_result_code(self): 1.81 return None 1.82 1.83 def calculate_result_code(self): 1.84 @@ -915,6 +923,11 @@ 1.85 return denv.lookup(self.name) 1.86 except KeyError: 1.87 error(self.pos, "Compile-time name '%s' not defined" % self.name) 1.88 + 1.89 + def get_constant_c_result_code(self): 1.90 + if not self.entry or self.entry.type.is_pyobject: 1.91 + return None 1.92 + return self.entry.cname 1.93 1.94 def coerce_to(self, dst_type, env): 1.95 # If coercing to a generic pyobject and this is a builtin 1.96 @@ -4164,6 +4177,14 @@ 1.97 return PyrexTypes.widest_numeric_type(type1, type2) 1.98 else: 1.99 return None 1.100 + 1.101 + def get_constant_c_result_code(self): 1.102 + value1 = self.operand1.get_constant_c_result_code() 1.103 + value2 = self.operand2.get_constant_c_result_code() 1.104 + if value1 and value2: 1.105 + return "(%s %s %s)" % (value1, self.operator, value2) 1.106 + else: 1.107 + return None 1.108 1.109 def c_types_okay(self, type1, type2): 1.110 #print "NumBinopNode.c_types_okay:", type1, type2 ###
2.1 --- a/Cython/Compiler/Nodes.py Fri Apr 10 20:50:48 2009 +0200 2.2 +++ b/Cython/Compiler/Nodes.py Fri Apr 10 21:21:02 2009 +0200 2.3 @@ -455,12 +455,13 @@ 2.4 self.dimension.analyse_const_expression(env) 2.5 if not self.dimension.type.is_int: 2.6 error(self.dimension.pos, "Array dimension not integer") 2.7 - size = self.dimension.get_constant_result_code() 2.8 - try: 2.9 - size = int(size) 2.10 - except (ValueError, TypeError): 2.11 - # runtime constant? 2.12 - pass 2.13 + size = self.dimension.get_constant_c_result_code() 2.14 + if size is not None: 2.15 + try: 2.16 + size = int(size) 2.17 + except ValueError: 2.18 + # runtime constant? 2.19 + pass 2.20 else: 2.21 size = None 2.22 if not base_type.is_complete(): 2.23 @@ -541,7 +542,7 @@ 2.24 else: 2.25 if self.exception_value: 2.26 self.exception_value.analyse_const_expression(env) 2.27 - exc_val = self.exception_value.get_constant_result_code() 2.28 + exc_val = self.exception_value.get_constant_c_result_code() 2.29 if self.exception_check == '+': 2.30 exc_val_type = self.exception_value.type 2.31 if not exc_val_type.is_error and \