Shadow.py 5.33 KB
Newer Older
Robert Bradshaw's avatar
Robert Bradshaw committed
1 2
# cython.* namespace for pure mode.

3 4
compiled = False

5 6 7
def empty_decorator(x):
    return x

Robert Bradshaw's avatar
Robert Bradshaw committed
8 9
# Function decorators

10 11 12
def locals(**arg_types):
    return empty_decorator

Robert Bradshaw's avatar
Robert Bradshaw committed
13 14 15 16 17 18 19 20
def inline(f, *args, **kwds):
  if isinstance(f, basestring):
    from Cython.Build.Inline import cython_inline
    return cython_inline(f, *args, **kwds)
  else:
    assert len(args) == len(kwds) == 0
    return f

Robert Bradshaw's avatar
Robert Bradshaw committed
21 22 23 24
def compile(f):
    from Cython.Build.Inline import RuntimeCompiledFunction
    return RuntimeCompiledFunction(f)

Robert Bradshaw's avatar
Robert Bradshaw committed
25 26 27 28 29 30 31 32 33 34 35 36 37
# Special functions

def cdiv(a, b):
    q = a / b
    if q < 0:
        q += 1

def cmod(a, b):
    r = a % b
    if (a*b) < 0:
        r -= b
    return r

38 39 40

# Emulated language constructs

41
def cast(type, arg):
42
    if hasattr(type, '__call__'):
43 44 45
        return type(arg)
    else:
        return arg
46

47 48
def sizeof(arg):
    return 1
49 50 51

def typeof(arg):
    return type(arg)
52 53 54 55
    
def address(arg):
    return pointer(type(arg))([arg])
    
Robert Bradshaw's avatar
Robert Bradshaw committed
56
def declare(type=None, value=None, **kwds):
57
    if type is not None and hasattr(type, '__call__'):
Robert Bradshaw's avatar
Robert Bradshaw committed
58 59 60 61
        if value:
            return type(value)
        else:
            return type()
62
    else:
Robert Bradshaw's avatar
Robert Bradshaw committed
63
        return value
64

65 66 67 68 69 70 71 72 73 74 75
class _nogil(object):
    """Support for 'with nogil' statement
    """
    def __enter__(self):
        pass
    def __exit__(self, exc_class, exc, tb):
        return exc_class is None

nogil = _nogil()
del _nogil

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
# Emulated types

class CythonType(object):

    def _pointer(self, n=1):
        for i in range(n):
            self = pointer(self)
        return self

    def __getitem__(self, ix):
        return array(self, ix)


class PointerType(CythonType):

    def __init__(self, value=None):
        if isinstance(value, ArrayType):
            self._items = [cast(self._basetype, a) for a in value._items]
        elif isinstance(value, list):
            self._items = [cast(self._basetype, a) for a in value]
        elif value is None:
            self._items = []
        else:
            raise ValueError
            
    def __getitem__(self, ix):
        if ix < 0:
103
            raise IndexError("negative indexing not allowed in C")
104 105 106 107
        return self._items[ix]
        
    def __setitem__(self, ix, value):
        if ix < 0:
108
            raise IndexError("negative indexing not allowed in C")
109 110 111 112 113 114 115 116 117 118 119
        self._items[ix] = cast(self._basetype, value)
        
class ArrayType(PointerType):
    
    def __init__(self):
        self._items = [None] * self._n


class StructType(CythonType):
    
    def __init__(self, **data):
120
        for key, value in data.iteritems():
121 122 123 124 125 126
            setattr(self, key, value)
            
    def __setattr__(self, key, value):
        if key in self._members:
            self.__dict__[key] = cast(self._members[key], value)
        else:
127
            raise AttributeError("Struct has no member '%s'" % key)
128 129 130 131 132 133
    

class UnionType(CythonType):

    def __init__(self, **data):
        if len(data) > 0:
134 135
            raise AttributeError("Union can only store one field at a time.")
        for key, value in data.iteritems():
136 137 138 139 140 141 142 143
            setattr(self, key, value)
            
    def __setattr__(self, key, value):
        if key in '__dict__':
            CythonType.__setattr__(self, key, value)
        elif key in self._members:
            self.__dict__ = {key: cast(self._members[key], value)}
        else:
144
            raise AttributeError("Union has no member '%s'" % key)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

def pointer(basetype):
    class PointerInstance(PointerType):
        _basetype = basetype
    return PointerInstance

def array(basetype, n):
    class ArrayInstance(ArrayType):
        _basetype = basetype
        _n = n
    return ArrayInstance

def struct(**members):
    class StructInstance(StructType):
        _members = members
160
    for key in members:
161 162 163 164 165 166
        setattr(StructInstance, key, None)
    return StructInstance

def union(**members):
    class UnionInstance(UnionType):
        _members = members
167
    for key in members:
168 169 170 171 172 173 174 175 176 177 178 179 180 181
        setattr(UnionInstance, key, None)
    return UnionInstance

class typedef(CythonType):

    def __init__(self, type):
        self._basetype = type
    
    def __call__(self, value=None):
        if value is not None:
            value = cast(self._basetype, value)
        return value
        

182

183 184 185 186 187
py_int = int
try:
    py_long = long
except NameError: # Py3
    py_long = int
188 189
py_float = float
py_complex = complex
190

191
try:
Stefan Behnel's avatar
Stefan Behnel committed
192
    # Python 3
193
    from builtins import set, frozenset
Stefan Behnel's avatar
Stefan Behnel committed
194
except ImportError:
195
    try:
Stefan Behnel's avatar
Stefan Behnel committed
196
        # Python 2.4+
197
        from __builtin__ import set, frozenset
Stefan Behnel's avatar
Stefan Behnel committed
198
    except ImportError:
199
        # Py 2.3
200
        from sets import Set as set, ImmutableSet as frozenset
201 202 203

# Predefined types

204
int_types = ['char', 'short', 'Py_UNICODE', 'int', 'long', 'longlong', 'Py_ssize_t', 'size_t']
205 206
float_types = ['longdouble', 'double', 'float']
complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex']
207
other_types = ['bint', 'void']
208

209 210 211 212
gs = globals()

for name in int_types:
    gs[name] = typedef(py_int)
213
    if name != 'Py_UNICODE' and not name.endswith('size_t'):
214 215
        gs['u'+name] = typedef(py_int)
        gs['s'+name] = typedef(py_int)
216
    
217 218 219 220 221 222
for name in float_types:
    gs[name] = typedef(py_float)

for name in complex_types:
    gs[name] = typedef(py_complex)

223 224 225
bint = typedef(bool)
void = typedef(int)

226
for t in int_types + float_types + complex_types + other_types:
227 228 229 230 231
    for i in range(1, 4):
        gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i)

void = typedef(None)
NULL = None