use an explicit way to ask for a non-calculated constant result code during analysis
authorStefan Behnel <scoder@users.berlios.de>
Thu, 19 Mar 2009 16:02:07 +0000 (17:02 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Thu, 19 Mar 2009 16:02:07 +0000 (17:02 +0100)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py

index eca3dd30840d2efd3e7530d9a4928087b817f2b4..0f2ae9caa9d5ccc599ef84ac17ebfee83cf7fa5d 100644 (file)
@@ -239,6 +239,11 @@ class ExprNode(Node):
         #  C type of the result_code expression).
         return self.result_ctype or self.type
 
+    def get_constant_result_code(self):
+        # Return the constant value of this node as a result code
+        # string, or None if the node is not constant.
+        return None
+
     def calculate_constant_result(self):
         # Calculate the constant result of this expression and store
         # it in ``self.constant_result``.  Does nothing by default,
@@ -801,6 +806,9 @@ class ConstNode(AtomicNewTempExprNode):
     def check_const(self):
         pass
     
+    def get_constant_result_code(self):
+        return self.calculate_result_code()
+
     def calculate_result_code(self):
         return str(self.value)
 
@@ -827,6 +835,9 @@ class NullNode(ConstNode):
     value = "NULL"
     constant_result = 0
 
+    def get_constant_result_code(self):
+        return self.value
+
 
 class CharNode(ConstNode):
     type = PyrexTypes.c_char_type
@@ -871,7 +882,10 @@ class IntNode(ConstNode):
         if self.type.is_pyobject:
             self.result_code = code.get_py_num(self.value, self.longness)
         else:
-            self.result_code = str(self.value) + self.unsigned + self.longness
+            self.result_code = self.get_constant_result_code()
+    
+    def get_constant_result_code(self):
+        return str(self.value) + self.unsigned + self.longness
 
     def calculate_result_code(self):
         return self.result_code
@@ -954,6 +968,9 @@ class StringNode(ConstNode):
             self.result_code = code.get_py_string_const(self.value)
         else:
             self.result_code = code.get_string_const(self.value)
+
+    def get_constant_result_code(self):
+        return None # FIXME
     
     def calculate_result_code(self):
         return self.result_code
@@ -993,6 +1010,9 @@ class IdentifierStringNode(ConstNode):
         else:
             self.result_code = code.get_string_const(self.value)
 
+    def get_constant_result_code(self):
+        return None
+
     def calculate_result_code(self):
         return self.result_code
 
index 608b4776fe675da26c938f1bd18eacfbe678745e..9bdbd614ece79ba52783425112218682759883e0 100644 (file)
@@ -489,7 +489,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
             self.dimension.analyse_const_expression(env)
             if not self.dimension.type.is_int:
                 error(self.dimension.pos, "Array dimension not integer")
-            size = self.dimension.compile_time_value(env)
+            size = self.dimension.get_constant_result_code()
             try:
                 size = int(size)
             except ValueError:
@@ -572,6 +572,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
         else:
             if self.exception_value:
                 self.exception_value.analyse_const_expression(env)
+                exc_val = self.exception_value.get_constant_result_code()
                 if self.exception_check == '+':
                     exc_val_type = self.exception_value.type
                     if not exc_val_type.is_error and \
@@ -579,12 +580,10 @@ class CFuncDeclaratorNode(CDeclaratorNode):
                           not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
                         error(self.exception_value.pos,
                             "Exception value must be a Python exception or cdef function with no arguments.")
-                    exc_val = self.exception_value
                 else:
-                    exc_val = self.exception_value.compile_time_value(env)
                     if not return_type.assignable_from(self.exception_value.type):
                         error(self.exception_value.pos,
-                            "Exception value incompatible with function return type")
+                              "Exception value incompatible with function return type")
             exc_check = self.exception_check
         if return_type.is_array:
             error(self.pos,
@@ -945,7 +944,7 @@ class CEnumDefItemNode(StatNode):
             if not self.value.type.is_int:
                 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
                 self.value.analyse_const_expression(env)
-            value = self.value.compile_time_value(env)
+            value = self.value.get_constant_result_code()
         else:
             value = self.name
         entry = env.declare_const(self.name, enum_entry.type, 
@@ -3703,11 +3702,12 @@ class SwitchCaseNode(StatNode):
     # body          StatNode
     
     child_attrs = ['conditions', 'body']
-    
+
     def generate_execution_code(self, code):
         for cond in self.conditions:
             code.mark_pos(cond.pos)
-            code.putln("case %s:" % cond.calculate_result_code())
+            cond.generate_evaluation_code(code)
+            code.putln("case %s:" % cond.result())
         self.body.generate_execution_code(code)
         code.putln("break;")
         
@@ -3726,7 +3726,7 @@ class SwitchStatNode(StatNode):
     child_attrs = ['test', 'cases', 'else_clause']
     
     def generate_execution_code(self, code):
-        code.putln("switch (%s) {" % self.test.calculate_result_code())
+        code.putln("switch (%s) {" % self.test.result())
         for case in self.cases:
             case.generate_execution_code(code)
         if self.else_clause is not None: