Commit fc97fc88 authored by Robert Bradshaw's avatar Robert Bradshaw

c literal lists

parent 0869f9d4
...@@ -564,7 +564,7 @@ class ExprNode(Node): ...@@ -564,7 +564,7 @@ class ExprNode(Node):
# reference, or temporary. # reference, or temporary.
return self.result_in_temp() return self.result_in_temp()
def as_cython_attribute(self): def magic_cython_method(self):
return None return None
...@@ -866,7 +866,7 @@ class NameNode(AtomicExprNode): ...@@ -866,7 +866,7 @@ class NameNode(AtomicExprNode):
node.analyse_types(env, entry=entry) node.analyse_types(env, entry=entry)
return node return node
def as_cython_attribute(self): def magic_cython_method(self):
return self.cython_attribute return self.cython_attribute
create_analysed_rvalue = staticmethod(create_analysed_rvalue) create_analysed_rvalue = staticmethod(create_analysed_rvalue)
...@@ -1822,7 +1822,7 @@ class SimpleCallNode(CallNode): ...@@ -1822,7 +1822,7 @@ class SimpleCallNode(CallNode):
self.compile_time_value_error(e) self.compile_time_value_error(e)
def analyse_as_type(self, env): def analyse_as_type(self, env):
attr = self.function.as_cython_attribute() attr = self.function.magic_cython_method()
if attr == 'pointer': if attr == 'pointer':
if len(self.args) != 1: if len(self.args) != 1:
error(self.args.pos, "only one type allowed.") error(self.args.pos, "only one type allowed.")
...@@ -2173,7 +2173,7 @@ class AttributeNode(ExprNode): ...@@ -2173,7 +2173,7 @@ class AttributeNode(ExprNode):
is_called = 0 is_called = 0
needs_none_check = True needs_none_check = True
def as_cython_attribute(self): def magic_cython_method(self):
if isinstance(self.obj, NameNode) and self.obj.is_cython_module: if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
return self.attribute return self.attribute
...@@ -2659,26 +2659,57 @@ class ListNode(SequenceNode): ...@@ -2659,26 +2659,57 @@ class ListNode(SequenceNode):
gil_message = "Constructing Python list" gil_message = "Constructing Python list"
def analyse_types(self, env): def analyse_types(self, env):
SequenceNode.analyse_types(self, env) for arg in self.args:
self.type = list_type arg.analyse_types(env)
self.is_temp = 1
self.type = PyrexTypes.unspecified_type
def coerce_to(self, dst_type, env):
if dst_type.is_pyobject:
self.gil_check(env)
self.type = list_type
for i in range(len(self.args)):
arg = self.args[i]
if not arg.type.is_pyobject:
self.args[i] = arg.coerce_to_pyobject(env)
if not self.type.subtype_of(dst_type):
error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
elif dst_type.is_ptr:
base_type = dst_type.base_type
self.type = dst_type
for i in range(len(self.args)):
arg = self.args[i]
self.args[i] = arg.coerce_to(base_type, env)
else:
self.type = error_type
error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
return self
def compile_time_value(self, denv): def compile_time_value(self, denv):
return self.compile_time_value_list(denv) return self.compile_time_value_list(denv)
def generate_operation_code(self, code): def generate_operation_code(self, code):
code.putln("%s = PyList_New(%s); %s" % if self.type.is_pyobject:
(self.result(), code.putln("%s = PyList_New(%s); %s" %
len(self.args),
code.error_goto_if_null(self.result(), self.pos)))
for i in range(len(self.args)):
arg = self.args[i]
#if not arg.is_temp:
if not arg.result_in_temp():
code.put_incref(arg.result(), arg.ctype())
code.putln("PyList_SET_ITEM(%s, %s, %s);" %
(self.result(), (self.result(),
i, len(self.args),
arg.py_result())) code.error_goto_if_null(self.result(), self.pos)))
for i in range(len(self.args)):
arg = self.args[i]
#if not arg.is_temp:
if not arg.result_in_temp():
code.put_incref(arg.result(), arg.ctype())
code.putln("PyList_SET_ITEM(%s, %s, %s);" %
(self.result(),
i,
arg.py_result()))
else:
code.putln("%s = (%s[]) {" % (self.result(), self.type.base_type))
for i, arg in enumerate(self.args):
code.put(arg.result())
code.put(", ")
code.putln();
code.putln("};")
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
# We call generate_post_assignment_code here instead # We call generate_post_assignment_code here instead
......
...@@ -2552,7 +2552,7 @@ class ExprStatNode(StatNode): ...@@ -2552,7 +2552,7 @@ class ExprStatNode(StatNode):
def analyse_declarations(self, env): def analyse_declarations(self, env):
import ExprNodes import ExprNodes
if isinstance(self.expr, ExprNodes.GeneralCallNode): if isinstance(self.expr, ExprNodes.GeneralCallNode):
func = self.expr.function.as_cython_attribute() func = self.expr.function.magic_cython_method()
if func == u'declare': if func == u'declare':
args, kwds = self.expr.explicit_args_kwds() args, kwds = self.expr.explicit_args_kwds()
if len(args): if len(args):
...@@ -2620,7 +2620,7 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -2620,7 +2620,7 @@ class SingleAssignmentNode(AssignmentNode):
# handle declarations of the form x = cython.foo() # handle declarations of the form x = cython.foo()
if isinstance(self.rhs, ExprNodes.CallNode): if isinstance(self.rhs, ExprNodes.CallNode):
func_name = self.rhs.function.as_cython_attribute() func_name = self.rhs.function.magic_cython_method()
if func_name: if func_name:
args, kwds = self.rhs.explicit_args_kwds() args, kwds = self.rhs.explicit_args_kwds()
......
...@@ -355,7 +355,7 @@ class InterpretCompilerDirectives(CythonTransform): ...@@ -355,7 +355,7 @@ class InterpretCompilerDirectives(CythonTransform):
optname = None optname = None
if isinstance(node, CallNode): if isinstance(node, CallNode):
self.visit(node.function) self.visit(node.function)
optname = node.function.as_cython_attribute() optname = node.function.magic_cython_method()
# if (isinstance(node.function, AttributeNode) and # if (isinstance(node.function, AttributeNode) and
# isinstance(node.function.obj, NameNode) and # isinstance(node.function.obj, NameNode) and
# node.function.obj.name in self.cython_module_names): # node.function.obj.name in self.cython_module_names):
...@@ -714,7 +714,7 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -714,7 +714,7 @@ class TransformBuiltinMethods(EnvTransform):
return node return node
def visit_AttributeNode(self, node): def visit_AttributeNode(self, node):
attribute = node.as_cython_attribute() attribute = node.magic_cython_method()
if attribute: if attribute:
if attribute == u'compiled': if attribute == u'compiled':
node = BoolNode(node.pos, value=True) node = BoolNode(node.pos, value=True)
...@@ -735,7 +735,7 @@ class TransformBuiltinMethods(EnvTransform): ...@@ -735,7 +735,7 @@ class TransformBuiltinMethods(EnvTransform):
return ExprNodes.DictNode(pos, key_value_pairs=items) return ExprNodes.DictNode(pos, key_value_pairs=items)
# cython.foo # cython.foo
function = node.function.as_cython_attribute() function = node.function.magic_cython_method()
if function: if function:
if function == u'cast': if function == u'cast':
if len(node.args) != 2: if len(node.args) != 2:
......
...@@ -1047,6 +1047,17 @@ class CCharPtrType(CStringType, CPtrType): ...@@ -1047,6 +1047,17 @@ class CCharPtrType(CStringType, CPtrType):
CPtrType.__init__(self, c_char_type) CPtrType.__init__(self, c_char_type)
class UnspecifiedType(PyrexType):
# Used as a placeholder until the type can be determined.
def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0):
return "<unspecified>"
def same_as_resolved_type(self, other_type):
return False
class ErrorType(PyrexType): class ErrorType(PyrexType):
# Used to prevent propagation of error messages. # Used to prevent propagation of error messages.
...@@ -1127,6 +1138,7 @@ c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer ...@@ -1127,6 +1138,7 @@ c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer
c_py_buffer_ptr_type = CPtrType(c_py_buffer_type) c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
error_type = ErrorType() error_type = ErrorType()
unspecified_type = UnspecifiedType()
lowest_float_rank = 6 lowest_float_rank = 6
......
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