Commit 0e92b4fc authored by Stefan Behnel's avatar Stefan Behnel

use an explicit way to ask for a non-calculated constant result code during analysis

parent 0a8ea6e7
...@@ -239,6 +239,11 @@ class ExprNode(Node): ...@@ -239,6 +239,11 @@ class ExprNode(Node):
# C type of the result_code expression). # C type of the result_code expression).
return self.result_ctype or self.type 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): def calculate_constant_result(self):
# Calculate the constant result of this expression and store # Calculate the constant result of this expression and store
# it in ``self.constant_result``. Does nothing by default, # it in ``self.constant_result``. Does nothing by default,
...@@ -801,6 +806,9 @@ class ConstNode(AtomicNewTempExprNode): ...@@ -801,6 +806,9 @@ class ConstNode(AtomicNewTempExprNode):
def check_const(self): def check_const(self):
pass pass
def get_constant_result_code(self):
return self.calculate_result_code()
def calculate_result_code(self): def calculate_result_code(self):
return str(self.value) return str(self.value)
...@@ -827,6 +835,9 @@ class NullNode(ConstNode): ...@@ -827,6 +835,9 @@ class NullNode(ConstNode):
value = "NULL" value = "NULL"
constant_result = 0 constant_result = 0
def get_constant_result_code(self):
return self.value
class CharNode(ConstNode): class CharNode(ConstNode):
type = PyrexTypes.c_char_type type = PyrexTypes.c_char_type
...@@ -871,7 +882,10 @@ class IntNode(ConstNode): ...@@ -871,7 +882,10 @@ class IntNode(ConstNode):
if self.type.is_pyobject: if self.type.is_pyobject:
self.result_code = code.get_py_num(self.value, self.longness) self.result_code = code.get_py_num(self.value, self.longness)
else: 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): def calculate_result_code(self):
return self.result_code return self.result_code
...@@ -954,6 +968,9 @@ class StringNode(ConstNode): ...@@ -954,6 +968,9 @@ class StringNode(ConstNode):
self.result_code = code.get_py_string_const(self.value) self.result_code = code.get_py_string_const(self.value)
else: else:
self.result_code = code.get_string_const(self.value) self.result_code = code.get_string_const(self.value)
def get_constant_result_code(self):
return None # FIXME
def calculate_result_code(self): def calculate_result_code(self):
return self.result_code return self.result_code
...@@ -993,6 +1010,9 @@ class IdentifierStringNode(ConstNode): ...@@ -993,6 +1010,9 @@ class IdentifierStringNode(ConstNode):
else: else:
self.result_code = code.get_string_const(self.value) self.result_code = code.get_string_const(self.value)
def get_constant_result_code(self):
return None
def calculate_result_code(self): def calculate_result_code(self):
return self.result_code return self.result_code
......
...@@ -489,7 +489,7 @@ class CArrayDeclaratorNode(CDeclaratorNode): ...@@ -489,7 +489,7 @@ class CArrayDeclaratorNode(CDeclaratorNode):
self.dimension.analyse_const_expression(env) self.dimension.analyse_const_expression(env)
if not self.dimension.type.is_int: if not self.dimension.type.is_int:
error(self.dimension.pos, "Array dimension not integer") error(self.dimension.pos, "Array dimension not integer")
size = self.dimension.compile_time_value(env) size = self.dimension.get_constant_result_code()
try: try:
size = int(size) size = int(size)
except ValueError: except ValueError:
...@@ -572,6 +572,7 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -572,6 +572,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
else: else:
if self.exception_value: if self.exception_value:
self.exception_value.analyse_const_expression(env) self.exception_value.analyse_const_expression(env)
exc_val = self.exception_value.get_constant_result_code()
if self.exception_check == '+': if self.exception_check == '+':
exc_val_type = self.exception_value.type exc_val_type = self.exception_value.type
if not exc_val_type.is_error and \ if not exc_val_type.is_error and \
...@@ -579,12 +580,10 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -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): 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, error(self.exception_value.pos,
"Exception value must be a Python exception or cdef function with no arguments.") "Exception value must be a Python exception or cdef function with no arguments.")
exc_val = self.exception_value
else: else:
exc_val = self.exception_value.compile_time_value(env)
if not return_type.assignable_from(self.exception_value.type): if not return_type.assignable_from(self.exception_value.type):
error(self.exception_value.pos, error(self.exception_value.pos,
"Exception value incompatible with function return type") "Exception value incompatible with function return type")
exc_check = self.exception_check exc_check = self.exception_check
if return_type.is_array: if return_type.is_array:
error(self.pos, error(self.pos,
...@@ -945,7 +944,7 @@ class CEnumDefItemNode(StatNode): ...@@ -945,7 +944,7 @@ class CEnumDefItemNode(StatNode):
if not self.value.type.is_int: if not self.value.type.is_int:
self.value = self.value.coerce_to(PyrexTypes.c_int_type, env) self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
self.value.analyse_const_expression(env) self.value.analyse_const_expression(env)
value = self.value.compile_time_value(env) value = self.value.get_constant_result_code()
else: else:
value = self.name value = self.name
entry = env.declare_const(self.name, enum_entry.type, entry = env.declare_const(self.name, enum_entry.type,
...@@ -3703,11 +3702,12 @@ class SwitchCaseNode(StatNode): ...@@ -3703,11 +3702,12 @@ class SwitchCaseNode(StatNode):
# body StatNode # body StatNode
child_attrs = ['conditions', 'body'] child_attrs = ['conditions', 'body']
def generate_execution_code(self, code): def generate_execution_code(self, code):
for cond in self.conditions: for cond in self.conditions:
code.mark_pos(cond.pos) 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) self.body.generate_execution_code(code)
code.putln("break;") code.putln("break;")
...@@ -3726,7 +3726,7 @@ class SwitchStatNode(StatNode): ...@@ -3726,7 +3726,7 @@ class SwitchStatNode(StatNode):
child_attrs = ['test', 'cases', 'else_clause'] child_attrs = ['test', 'cases', 'else_clause']
def generate_execution_code(self, code): 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: for case in self.cases:
case.generate_execution_code(code) case.generate_execution_code(code)
if self.else_clause is not None: if self.else_clause is not None:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment