merge in latest cython-devel
[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 address(arg):
35     return pointer(type(arg))([arg])
36     
37 def declare(type=None, value=None, **kwds):
38     if type is not None and hasattr(type, '__call__'):
39         if value:
40             return type(value)
41         else:
42             return type()
43     else:
44         return value
45
46 # Emulated types
47
48 class CythonType(object):
49
50     def _pointer(self, n=1):
51         for i in range(n):
52             self = pointer(self)
53         return self
54
55     def __getitem__(self, ix):
56         return array(self, ix)
57
58
59 class PointerType(CythonType):
60
61     def __init__(self, value=None):
62         if isinstance(value, ArrayType):
63             self._items = [cast(self._basetype, a) for a in value._items]
64         elif isinstance(value, list):
65             self._items = [cast(self._basetype, a) for a in value]
66         elif value is None:
67             self._items = []
68         else:
69             raise ValueError
70             
71     def __getitem__(self, ix):
72         if ix < 0:
73             raise IndexError("negative indexing not allowed in C")
74         return self._items[ix]
75         
76     def __setitem__(self, ix, value):
77         if ix < 0:
78             raise IndexError("negative indexing not allowed in C")
79         self._items[ix] = cast(self._basetype, value)
80         
81 class ArrayType(PointerType):
82     
83     def __init__(self):
84         self._items = [None] * self._n
85
86
87 class StructType(CythonType):
88     
89     def __init__(self, **data):
90         for key, value in data.iteritems():
91             setattr(self, key, value)
92             
93     def __setattr__(self, key, value):
94         if key in self._members:
95             self.__dict__[key] = cast(self._members[key], value)
96         else:
97             raise AttributeError("Struct has no member '%s'" % key)
98     
99
100 class UnionType(CythonType):
101
102     def __init__(self, **data):
103         if len(data) > 0:
104             raise AttributeError("Union can only store one field at a time.")
105         for key, value in data.iteritems():
106             setattr(self, key, value)
107             
108     def __setattr__(self, key, value):
109         if key in '__dict__':
110             CythonType.__setattr__(self, key, value)
111         elif key in self._members:
112             self.__dict__ = {key: cast(self._members[key], value)}
113         else:
114             raise AttributeError("Union has no member '%s'" % key)
115
116 def pointer(basetype):
117     class PointerInstance(PointerType):
118         _basetype = basetype
119     return PointerInstance
120
121 def array(basetype, n):
122     class ArrayInstance(ArrayType):
123         _basetype = basetype
124         _n = n
125     return ArrayInstance
126
127 def struct(**members):
128     class StructInstance(StructType):
129         _members = members
130     for key in members:
131         setattr(StructInstance, key, None)
132     return StructInstance
133
134 def union(**members):
135     class UnionInstance(UnionType):
136         _members = members
137     for key in members:
138         setattr(UnionInstance, key, None)
139     return UnionInstance
140
141 class typedef(CythonType):
142
143     def __init__(self, type):
144         self._basetype = type
145     
146     def __call__(self, value=None):
147         if value is not None:
148             value = cast(self._basetype, value)
149         return value
150         
151
152
153 py_float = float
154 py_int = int
155 try:
156     py_long = long
157 except NameError: # Py3
158     py_long = int
159
160
161 # Predefined types
162
163 int_types = ['char', 'short', 'int', 'long', 'longlong', 'Py_ssize_t'] 
164 float_types = ['double', 'float']
165 other_types = ['bint', 'Py_ssize_t', 'void']
166 gs = globals()
167
168 for name in int_types:
169     gs[name] = typedef(py_int)
170     gs['u'+name] = typedef(py_int)
171     
172 double = float = typedef(py_float)
173 bint = typedef(bool)
174 void = typedef(int)
175
176 for t in int_types + float_types + other_types:
177     for i in range(1, 4):
178         gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i)
179
180 void = typedef(None)
181 NULL = None