Cython has moved to github.

cython-devel

view Cython/Compiler/PyrexTypes.py @ 2052:dcc78ab6a498

Fix #303 as per Lisandro's idea
author Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
date Thu May 14 16:49:54 2009 +0200 (3 years ago)
parents a4dd4c9292dc
children f0d9b51d7ec8
line source
1 #
2 # Pyrex - Types
3 #
5 from Cython.Utils import UtilityCode
6 import StringEncoding
7 import Naming
8 import copy
10 class BaseType(object):
11 #
12 # Base class for all Pyrex types including pseudo-types.
14 def cast_code(self, expr_code):
15 return "((%s)%s)" % (self.declaration_code(""), expr_code)
17 def specalization_name(self):
18 return self.declaration_code("").replace(" ", "__")
20 def base_declaration_code(self, base_code, entity_code):
21 if entity_code:
22 return "%s %s" % (base_code, entity_code)
23 else:
24 return base_code
26 class PyrexType(BaseType):
27 #
28 # Base class for all Pyrex types.
29 #
30 # is_pyobject boolean Is a Python object type
31 # is_extension_type boolean Is a Python extension type
32 # is_numeric boolean Is a C numeric type
33 # is_int boolean Is a C integer type
34 # is_longlong boolean Is a long long or unsigned long long.
35 # is_float boolean Is a C floating point type
36 # is_complex boolean Is a C complex type
37 # is_void boolean Is the C void type
38 # is_array boolean Is a C array type
39 # is_ptr boolean Is a C pointer type
40 # is_null_ptr boolean Is the type of NULL
41 # is_cfunction boolean Is a C function type
42 # is_struct_or_union boolean Is a C struct or union type
43 # is_struct boolean Is a C struct type
44 # is_enum boolean Is a C enum type
45 # is_typedef boolean Is a typedef type
46 # is_string boolean Is a C char * type
47 # is_unicode boolean Is a UTF-8 encoded C char * type
48 # is_returncode boolean Is used only to signal exceptions
49 # is_error boolean Is the dummy error type
50 # is_buffer boolean Is buffer access type
51 # has_attributes boolean Has C dot-selectable attributes
52 # default_value string Initial value
53 # pymemberdef_typecode string Type code for PyMemberDef struct
54 #
55 # declaration_code(entity_code,
56 # for_display = 0, dll_linkage = None, pyrex = 0)
57 # Returns a code fragment for the declaration of an entity
58 # of this type, given a code fragment for the entity.
59 # * If for_display, this is for reading by a human in an error
60 # message; otherwise it must be valid C code.
61 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
62 # 'DL_IMPORT', and will be added to the base type part of
63 # the declaration.
64 # * If pyrex = 1, this is for use in a 'cdef extern'
65 # statement of a Pyrex include file.
66 #
67 # assignable_from(src_type)
68 # Tests whether a variable of this type can be
69 # assigned a value of type src_type.
70 #
71 # same_as(other_type)
72 # Tests whether this type represents the same type
73 # as other_type.
74 #
75 # as_argument_type():
76 # Coerces array type into pointer type for use as
77 # a formal argument type.
78 #
80 is_pyobject = 0
81 is_extension_type = 0
82 is_builtin_type = 0
83 is_numeric = 0
84 is_int = 0
85 is_longlong = 0
86 is_float = 0
87 is_complex = 0
88 is_void = 0
89 is_array = 0
90 is_ptr = 0
91 is_null_ptr = 0
92 is_cfunction = 0
93 is_struct_or_union = 0
94 is_struct = 0
95 is_enum = 0
96 is_typedef = 0
97 is_string = 0
98 is_unicode = 0
99 is_returncode = 0
100 is_error = 0
101 is_buffer = 0
102 has_attributes = 0
103 default_value = ""
104 pymemberdef_typecode = None
106 def resolve(self):
107 # If a typedef, returns the base type.
108 return self
110 def literal_code(self, value):
111 # Returns a C code fragment representing a literal
112 # value of this type.
113 return str(value)
115 def __str__(self):
116 return self.declaration_code("", for_display = 1).strip()
118 def same_as(self, other_type, **kwds):
119 return self.same_as_resolved_type(other_type.resolve(), **kwds)
121 def same_as_resolved_type(self, other_type):
122 return self == other_type or other_type is error_type
124 def subtype_of(self, other_type):
125 return self.subtype_of_resolved_type(other_type.resolve())
127 def subtype_of_resolved_type(self, other_type):
128 return self.same_as(other_type)
130 def assignable_from(self, src_type):
131 return self.assignable_from_resolved_type(src_type.resolve())
133 def assignable_from_resolved_type(self, src_type):
134 return self.same_as(src_type)
136 def as_argument_type(self):
137 return self
139 def is_complete(self):
140 # A type is incomplete if it is an unsized array,
141 # a struct whose attributes are not defined, etc.
142 return 1
144 def is_simple_buffer_dtype(self):
145 return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
146 self.is_extension_type or self.is_ptr)
148 def struct_nesting_depth(self):
149 # Returns the number levels of nested structs. This is
150 # used for constructing a stack for walking the run-time
151 # type information of the struct.
152 return 1
154 class CTypedefType(BaseType):
155 #
156 # Pseudo-type defined with a ctypedef statement in a
157 # 'cdef extern from' block. Delegates most attribute
158 # lookups to the base type. ANYTHING NOT DEFINED
159 # HERE IS DELEGATED!
160 #
161 # qualified_name string
162 # typedef_cname string
163 # typedef_base_type PyrexType
164 # typedef_is_external bool
166 is_typedef = 1
167 typedef_is_external = 0
169 def __init__(self, cname, base_type, is_external=0):
170 self.typedef_cname = cname
171 self.typedef_base_type = base_type
172 self.typedef_is_external = is_external
174 def resolve(self):
175 return self.typedef_base_type.resolve()
177 def declaration_code(self, entity_code,
178 for_display = 0, dll_linkage = None, pyrex = 0):
179 name = self.declaration_name(for_display, pyrex)
180 return self.base_declaration_code(name, entity_code)
182 def declaration_name(self, for_display = 0, pyrex = 0):
183 if pyrex or for_display:
184 return self.qualified_name
185 else:
186 return self.typedef_cname
188 def as_argument_type(self):
189 return self
191 def cast_code(self, expr_code):
192 # If self is really an array (rather than pointer), we can't cast.
193 # For example, the gmp mpz_t.
194 if self.typedef_base_type.is_ptr:
195 return self.typedef_base_type.cast_code(expr_code)
196 else:
197 return BaseType.cast_code(self, expr_code)
199 def __repr__(self):
200 return "<CTypedefType %s>" % self.typedef_cname
202 def __str__(self):
203 return self.declaration_name(for_display = 1)
205 def __getattr__(self, name):
206 return getattr(self.typedef_base_type, name)
208 class BufferType(BaseType):
209 #
210 # Delegates most attribute
211 # lookups to the base type. ANYTHING NOT DEFINED
212 # HERE IS DELEGATED!
214 # dtype PyrexType
215 # ndim int
216 # mode str
217 # negative_indices bool
218 # cast bool
219 # is_buffer bool
220 # writable bool
222 is_buffer = 1
223 writable = True
224 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
225 self.base = base
226 self.dtype = dtype
227 self.ndim = ndim
228 self.buffer_ptr_type = CPtrType(dtype)
229 self.mode = mode
230 self.negative_indices = negative_indices
231 self.cast = cast
233 def as_argument_type(self):
234 return self
236 def __getattr__(self, name):
237 return getattr(self.base, name)
239 def __repr__(self):
240 return "<BufferType %r>" % self.base
242 def public_decl(base, dll_linkage):
243 if dll_linkage:
244 return "%s(%s)" % (dll_linkage, base)
245 else:
246 return base
248 class PyObjectType(PyrexType):
249 #
250 # Base class for all Python object types (reference-counted).
251 #
252 # buffer_defaults dict or None Default options for bu
254 is_pyobject = 1
255 default_value = "0"
256 pymemberdef_typecode = "T_OBJECT"
257 buffer_defaults = None
259 def __str__(self):
260 return "Python object"
262 def __repr__(self):
263 return "<PyObjectType>"
265 def assignable_from(self, src_type):
266 return 1 # Conversion will be attempted
268 def declaration_code(self, entity_code,
269 for_display = 0, dll_linkage = None, pyrex = 0):
270 if pyrex or for_display:
271 return self.base_declaration_code("object", entity_code)
272 else:
273 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
275 def as_pyobject(self, cname):
276 if (not self.is_complete()) or self.is_extension_type:
277 return "(PyObject *)" + cname
278 else:
279 return cname
281 class BuiltinObjectType(PyObjectType):
283 is_builtin_type = 1
284 has_attributes = 1
285 base_type = None
286 module_name = '__builtin__'
288 alternative_name = None # used for str/bytes duality
290 def __init__(self, name, cname):
291 self.name = name
292 if name == 'str':
293 self.alternative_name = 'bytes'
294 elif name == 'bytes':
295 self.alternative_name = 'str'
296 self.cname = cname
297 self.typeptr_cname = "&" + cname
299 def set_scope(self, scope):
300 self.scope = scope
301 if scope:
302 scope.parent_type = self
304 def __str__(self):
305 return "%s object" % self.name
307 def __repr__(self):
308 return "<%s>"% self.cname
310 def assignable_from(self, src_type):
311 if isinstance(src_type, BuiltinObjectType):
312 return src_type.name == self.name or (
313 src_type.name == self.alternative_name and
314 src_type.name is not None)
315 else:
316 return not src_type.is_extension_type
318 def typeobj_is_available(self):
319 return True
321 def attributes_known(self):
322 return True
324 def subtype_of(self, type):
325 return type.is_pyobject and self.assignable_from(type)
327 def type_test_code(self, arg):
328 type_name = self.name
329 if type_name == 'str':
330 check = 'PyString_CheckExact'
331 elif type_name == 'set':
332 check = 'PyAnySet_CheckExact'
333 elif type_name == 'frozenset':
334 check = 'PyFrozenSet_CheckExact'
335 elif type_name == 'bool':
336 check = 'PyBool_Check'
337 else:
338 check = 'Py%s_CheckExact' % type_name.capitalize()
339 return 'likely(%s(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (check, arg, arg, self.name, arg)
341 def declaration_code(self, entity_code,
342 for_display = 0, dll_linkage = None, pyrex = 0):
343 if pyrex or for_display:
344 return self.base_declaration_code(self.name, entity_code)
345 else:
346 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
349 class PyExtensionType(PyObjectType):
350 #
351 # A Python extension type.
352 #
353 # name string
354 # scope CClassScope Attribute namespace
355 # visibility string
356 # typedef_flag boolean
357 # base_type PyExtensionType or None
358 # module_name string or None Qualified name of defining module
359 # objstruct_cname string Name of PyObject struct
360 # typeobj_cname string or None C code fragment referring to type object
361 # typeptr_cname string or None Name of pointer to external type object
362 # vtabslot_cname string Name of C method table member
363 # vtabstruct_cname string Name of C method table struct
364 # vtabptr_cname string Name of pointer to C method table
365 # vtable_cname string Name of C method table definition
367 is_extension_type = 1
368 has_attributes = 1
370 def __init__(self, name, typedef_flag, base_type):
371 self.name = name
372 self.scope = None
373 self.typedef_flag = typedef_flag
374 self.base_type = base_type
375 self.module_name = None
376 self.objstruct_cname = None
377 self.typeobj_cname = None
378 self.typeptr_cname = None
379 self.vtabslot_cname = None
380 self.vtabstruct_cname = None
381 self.vtabptr_cname = None
382 self.vtable_cname = None
384 def set_scope(self, scope):
385 self.scope = scope
386 if scope:
387 scope.parent_type = self
389 def subtype_of_resolved_type(self, other_type):
390 if other_type.is_extension_type:
391 return self is other_type or (
392 self.base_type and self.base_type.subtype_of(other_type))
393 else:
394 return other_type is py_object_type
396 def typeobj_is_available(self):
397 # Do we have a pointer to the type object?
398 return self.typeptr_cname
400 def typeobj_is_imported(self):
401 # If we don't know the C name of the type object but we do
402 # know which module it's defined in, it will be imported.
403 return self.typeobj_cname is None and self.module_name is not None
405 def declaration_code(self, entity_code,
406 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
407 if pyrex or for_display:
408 return self.base_declaration_code(self.name, entity_code)
409 else:
410 if self.typedef_flag:
411 base_format = "%s"
412 else:
413 base_format = "struct %s"
414 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
415 if deref:
416 return "%s %s" % (base, entity_code)
417 else:
418 return "%s *%s" % (base, entity_code)
420 def type_test_code(self, py_arg):
421 return "__Pyx_TypeTest(%s, %s)" % (py_arg, self.typeptr_cname)
423 def attributes_known(self):
424 return self.scope is not None
426 def __str__(self):
427 return self.name
429 def __repr__(self):
430 return "<PyExtensionType %s%s>" % (self.scope.class_name,
431 ("", " typedef")[self.typedef_flag])
434 class CType(PyrexType):
435 #
436 # Base class for all C types (non-reference-counted).
437 #
438 # to_py_function string C function for converting to Python object
439 # from_py_function string C function for constructing from Python object
440 #
442 to_py_function = None
443 from_py_function = None
444 exception_value = None
445 exception_check = 1
447 def create_to_py_utility_code(self, env):
448 return True
450 def create_from_py_utility_code(self, env):
451 return True
453 def error_condition(self, result_code):
454 conds = []
455 if self.is_string:
456 conds.append("(!%s)" % result_code)
457 elif self.exception_value is not None:
458 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
459 if self.exception_check:
460 conds.append("PyErr_Occurred()")
461 if len(conds) > 0:
462 return " && ".join(conds)
463 else:
464 return 0
467 class CVoidType(CType):
468 is_void = 1
470 def __repr__(self):
471 return "<CVoidType>"
473 def declaration_code(self, entity_code,
474 for_display = 0, dll_linkage = None, pyrex = 0):
475 base = public_decl("void", dll_linkage)
476 return self.base_declaration_code(base, entity_code)
478 def is_complete(self):
479 return 0
482 class CNumericType(CType):
483 #
484 # Base class for all C numeric types.
485 #
486 # rank integer Relative size
487 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
488 #
490 is_numeric = 1
491 default_value = "0"
493 sign_words = ("unsigned ", "", "signed ")
495 def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
496 self.rank = rank
497 self.signed = signed
498 self.pymemberdef_typecode = pymemberdef_typecode
500 def sign_and_name(self):
501 s = self.sign_words[self.signed]
502 n = rank_to_type_name[self.rank]
503 return s + n
505 def __repr__(self):
506 return "<CNumericType %s>" % self.sign_and_name()
508 def declaration_code(self, entity_code,
509 for_display = 0, dll_linkage = None, pyrex = 0):
510 base = public_decl(self.sign_and_name(), dll_linkage)
511 if for_display and self.is_longlong:
512 base = base.replace('PY_LONG_LONG', 'long long')
513 return self.base_declaration_code(base, entity_code)
516 type_conversion_predeclarations = ""
517 type_conversion_functions = ""
519 c_int_from_py_function = UtilityCode(
520 proto="""
521 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
522 """,
523 impl="""
524 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
525 if (sizeof(%(type)s) < sizeof(long)) {
526 long val = __Pyx_PyInt_AsLong(x);
527 if (unlikely(val != (long)(%(type)s)val)) {
528 if (unlikely(val == -1 && PyErr_Occurred()))
529 return (%(type)s)-1;""" + \
530 "%(IntValSignTest)s" + \
531 """
532 PyErr_SetString(PyExc_OverflowError,
533 "value too large to convert to %(type)s");
534 return (%(type)s)-1;
535 }
536 return (%(type)s)val;
537 }
538 return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
539 }
540 """)
541 intval_signtest = """
542 if (unlikely(%(var)s < 0)) {
543 PyErr_SetString(PyExc_OverflowError,
544 "can't convert negative value to %(type)s");
545 return (%(type)s)-1;
546 }"""
548 c_long_from_py_function = UtilityCode(
549 proto="""
550 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
551 """,
552 impl="""
553 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
554 #if PY_VERSION_HEX < 0x03000000
555 if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) {
556 long val = PyInt_AS_LONG(x);""" + \
557 "%(IntValSignTest)s" + \
558 """
559 return (%(type)s)val;
560 } else
561 #endif
562 if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {""" +\
563 "%(PyLongSignTest)s" + \
564 """
565 return %(PyLongConvert)s(x);
566 } else {
567 %(type)s val;
568 PyObject *tmp = __Pyx_PyNumber_Int(x);
569 if (!tmp) return (%(type)s)-1;
570 val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
571 Py_DECREF(tmp);
572 return val;
573 }
574 }
575 """)
576 pylong_signtest = """
577 if (unlikely(Py_SIZE(%(var)s) < 0)) {
578 PyErr_SetString(PyExc_OverflowError,
579 "can't convert negative value to %(type)s");
580 return (%(type)s)-1;
581 }"""
585 class CIntType(CNumericType):
587 is_int = 1
588 typedef_flag = 0
589 to_py_function = "PyInt_FromLong"
590 from_py_function = "__Pyx_PyInt_AsInt"
591 exception_value = -1
593 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
594 CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
595 self.is_returncode = is_returncode
596 if self.from_py_function == "__Pyx_PyInt_AsInt":
597 self.from_py_function = self.get_type_conversion()
599 def get_type_conversion(self):
600 ctype = self.declaration_code('')
601 bits = ctype.split(" ", 1)
602 if len(bits) == 1:
603 sign_word, type_name = "", bits[0]
604 else:
605 sign_word, type_name = bits
606 type_name = type_name.replace("PY_LONG_LONG","long long")
607 SignWord = sign_word.title()
608 TypeName = type_name.title().replace(" ", "")
609 data = {'IntValSignTest' : "",
610 'PyLongSignTest' : "",
611 'PyLongConvert' : "",
612 }
613 if not self.signed:
614 data['IntValSignTest'] = intval_signtest % {'var':"val", 'type':ctype}
615 data['PyLongSignTest'] = pylong_signtest % {'var':"x", 'type':ctype}
616 if "Long" in TypeName:
617 data['PyLongConvert'] = \
618 "PyLong_As" + SignWord.replace("Signed", "") + TypeName
619 # the replaces below are just for generating well indented C code
620 data['IntValSignTest'] = "\n".join(
621 [ln.replace(" "*4, "", 1) for ln in data['IntValSignTest'].split('\n')]
622 )
623 utility_code = c_long_from_py_function
624 else:
625 utility_code = c_int_from_py_function
626 utility_code.specialize(self,
627 SignWord=SignWord,
628 TypeName=TypeName,
629 **data)
630 func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
631 return func_name
633 def assignable_from_resolved_type(self, src_type):
634 return src_type.is_int or src_type.is_enum or src_type is error_type
637 class CBIntType(CIntType):
639 to_py_function = "__Pyx_PyBool_FromLong"
640 from_py_function = "__Pyx_PyObject_IsTrue"
641 exception_check = 0
644 class CAnonEnumType(CIntType):
646 is_enum = 1
648 def sign_and_name(self):
649 return 'int'
652 class CUIntType(CIntType):
654 to_py_function = "PyLong_FromUnsignedLong"
655 exception_value = -1
658 class CLongType(CIntType):
660 to_py_function = "PyInt_FromLong"
663 class CULongType(CUIntType):
665 to_py_function = "PyLong_FromUnsignedLong"
668 class CLongLongType(CIntType):
670 is_longlong = 1
671 to_py_function = "PyLong_FromLongLong"
674 class CULongLongType(CUIntType):
676 is_longlong = 1
677 to_py_function = "PyLong_FromUnsignedLongLong"
680 class CPySSizeTType(CIntType):
682 to_py_function = "PyInt_FromSsize_t"
683 from_py_function = "__Pyx_PyIndex_AsSsize_t"
685 def sign_and_name(self):
686 return rank_to_type_name[self.rank]
689 class CSizeTType(CUIntType):
691 to_py_function = "__Pyx_PyInt_FromSize_t"
692 from_py_function = "__Pyx_PyInt_AsSize_t"
694 def sign_and_name(self):
695 return rank_to_type_name[self.rank]
698 class CFloatType(CNumericType):
700 is_float = 1
701 to_py_function = "PyFloat_FromDouble"
702 from_py_function = "__pyx_PyFloat_AsDouble"
704 def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
705 CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
706 self.math_h_modifier = math_h_modifier
708 def assignable_from_resolved_type(self, src_type):
709 return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
712 class CComplexType(CNumericType):
714 is_complex = 1
715 to_py_function = "__pyx_PyObject_from_complex"
717 def __init__(self, real_type):
718 self.real_type = real_type
719 CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
720 self.binops = {}
722 def __cmp__(self, other):
723 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
724 return cmp(self.real_type, other.real_type)
725 else:
726 return 1
728 def __hash__(self):
729 return ~hash(self.real_type)
731 def sign_and_name(self):
732 return Naming.type_prefix + self.real_type.specalization_name() + "_complex"
734 def assignable_from_resolved_type(self, src_type):
735 return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
736 or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
737 or src_type is error_type)
739 def create_declaration_utility_code(self, env):
740 if not hasattr(self, 'from_parts'):
741 self.from_parts = "%s_from_parts" % self.specalization_name()
742 env.use_utility_code(complex_generic_utility_code)
743 env.use_utility_code(
744 complex_arithmatic_utility_code.specialize(self,
745 math_h_modifier = self.real_type.math_h_modifier,
746 real_type = self.real_type.declaration_code('')))
747 return True
749 def create_from_py_utility_code(self, env):
750 self.real_type.create_from_py_utility_code(env)
751 env.use_utility_code(
752 complex_conversion_utility_code.specialize(self,
753 math_h_modifier = self.real_type.math_h_modifier,
754 real_type = self.real_type.declaration_code(''),
755 type_convert = self.real_type.from_py_function))
756 self.from_py_function = "__pyx_PyObject_As_" + self.specalization_name()
757 return True
759 def lookup_op(self, nargs, op):
760 try:
761 return self.binops[nargs, op]
762 except KeyError:
763 pass
764 try:
765 op_name = complex_ops[nargs, op]
766 self.binops[nargs, op] = func_name = "%s_%s" % (self.specalization_name(), op_name)
767 return func_name
768 except KeyError:
769 return None
771 def unary_op(self, op):
772 return self.lookup_op(1, op)
774 def binary_op(self, op):
775 return self.lookup_op(2, op)
777 complex_ops = {
778 (1, '-'): 'neg',
779 (1, 'zero'): 'is_zero',
780 (2, '+'): 'add',
781 (2, '-') : 'sub',
782 (2, '*'): 'mul',
783 (2, '/'): 'div',
784 (2, '=='): 'eq',
785 }
787 complex_generic_utility_code = UtilityCode(
788 proto="""
789 #if __PYX_USE_C99_COMPLEX
790 #define __Pyx_REAL_PART(z) __real__(z)
791 #define __Pyx_IMAG_PART(z) __imag__(z)
792 #else
793 #define __Pyx_REAL_PART(z) ((z).real)
794 #define __Pyx_IMAG_PART(z) ((z).imag)
795 #endif
797 #define __pyx_PyObject_from_complex(z) PyComplex_FromDoubles((double)__Pyx_REAL_PART(z), (double)__Pyx_IMAG_PART(z))
798 """)
800 complex_conversion_utility_code = UtilityCode(
801 proto="""
802 static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */
803 """,
804 impl="""
805 static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) {
806 if (PyComplex_Check(o)) {
807 return %(type_name)s_from_parts(
808 (%(real_type)s)((PyComplexObject *)o)->cval.real,
809 (%(real_type)s)((PyComplexObject *)o)->cval.imag);
810 }
811 else {
812 return %(type_name)s_from_parts(%(type_convert)s(o), 0);
813 }
814 }
815 """)
817 complex_arithmatic_utility_code = UtilityCode(
818 proto="""
819 #if __PYX_USE_C99_COMPLEX
821 typedef %(real_type)s _Complex %(type_name)s;
822 #define %(type_name)s_from_parts(x, y) ((x) + (y)*(%(type)s)_Complex_I)
824 #define %(type_name)s_is_zero(a) ((a) == 0)
825 #define %(type_name)s_eq(a, b) ((a) == (b))
826 #define %(type_name)s_add(a, b) ((a)+(b))
827 #define %(type_name)s_sub(a, b) ((a)-(b))
828 #define %(type_name)s_mul(a, b) ((a)*(b))
829 #define %(type_name)s_div(a, b) ((a)/(b))
830 #define %(type_name)s_neg(a) (-(a))
832 #else
834 typedef struct { %(real_type)s real, imag; } %(type_name)s;
835 #define %(type_name)s_from_parts(x, y) ((%(type_name)s){(%(real_type)s)x, (%(real_type)s)y})
837 static INLINE int %(type_name)s_is_zero(%(type)s a) {
838 return (a.real == 0) & (a.imag == 0);
839 }
841 static INLINE int %(type_name)s_eq(%(type)s a, %(type)s b) {
842 return (a.real == b.real) & (a.imag == b.imag);
843 }
845 static INLINE %(type)s %(type_name)s_add(%(type)s a, %(type)s b) {
846 %(type)s z;
847 z.real = a.real + b.real;
848 z.imag = a.imag + b.imag;
849 return z;
850 }
852 static INLINE %(type)s %(type_name)s_sub(%(type)s a, %(type)s b) {
853 %(type)s z;
854 z.real = a.real - b.real;
855 z.imag = a.imag - b.imag;
856 return z;
857 }
859 static INLINE %(type)s %(type_name)s_mul(%(type)s a, %(type)s b) {
860 %(type)s z;
861 z.real = a.real * b.real - a.imag * b.imag;
862 z.imag = a.real * b.imag + a.imag * b.real;
863 return z;
864 }
866 static INLINE %(type)s %(type_name)s_div(%(type)s a, %(type)s b) {
867 %(type)s z;
868 %(real_type)s denom = b.real*b.real + b.imag*b.imag;
869 z.real = (a.real * b.real + a.imag * b.imag) / denom;
870 z.imag = (a.imag * b.real - a.real * b.imag) / denom;
871 return z;
872 }
874 static INLINE %(type)s %(type_name)s_neg(%(type)s a) {
875 %(type)s z;
876 z.real = -a.real;
877 z.imag = -a.imag;
878 return z;
879 }
881 #endif
882 """)
885 class CArrayType(CType):
886 # base_type CType Element type
887 # size integer or None Number of elements
889 is_array = 1
891 def __init__(self, base_type, size):
892 self.base_type = base_type
893 self.size = size
894 if base_type is c_char_type:
895 self.is_string = 1
897 def __repr__(self):
898 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
900 def same_as_resolved_type(self, other_type):
901 return ((other_type.is_array and
902 self.base_type.same_as(other_type.base_type))
903 or other_type is error_type)
905 def assignable_from_resolved_type(self, src_type):
906 # Can't assign to a variable of an array type
907 return 0
909 def element_ptr_type(self):
910 return c_ptr_type(self.base_type)
912 def declaration_code(self, entity_code,
913 for_display = 0, dll_linkage = None, pyrex = 0):
914 if self.size is not None:
915 dimension_code = self.size
916 else:
917 dimension_code = ""
918 if entity_code.startswith("*"):
919 entity_code = "(%s)" % entity_code
920 return self.base_type.declaration_code(
921 "%s[%s]" % (entity_code, dimension_code),
922 for_display, dll_linkage, pyrex)
924 def as_argument_type(self):
925 return c_ptr_type(self.base_type)
927 def is_complete(self):
928 return self.size is not None
931 class CPtrType(CType):
932 # base_type CType Referenced type
934 is_ptr = 1
935 default_value = "0"
937 def __init__(self, base_type):
938 self.base_type = base_type
940 def __repr__(self):
941 return "<CPtrType %s>" % repr(self.base_type)
943 def same_as_resolved_type(self, other_type):
944 return ((other_type.is_ptr and
945 self.base_type.same_as(other_type.base_type))
946 or other_type is error_type)
948 def declaration_code(self, entity_code,
949 for_display = 0, dll_linkage = None, pyrex = 0):
950 #print "CPtrType.declaration_code: pointer to", self.base_type ###
951 return self.base_type.declaration_code(
952 "*%s" % entity_code,
953 for_display, dll_linkage, pyrex)
955 def assignable_from_resolved_type(self, other_type):
956 if other_type is error_type:
957 return 1
958 if other_type.is_null_ptr:
959 return 1
960 if self.base_type.is_cfunction:
961 if other_type.is_ptr:
962 other_type = other_type.base_type.resolve()
963 if other_type.is_cfunction:
964 return self.base_type.pointer_assignable_from_resolved_type(other_type)
965 else:
966 return 0
967 if other_type.is_array or other_type.is_ptr:
968 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
969 return 0
972 class CNullPtrType(CPtrType):
974 is_null_ptr = 1
977 class CFuncType(CType):
978 # return_type CType
979 # args [CFuncTypeArg]
980 # has_varargs boolean
981 # exception_value string
982 # exception_check boolean True if PyErr_Occurred check needed
983 # calling_convention string Function calling convention
984 # nogil boolean Can be called without gil
985 # with_gil boolean Acquire gil around function body
987 is_cfunction = 1
988 original_sig = None
990 def __init__(self, return_type, args, has_varargs = 0,
991 exception_value = None, exception_check = 0, calling_convention = "",
992 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
993 self.return_type = return_type
994 self.args = args
995 self.has_varargs = has_varargs
996 self.optional_arg_count = optional_arg_count
997 self.exception_value = exception_value
998 self.exception_check = exception_check
999 self.calling_convention = calling_convention
1000 self.nogil = nogil
1001 self.with_gil = with_gil
1002 self.is_overridable = is_overridable
1004 def __repr__(self):
1005 arg_reprs = map(repr, self.args)
1006 if self.has_varargs:
1007 arg_reprs.append("...")
1008 return "<CFuncType %s %s[%s]>" % (
1009 repr(self.return_type),
1010 self.calling_convention_prefix(),
1011 ",".join(arg_reprs))
1013 def calling_convention_prefix(self):
1014 cc = self.calling_convention
1015 if cc:
1016 return cc + " "
1017 else:
1018 return ""
1020 def same_c_signature_as(self, other_type, as_cmethod = 0):
1021 return self.same_c_signature_as_resolved_type(
1022 other_type.resolve(), as_cmethod)
1024 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1025 #print "CFuncType.same_c_signature_as_resolved_type:", \
1026 # self, other_type, "as_cmethod =", as_cmethod ###
1027 if other_type is error_type:
1028 return 1
1029 if not other_type.is_cfunction:
1030 return 0
1031 if self.is_overridable != other_type.is_overridable:
1032 return 0
1033 nargs = len(self.args)
1034 if nargs != len(other_type.args):
1035 return 0
1036 # When comparing C method signatures, the first argument
1037 # is exempt from compatibility checking (the proper check
1038 # is performed elsewhere).
1039 for i in range(as_cmethod, nargs):
1040 if not self.args[i].type.same_as(
1041 other_type.args[i].type):
1042 return 0
1043 if self.has_varargs != other_type.has_varargs:
1044 return 0
1045 if self.optional_arg_count != other_type.optional_arg_count:
1046 return 0
1047 if not self.return_type.same_as(other_type.return_type):
1048 return 0
1049 if not self.same_calling_convention_as(other_type):
1050 return 0
1051 return 1
1053 def compatible_signature_with(self, other_type, as_cmethod = 0):
1054 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
1056 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
1057 #print "CFuncType.same_c_signature_as_resolved_type:", \
1058 # self, other_type, "as_cmethod =", as_cmethod ###
1059 if other_type is error_type:
1060 return 1
1061 if not other_type.is_cfunction:
1062 return 0
1063 if not self.is_overridable and other_type.is_overridable:
1064 return 0
1065 nargs = len(self.args)
1066 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
1067 return 0
1068 if self.optional_arg_count < other_type.optional_arg_count:
1069 return 0
1070 # When comparing C method signatures, the first argument
1071 # is exempt from compatibility checking (the proper check
1072 # is performed elsewhere).
1073 for i in range(as_cmethod, len(other_type.args)):
1074 if not self.args[i].type.same_as(
1075 other_type.args[i].type):
1076 return 0
1077 if self.has_varargs != other_type.has_varargs:
1078 return 0
1079 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1080 return 0
1081 if not self.same_calling_convention_as(other_type):
1082 return 0
1083 if self.nogil != other_type.nogil:
1084 return 0
1085 self.original_sig = other_type.original_sig or other_type
1086 if as_cmethod:
1087 self.args[0] = other_type.args[0]
1088 return 1
1091 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
1092 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
1094 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
1095 if other_type is error_type:
1096 return 1
1097 if not other_type.is_cfunction:
1098 return 0
1099 nargs = len(self.args)
1100 if nargs != len(other_type.args):
1101 return 0
1102 for i in range(as_cmethod, nargs):
1103 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
1104 return 0
1105 else:
1106 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
1107 or not self.args[i].type.same_as(other_type.args[i].type)
1108 if self.has_varargs != other_type.has_varargs:
1109 return 0
1110 if self.optional_arg_count != other_type.optional_arg_count:
1111 return 0
1112 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1113 return 0
1114 return 1
1116 def same_calling_convention_as(self, other):
1117 sc1 = self.calling_convention == '__stdcall'
1118 sc2 = other.calling_convention == '__stdcall'
1119 return sc1 == sc2
1121 def same_exception_signature_as(self, other_type):
1122 return self.same_exception_signature_as_resolved_type(
1123 other_type.resolve())
1125 def same_exception_signature_as_resolved_type(self, other_type):
1126 return self.exception_value == other_type.exception_value \
1127 and self.exception_check == other_type.exception_check
1129 def same_as_resolved_type(self, other_type, as_cmethod = 0):
1130 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1131 and self.same_exception_signature_as_resolved_type(other_type) \
1132 and self.nogil == other_type.nogil
1134 def pointer_assignable_from_resolved_type(self, other_type):
1135 return self.same_c_signature_as_resolved_type(other_type) \
1136 and self.same_exception_signature_as_resolved_type(other_type) \
1137 and not (self.nogil and not other_type.nogil)
1139 def declaration_code(self, entity_code,
1140 for_display = 0, dll_linkage = None, pyrex = 0,
1141 with_calling_convention = 1):
1142 arg_decl_list = []
1143 for arg in self.args[:len(self.args)-self.optional_arg_count]:
1144 arg_decl_list.append(
1145 arg.type.declaration_code("", for_display, pyrex = pyrex))
1146 if self.is_overridable:
1147 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1148 if self.optional_arg_count:
1149 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
1150 if self.has_varargs:
1151 arg_decl_list.append("...")
1152 arg_decl_code = ", ".join(arg_decl_list)
1153 if not arg_decl_code and not pyrex:
1154 arg_decl_code = "void"
1155 trailer = ""
1156 if (pyrex or for_display) and not self.return_type.is_pyobject:
1157 if self.exception_value and self.exception_check:
1158 trailer = " except? %s" % self.exception_value
1159 elif self.exception_value:
1160 trailer = " except %s" % self.exception_value
1161 elif self.exception_check == '+':
1162 trailer = " except +"
1163 else:
1164 " except *" # ignored
1165 if self.nogil:
1166 trailer += " nogil"
1167 if not with_calling_convention:
1168 cc = ''
1169 else:
1170 cc = self.calling_convention_prefix()
1171 if (not entity_code and cc) or entity_code.startswith("*"):
1172 entity_code = "(%s%s)" % (cc, entity_code)
1173 cc = ""
1174 return self.return_type.declaration_code(
1175 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
1176 for_display, dll_linkage, pyrex)
1178 def function_header_code(self, func_name, arg_code):
1179 return "%s%s(%s)" % (self.calling_convention_prefix(),
1180 func_name, arg_code)
1182 def signature_string(self):
1183 s = self.declaration_code("")
1184 return s
1186 def signature_cast_string(self):
1187 s = self.declaration_code("(*)", with_calling_convention=False)
1188 return '(%s)' % s
1191 class CFuncTypeArg(object):
1192 # name string
1193 # cname string
1194 # type PyrexType
1195 # pos source file position
1197 def __init__(self, name, type, pos, cname=None):
1198 self.name = name
1199 if cname is not None:
1200 self.cname = cname
1201 else:
1202 self.cname = Naming.var_prefix + name
1203 self.type = type
1204 self.pos = pos
1205 self.not_none = False
1206 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
1208 def __repr__(self):
1209 return "%s:%s" % (self.name, repr(self.type))
1211 def declaration_code(self, for_display = 0):
1212 return self.type.declaration_code(self.cname, for_display)
1215 class CStructOrUnionType(CType):
1216 # name string
1217 # cname string
1218 # kind string "struct" or "union"
1219 # scope StructOrUnionScope, or None if incomplete
1220 # typedef_flag boolean
1221 # packed boolean
1223 is_struct_or_union = 1
1224 has_attributes = 1
1226 def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
1227 self.name = name
1228 self.cname = cname
1229 self.kind = kind
1230 self.scope = scope
1231 self.typedef_flag = typedef_flag
1232 self.is_struct = kind == 'struct'
1233 if self.is_struct:
1234 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
1235 self.exception_check = True
1236 self._convert_code = None
1237 self.packed = packed
1239 def create_to_py_utility_code(self, env):
1240 if env.outer_scope is None:
1241 return False
1242 if self._convert_code is None:
1243 import Code
1244 code = Code.CCodeWriter()
1245 Code.GlobalState(code)
1246 header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s'))
1247 code.putln("%s {" % header)
1248 code.putln("PyObject* res;")
1249 code.putln("PyObject* member;")
1250 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
1251 for member in self.scope.var_entries:
1252 if member.type.to_py_function and member.type.create_to_py_utility_code(env):
1253 interned_name = env.get_string_const(member.name, identifier=True)
1254 env.add_py_string(interned_name)
1255 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
1256 member.type.to_py_function, member.cname))
1257 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % interned_name.pystring_cname)
1258 code.putln("Py_DECREF(member);")
1259 else:
1260 self.to_py_function = None
1261 return False
1262 code.putln("return res;")
1263 code.putln("bad:")
1264 code.putln("Py_XDECREF(member);")
1265 code.putln("Py_DECREF(res);")
1266 code.putln("return NULL;")
1267 code.putln("}")
1268 proto = header + ";"
1269 # This is a bit of a hack, we need a forward declaration
1270 # due to the way things are ordered in the module...
1271 entry = env.lookup(self.name)
1272 if entry.visibility != 'extern':
1273 proto = self.declaration_code('') + ';\n' + proto
1274 self._convert_code = UtilityCode(proto=proto, impl=code.buffer.getvalue())
1276 env.use_utility_code(self._convert_code)
1277 return True
1279 def __repr__(self):
1280 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1281 ("", " typedef")[self.typedef_flag])
1283 def declaration_code(self, entity_code,
1284 for_display = 0, dll_linkage = None, pyrex = 0):
1285 if pyrex:
1286 return self.base_declaration_code(self.name, entity_code)
1287 else:
1288 if for_display:
1289 base = self.name
1290 elif self.typedef_flag:
1291 base = self.cname
1292 else:
1293 base = "%s %s" % (self.kind, self.cname)
1294 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1296 def __cmp__(self, other):
1297 try:
1298 if self.name == other.name:
1299 return 0
1300 else:
1301 return 1
1302 except AttributeError:
1303 return 1
1305 def is_complete(self):
1306 return self.scope is not None
1308 def attributes_known(self):
1309 return self.is_complete()
1311 def can_be_complex(self):
1312 # Does the struct consist of exactly two floats?
1313 fields = self.scope.var_entries
1314 return len(fields) == 2 and fields[0].type.is_float and fields[1].type.is_float
1316 def struct_nesting_depth(self):
1317 child_depths = [x.type.struct_nesting_depth()
1318 for x in self.scope.var_entries]
1319 return max(child_depths) + 1
1321 class CEnumType(CType):
1322 # name string
1323 # cname string or None
1324 # typedef_flag boolean
1326 is_enum = 1
1327 signed = 1
1328 rank = -1 # Ranks below any integer type
1329 to_py_function = "PyInt_FromLong"
1330 from_py_function = "PyInt_AsLong"
1332 def __init__(self, name, cname, typedef_flag):
1333 self.name = name
1334 self.cname = cname
1335 self.values = []
1336 self.typedef_flag = typedef_flag
1338 def __str__(self):
1339 return self.name
1341 def __repr__(self):
1342 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1343 ("", " typedef")[self.typedef_flag])
1345 def declaration_code(self, entity_code,
1346 for_display = 0, dll_linkage = None, pyrex = 0):
1347 if pyrex:
1348 return self.base_declaration_code(self.cname, entity_code)
1349 else:
1350 if self.typedef_flag:
1351 base = self.cname
1352 else:
1353 base = "enum %s" % self.cname
1354 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1357 class CStringType(object):
1358 # Mixin class for C string types.
1360 is_string = 1
1361 is_unicode = 0
1363 to_py_function = "__Pyx_PyBytes_FromString"
1364 from_py_function = "__Pyx_PyBytes_AsString"
1365 exception_value = "NULL"
1367 def literal_code(self, value):
1368 assert isinstance(value, str)
1369 return '"%s"' % StringEncoding.escape_byte_string(value)
1372 class CUTF8CharArrayType(CStringType, CArrayType):
1373 # C 'char []' type.
1375 pymemberdef_typecode = "T_STRING_INPLACE"
1376 is_unicode = 1
1378 to_py_function = "PyUnicode_DecodeUTF8"
1379 exception_value = "NULL"
1381 def __init__(self, size):
1382 CArrayType.__init__(self, c_char_type, size)
1384 class CCharArrayType(CStringType, CArrayType):
1385 # C 'char []' type.
1387 pymemberdef_typecode = "T_STRING_INPLACE"
1389 def __init__(self, size):
1390 CArrayType.__init__(self, c_char_type, size)
1393 class CCharPtrType(CStringType, CPtrType):
1394 # C 'char *' type.
1396 pymemberdef_typecode = "T_STRING"
1398 def __init__(self):
1399 CPtrType.__init__(self, c_char_type)
1402 class UnspecifiedType(PyrexType):
1403 # Used as a placeholder until the type can be determined.
1405 def declaration_code(self, entity_code,
1406 for_display = 0, dll_linkage = None, pyrex = 0):
1407 return "<unspecified>"
1409 def same_as_resolved_type(self, other_type):
1410 return False
1413 class ErrorType(PyrexType):
1414 # Used to prevent propagation of error messages.
1416 is_error = 1
1417 exception_value = "0"
1418 exception_check = 0
1419 to_py_function = "dummy"
1420 from_py_function = "dummy"
1422 def create_to_py_utility_code(self, env):
1423 return True
1425 def create_from_py_utility_code(self, env):
1426 return True
1428 def declaration_code(self, entity_code,
1429 for_display = 0, dll_linkage = None, pyrex = 0):
1430 return "<error>"
1432 def same_as_resolved_type(self, other_type):
1433 return 1
1435 def error_condition(self, result_code):
1436 return "dummy"
1439 rank_to_type_name = (
1440 "char", # 0
1441 "short", # 1
1442 "int", # 2
1443 "long", # 3
1444 "Py_ssize_t", # 4
1445 "size_t", # 5
1446 "PY_LONG_LONG", # 6
1447 "float", # 7
1448 "double", # 8
1449 "long double", # 9
1452 py_object_type = PyObjectType()
1454 c_void_type = CVoidType()
1455 c_void_ptr_type = CPtrType(c_void_type)
1456 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1458 c_uchar_type = CIntType(0, 0, "T_UBYTE")
1459 c_ushort_type = CIntType(1, 0, "T_USHORT")
1460 c_uint_type = CUIntType(2, 0, "T_UINT")
1461 c_ulong_type = CULongType(3, 0, "T_ULONG")
1462 c_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG")
1464 c_char_type = CIntType(0, 1, "T_CHAR")
1465 c_short_type = CIntType(1, 1, "T_SHORT")
1466 c_int_type = CIntType(2, 1, "T_INT")
1467 c_long_type = CLongType(3, 1, "T_LONG")
1468 c_longlong_type = CLongLongType(6, 1, "T_LONGLONG")
1469 c_bint_type = CBIntType(2, 1, "T_INT")
1471 c_schar_type = CIntType(0, 2, "T_CHAR")
1472 c_sshort_type = CIntType(1, 2, "T_SHORT")
1473 c_sint_type = CIntType(2, 2, "T_INT")
1474 c_slong_type = CLongType(3, 2, "T_LONG")
1475 c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG")
1477 c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET")
1478 c_size_t_type = CSizeTType(5, 0, "T_SIZET")
1480 c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f')
1481 c_double_type = CFloatType(8, "T_DOUBLE")
1482 c_longdouble_type = CFloatType(9, math_h_modifier='l')
1484 c_double_complex_type = CComplexType(c_double_type)
1486 c_null_ptr_type = CNullPtrType(c_void_type)
1487 c_char_array_type = CCharArrayType(None)
1488 c_char_ptr_type = CCharPtrType()
1489 c_utf8_char_array_type = CUTF8CharArrayType(None)
1490 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1491 c_int_ptr_type = CPtrType(c_int_type)
1492 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
1493 c_size_t_ptr_type = CPtrType(c_size_t_type)
1495 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
1497 c_anon_enum_type = CAnonEnumType(-1, 1)
1499 # the Py_buffer type is defined in Builtin.py
1500 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1501 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1503 error_type = ErrorType()
1504 unspecified_type = UnspecifiedType()
1506 sign_and_rank_to_type = {
1507 #(signed, rank)
1508 (0, 0): c_uchar_type,
1509 (0, 1): c_ushort_type,
1510 (0, 2): c_uint_type,
1511 (0, 3): c_ulong_type,
1512 (0, 6): c_ulonglong_type,
1514 (1, 0): c_char_type,
1515 (1, 1): c_short_type,
1516 (1, 2): c_int_type,
1517 (1, 3): c_long_type,
1518 (1, 6): c_longlong_type,
1520 (2, 0): c_schar_type,
1521 (2, 1): c_sshort_type,
1522 (2, 2): c_sint_type,
1523 (2, 3): c_slong_type,
1524 (2, 6): c_slonglong_type,
1526 (0, 4): c_py_ssize_t_type,
1527 (1, 4): c_py_ssize_t_type,
1528 (2, 4): c_py_ssize_t_type,
1529 (0, 5): c_size_t_type,
1530 (1, 5): c_size_t_type,
1531 (2, 5): c_size_t_type,
1533 (1, 7): c_float_type,
1534 (1, 8): c_double_type,
1535 (1, 9): c_longdouble_type,
1536 # In case we're mixing unsigned ints and floats...
1537 (0, 7): c_float_type,
1538 (0, 8): c_double_type,
1539 (0, 9): c_longdouble_type,
1542 modifiers_and_name_to_type = {
1543 #(signed, longness, name)
1544 (0, 0, "char"): c_uchar_type,
1545 (0, -1, "int"): c_ushort_type,
1546 (0, 0, "int"): c_uint_type,
1547 (0, 1, "int"): c_ulong_type,
1548 (0, 2, "int"): c_ulonglong_type,
1549 (1, 0, "void"): c_void_type,
1550 (1, 0, "char"): c_char_type,
1551 (1, -1, "int"): c_short_type,
1552 (1, 0, "int"): c_int_type,
1553 (1, 1, "int"): c_long_type,
1554 (1, 2, "int"): c_longlong_type,
1555 (1, 0, "float"): c_float_type,
1556 (1, 0, "double"): c_double_type,
1557 (1, 1, "double"): c_longdouble_type,
1558 (1, 0, "object"): py_object_type,
1559 (1, 0, "bint"): c_bint_type,
1560 (2, 0, "char"): c_schar_type,
1561 (2, -1, "int"): c_sshort_type,
1562 (2, 0, "int"): c_sint_type,
1563 (2, 1, "int"): c_slong_type,
1564 (2, 2, "int"): c_slonglong_type,
1566 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1567 (0, 0, "size_t") : c_size_t_type,
1569 (1, 0, "long"): c_long_type,
1570 (1, 0, "short"): c_short_type,
1571 (1, 0, "longlong"): c_longlong_type,
1572 (1, 0, "bint"): c_bint_type,
1575 def widest_numeric_type(type1, type2):
1576 # Given two numeric types, return the narrowest type
1577 # encompassing both of them.
1578 if type1 == type2:
1579 return type1
1580 if type1.is_complex:
1581 if type2.is_complex:
1582 return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
1583 else:
1584 return CComplexType(widest_numeric_type(type1.real_type, type2))
1585 elif type2.is_complex:
1586 return CComplexType(widest_numeric_type(type1, type2.real_type))
1587 if type1.is_enum and type2.is_enum:
1588 return c_int_type
1589 elif type1 is type2:
1590 return type1
1591 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1592 if type2.rank > type1.rank:
1593 return type2
1594 else:
1595 return type1
1596 else:
1597 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1598 return widest_type
1600 def simple_c_type(signed, longness, name):
1601 # Find type descriptor for simple type given name and modifiers.
1602 # Returns None if arguments don't make sense.
1603 return modifiers_and_name_to_type.get((signed, longness, name))
1605 def parse_basic_type(name):
1606 base = None
1607 if name.startswith('p_'):
1608 base = parse_basic_type(name[2:])
1609 elif name.startswith('p'):
1610 base = parse_basic_type(name[1:])
1611 elif name.endswith('*'):
1612 base = parse_basic_type(name[:-1])
1613 if base:
1614 return CPtrType(base)
1615 elif name.startswith('u'):
1616 return simple_c_type(0, 0, name[1:])
1617 else:
1618 return simple_c_type(1, 0, name)
1620 def c_array_type(base_type, size):
1621 # Construct a C array type.
1622 if base_type is c_char_type:
1623 return CCharArrayType(size)
1624 elif base_type is error_type:
1625 return error_type
1626 else:
1627 return CArrayType(base_type, size)
1629 def c_ptr_type(base_type):
1630 # Construct a C pointer type.
1631 if base_type is c_char_type:
1632 return c_char_ptr_type
1633 elif base_type is error_type:
1634 return error_type
1635 else:
1636 return CPtrType(base_type)
1638 def Node_to_type(node, env):
1639 from ExprNodes import NameNode, AttributeNode, StringNode, error
1640 if isinstance(node, StringNode):
1641 node = NameNode(node.pos, name=node.value)
1642 if isinstance(node, NameNode) and node.name in rank_to_type_name:
1643 return simple_c_type(1, 0, node.name)
1644 elif isinstance(node, (AttributeNode, NameNode)):
1645 node.analyze_types(env)
1646 if not node.entry.is_type:
1647 pass
1648 else:
1649 error(node.pos, "Bad type")
1651 def same_type(type1, type2):
1652 return type1.same_as(type2)
1654 def assignable_from(type1, type2):
1655 return type1.assignable_from(type2)
1657 def typecast(to_type, from_type, expr_code):
1658 # Return expr_code cast to a C type which can be
1659 # assigned to to_type, assuming its existing C type
1660 # is from_type.
1661 if to_type is from_type or \
1662 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
1663 return expr_code
1664 else:
1665 #print "typecast: to", to_type, "from", from_type ###
1666 return to_type.cast_code(expr_code)
1669 type_conversion_predeclarations = """
1670 /* Type Conversion Predeclarations */
1672 #if PY_MAJOR_VERSION < 3
1673 #define __Pyx_PyBytes_FromString PyString_FromString
1674 #define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
1675 #define __Pyx_PyBytes_AsString PyString_AsString
1676 #else
1677 #define __Pyx_PyBytes_FromString PyBytes_FromString
1678 #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
1679 #define __Pyx_PyBytes_AsString PyBytes_AsString
1680 #endif
1682 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
1683 static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
1684 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
1686 #if !defined(T_PYSSIZET)
1687 #if PY_VERSION_HEX < 0x02050000
1688 #define T_PYSSIZET T_INT
1689 #elif !defined(T_LONGLONG)
1690 #define T_PYSSIZET \\
1691 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1692 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
1693 #else
1694 #define T_PYSSIZET \\
1695 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1696 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\
1697 ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
1698 #endif
1699 #endif
1701 #if !defined(T_SIZET)
1702 #if !defined(T_ULONGLONG)
1703 #define T_SIZET \\
1704 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1705 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
1706 #else
1707 #define T_SIZET \\
1708 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1709 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\
1710 ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
1711 #endif
1712 #endif
1714 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
1715 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
1716 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
1718 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
1720 """ + type_conversion_predeclarations
1722 type_conversion_functions = """
1723 /* Type Conversion Functions */
1725 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
1726 if (x == Py_True) return 1;
1727 else if ((x == Py_False) | (x == Py_None)) return 0;
1728 else return PyObject_IsTrue(x);
1731 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
1732 PyNumberMethods *m;
1733 const char *name = NULL;
1734 PyObject *res = NULL;
1735 #if PY_VERSION_HEX < 0x03000000
1736 if (PyInt_Check(x) || PyLong_Check(x))
1737 #else
1738 if (PyLong_Check(x))
1739 #endif
1740 return Py_INCREF(x), x;
1741 m = Py_TYPE(x)->tp_as_number;
1742 #if PY_VERSION_HEX < 0x03000000
1743 if (m && m->nb_long) {
1744 name = "long";
1745 res = PyNumber_Long(x);
1747 else if (m && m->nb_int) {
1748 name = "int";
1749 res = PyNumber_Int(x);
1751 #else
1752 if (m && m->nb_int) {
1753 name = "int";
1754 res = PyNumber_Long(x);
1756 #endif
1757 if (res) {
1758 #if PY_VERSION_HEX < 0x03000000
1759 if (!PyInt_Check(res) && !PyLong_Check(res)) {
1760 #else
1761 if (!PyLong_Check(res)) {
1762 #endif
1763 PyErr_Format(PyExc_TypeError,
1764 "__%s__ returned non-%s (type %.200s)",
1765 name, name, Py_TYPE(res)->tp_name);
1766 Py_DECREF(res);
1767 return NULL;
1770 else if (!PyErr_Occurred()) {
1771 PyErr_SetString(PyExc_TypeError,
1772 "an integer is required");
1774 return res;
1777 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
1778 Py_ssize_t ival;
1779 PyObject* x = PyNumber_Index(b);
1780 if (!x) return -1;
1781 ival = PyInt_AsSsize_t(x);
1782 Py_DECREF(x);
1783 return ival;
1786 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
1787 #if PY_VERSION_HEX < 0x02050000
1788 if (ival <= LONG_MAX)
1789 return PyInt_FromLong((long)ival);
1790 else {
1791 unsigned char *bytes = (unsigned char *) &ival;
1792 int one = 1; int little = (int)*(unsigned char*)&one;
1793 return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
1795 #else
1796 return PyInt_FromSize_t(ival);
1797 #endif
1800 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
1801 unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
1802 if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
1803 return (size_t)-1;
1804 } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
1805 PyErr_SetString(PyExc_OverflowError,
1806 "value too large to convert to size_t");
1807 return (size_t)-1;
1809 return (size_t)val;
1812 """ + type_conversion_functions