get rid of Py_TPFLAGS_HAVE_INDEX to fill typeobj.nb_index slot
[cython.git] / Cython / Shadow.py
1 compiled = False
2
3 def empty_decorator(x):
4     return x
5
6 def locals(**arg_types):
7     return empty_decorator
8
9 # Special functions
10
11 def cdiv(a, b):
12     q = a / b
13     if q < 0:
14         q += 1
15
16 def cmod(a, b):
17     r = a % b
18     if (a*b) < 0:
19         r -= b
20     return r
21
22
23 # Emulated language constructs
24
25 def cast(type, arg):
26     if hasattr(type, '__call__'):
27         return type(arg)
28     else:
29         return arg
30
31 def sizeof(arg):
32     return 1
33
34 def typeof(arg):
35     return type(arg)
36     
37 def address(arg):
38     return pointer(type(arg))([arg])
39     
40 def declare(type=None, value=None, **kwds):
41     if type is not None and hasattr(type, '__call__'):
42         if value:
43             return type(value)
44         else:
45             return type()
46     else:
47         return value
48
49 # Emulated types
50
51 class CythonType(object):
52
53     def _pointer(self, n=1):
54         for i in range(n):
55             self = pointer(self)
56         return self
57
58     def __getitem__(self, ix):
59         return array(self, ix)
60
61
62 class PointerType(CythonType):
63
64     def __init__(self, value=None):
65         if isinstance(value, ArrayType):
66             self._items = [cast(self._basetype, a) for a in value._items]
67         elif isinstance(value, list):
68             self._items = [cast(self._basetype, a) for a in value]
69         elif value is None:
70             self._items = []
71         else:
72             raise ValueError
73             
74     def __getitem__(self, ix):
75         if ix < 0:
76             raise IndexError("negative indexing not allowed in C")
77         return self._items[ix]
78         
79     def __setitem__(self, ix, value):
80         if ix < 0:
81             raise IndexError("negative indexing not allowed in C")
82         self._items[ix] = cast(self._basetype, value)
83         
84 class ArrayType(PointerType):
85     
86     def __init__(self):
87         self._items = [None] * self._n
88
89
90 class StructType(CythonType):
91     
92     def __init__(self, **data):
93         for key, value in data.iteritems():
94             setattr(self, key, value)
95             
96     def __setattr__(self, key, value):
97         if key in self._members:
98             self.__dict__[key] = cast(self._members[key], value)
99         else:
100             raise AttributeError("Struct has no member '%s'" % key)
101     
102
103 class UnionType(CythonType):
104
105     def __init__(self, **data):
106         if len(data) > 0:
107             raise AttributeError("Union can only store one field at a time.")
108         for key, value in data.iteritems():
109             setattr(self, key, value)
110             
111     def __setattr__(self, key, value):
112         if key in '__dict__':
113             CythonType.__setattr__(self, key, value)
114         elif key in self._members:
115             self.__dict__ = {key: cast(self._members[key], value)}
116         else:
117             raise AttributeError("Union has no member '%s'" % key)
118
119 def pointer(basetype):
120     class PointerInstance(PointerType):
121         _basetype = basetype
122     return PointerInstance
123
124 def array(basetype, n):
125     class ArrayInstance(ArrayType):
126         _basetype = basetype
127         _n = n
128     return ArrayInstance
129
130 def struct(**members):
131     class StructInstance(StructType):
132         _members = members
133     for key in members:
134         setattr(StructInstance, key, None)
135     return StructInstance
136
137 def union(**members):
138     class UnionInstance(UnionType):
139         _members = members
140     for key in members:
141         setattr(UnionInstance, key, None)
142     return UnionInstance
143
144 class typedef(CythonType):
145
146     def __init__(self, type):
147         self._basetype = type
148     
149     def __call__(self, value=None):
150         if value is not None:
151             value = cast(self._basetype, value)
152         return value
153         
154
155
156 py_int = int
157 try:
158     py_long = long
159 except NameError: # Py3
160     py_long = int
161 py_float = float
162 py_complex = complex
163
164 try:
165     # Python 3
166     from builtins import set, frozenset
167 except ImportError:
168     try:
169         # Python 2.4+
170         from __builtin__ import set, frozenset
171     except ImportError:
172         # Py 2.3
173         from sets import Set as set, ImmutableSet as frozenset
174
175 # Predefined types
176
177 int_types = ['char', 'short', 'Py_UNICODE', 'int', 'long', 'longlong', 'Py_ssize_t', 'size_t']
178 float_types = ['longdouble', 'double', 'float']
179 complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex']
180 other_types = ['bint', 'void']
181
182 gs = globals()
183
184 for name in int_types:
185     gs[name] = typedef(py_int)
186     if name != 'Py_UNICODE' and not name.endswith('size_t'):
187         gs['u'+name] = typedef(py_int)
188         gs['s'+name] = typedef(py_int)
189     
190 for name in float_types:
191     gs[name] = typedef(py_float)
192
193 for name in complex_types:
194     gs[name] = typedef(py_complex)
195
196 bint = typedef(bool)
197 void = typedef(int)
198
199 for t in int_types + float_types + complex_types + other_types:
200     for i in range(1, 4):
201         gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i)
202
203 void = typedef(None)
204 NULL = None