Beispiel #1
0
class LinePromise(object.Object):
    _type = object.Type(u"pixie.stdlib.LinePromise")

    def type(self):
        return LinePromise._type

    def __init__(self):
        self._chrs = []
        self._str = None

    def add_char(self, ch):
        self._chrs.append(ch)

    def finalize(self):
        if self._chrs is not None:
            self._str = u"".join(self._chrs)
            self._chrs = None

    def is_finalized(self):
        return self._chrs is None

    def __repr__(self):
        if self.is_finalized():
            return self._str
        return u"".join(self._chrs)
Beispiel #2
0
class Symbol(object.Object):
    _type = object.Type(u"pixie.stdlib.Symbol")
    __immutable_fields__ = ["_hash"]

    def __init__(self, s, meta=nil):
        #assert isinstance(s, unicode)
        self._str = s
        self._w_name = None
        self._w_ns = None
        self._hash = 0
        self._meta = meta

    def type(self):
        return Symbol._type

    def init_names(self):
        if self._w_name is None:
            s = self._str.split(u"/")
            if len(s) == 2:
                self._w_ns = rt.wrap(s[0])
                self._w_name = rt.wrap(s[1])
            elif len(s) == 1:
                self._w_name = rt.wrap(s[0])
                self._w_ns = nil
            else:
                self._w_ns = rt.wrap(s[0])
                self._w_name = rt.wrap(u"/".join(s[1:]))

    def with_meta(self, meta):
        return Symbol(self._str, meta)

    def meta(self):
        return self._meta
Beispiel #3
0
class CCallback(PointerType):
    _type = object.Type(u"pixie.ffi.CCallback")

    def __init__(self, cft, raw_closure, id, fn):
        self._fn = fn
        self._cft = cft
        self._raw_closure = raw_closure
        self._is_invoked = False
        self._unique_id = id

    def type(self):
        return CCallback._type

    def get_raw_closure(self):
        return self._raw_closure

    def ll_invoke(self, llargs, llres):
        cft = self._cft
        assert isinstance(cft, CFunctionType)

        args = [None] * len(cft._arg_types)
        for i, tp in enumerate(cft._arg_types):
            args[i] = tp.ffi_get_value(llargs[i])

        self._is_invoked = True
        retval = self._fn.invoke(args)
        if cft._ret_type is not cvoid:
            cft._ret_type.ffi_set_value(llres, retval)

    def cleanup(self):
        del registered_callbacks[self._unique_id]
        clibffi.closureHeap.free(self._raw_closure)
Beispiel #4
0
class CFunctionType(object.Type):
    base_type = object.Type(u"pixie.ffi.CType")
    _immutable_fields_ = ["_arg_types", "_ret-type", "_cd"]

    def __init__(self, arg_types, ret_type):
        object.Type.__init__(self, name_gen.next(), CStructType.base_type)
        self._arg_types = arg_types
        self._ret_type = ret_type
        self._cd = CifDescrBuilder(self._arg_types,
                                   self._ret_type).rawallocate()

    def ffi_get_value(self, ptr):
        runtime_error(u"Cannot get a callback value via FFI")

    def ffi_set_value(self, ptr, val):
        affirm(isinstance(val, CCallback),
               u"Can only encode CCallbacks as function pointers")

        casted = rffi.cast(rffi.VOIDPP, ptr)
        casted[0] = val.get_raw_closure()

        return None

    def get_cd(self):
        return self._cd

    def ffi_size(self):
        return rffi.sizeof(rffi.VOIDP)

    def ffi_type(self):
        return clibffi.ffi_type_pointer
Beispiel #5
0
class LazySeq(object.Object):
    _type = object.Type(u"pixie.stdlib.LazySeq")

    def type(self):
        return LazySeq._type

    def __init__(self, fn, meta=nil):
        self._fn = fn
        self._meta = meta
        self._s = nil

    @jit.jit_callback("lazy_seq_sval")
    def sval(self):
        if self._fn is None:
            return self._s
        else:
            self._s = self._fn.invoke([])
            self._fn = None
            return self._s

    @jit.dont_look_inside
    def lazy_seq_seq(self):
        self.sval()
        if self._s is not nil:
            ls = self._s
            while True:
                if isinstance(ls, LazySeq):
                    ls = ls.sval()
                    continue
                else:
                    self._s = ls
                    return rt.seq(self._s)
        else:
            return nil
Beispiel #6
0
class Protocol(object.Object):
    _type = object.Type(u"pixie.stdlib.Protocol")

    _immutable_fields_ = ["_rev?"]

    def type(self):
        return Protocol._type

    def __init__(self, name):
        self._name = name
        self._polyfns = {}
        self._satisfies = {}
        self._rev = 0

    def add_method(self, pfn):
        self._polyfns[pfn] = pfn

    def add_satisfies(self, tp):
        self._satisfies[tp] = tp
        self._rev += 1

    @elidable_promote()
    def _get_satisfies(self, tp, rev):
        return tp in self._satisfies

    def satisfies(self, tp):
        return self._get_satisfies(tp, self._rev)
Beispiel #7
0
class ArraySeq(object.Object):
    _type = object.Type(u"pixie.stdlib.ArraySeq")
    _immutable_fields_ = ["_idx", "_w_array"]

    def __init__(self, idx, array):
        self._idx = idx
        self._w_array = array

    def first(self):
        return rt.nth(self._w_array, rt.wrap(self._idx))

    def next(self):
        if self._idx < rt.count(self._w_array) - 1:
            return ArraySeq(self._idx + 1, self._w_array)
        else:
            return nil

    def reduce(self, f, init):
        for x in range(self._idx, rt.count(self._w_array)):
            if rt.reduced_QMARK_(init):
                return rt.deref(init)
            init = f.invoke([init, rt.nth(self._w_array, rt.wrap(x))])
        return init

    def type(self):
        return self._type
Beispiel #8
0
class Buffer(object.Object):
    """ Defines a byte buffer with non-gc'd (therefore non-movable) contents
    """
    _type = object.Type(u"pixie.stdlib.Buffer")

    def type(self):
        return Buffer._type

    def __init__(self, size):
        self._size = size
        self._used_size = 0
        self._buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor="raw")

    def __del__(self):
        lltype.free(self._buffer, flavor="raw")

    def set_used_size(self, size):
        self._used_size = size

    def buffer(self):
        return self._buffer

    def count(self):
        return self._used_size

    def nth_char(self, idx):
        assert isinstance(idx, int)
        return self._buffer[idx]

    def capacity(self):
        return self._size
Beispiel #9
0
class ByteArray(object.Object):
    _type = object.Type(u"pixie.stdlib.ByteArray")

    def __init__(self, size):
        self._cnt = size
        self._buffer = lltype.malloc(ARRAY_OF_UCHAR, size, flavor="raw")
        for x in range(size):
            self._buffer[x] = chr(0)

    def type(self):
        return ByteArray._type

    def __del__(self):
        lltype.free(self._buffer, flavor="raw")

    @jit.unroll_safe
    def reduce_small(self, f, init):
        for x in range(self._cnt):
            if rt.reduced_QMARK_(init):
                return rt.deref(init)
            init = f.invoke([init, rt.wrap(ord(self._buffer[x]))])
        return init

    def reduce_large(self, f, init):
        for x in range(self._cnt):
            if rt.reduced_QMARK_(init):
                return rt.deref(init)
            init = f.invoke([init, rt.wrap(ord(self._buffer[x]))])
        return init
Beispiel #10
0
class Code(BaseCode):
    """Interpreted code block. Contains consts and """
    _type = object.Type(u"pixie.stdlib.Code")
    _immutable_fields_ = ["_arity", "_consts[*]", "_bytecode", "_stack_size", "_meta"]

    def type(self):
        return Code._type

    def __init__(self, name, arity, bytecode, consts, stack_size, debug_points, meta=nil):
        BaseCode.__init__(self)
        self._arity = arity
        self._bytecode = bytecode
        self._consts = consts
        self._name = name
        self._stack_size = stack_size
        self._debug_points = debug_points
        self._meta = meta

    def with_meta(self, meta):
        return Code(self._name, self._arity, self._bytecode, self._consts, self._stack_size, self._debug_points, meta=meta)

    def get_debug_points(self):
        return self._debug_points

    def invoke(self, args):
        if len(args) == self.get_arity():
            return self.invoke_with(args, self)
        else:
            runtime_error(u"Invalid number of arguments " + unicode(str(len(args))) 
                          + u" for function '" + unicode(str(self._name)) + u"'. Expected "
                          + unicode(str(self.get_arity())),
                          u":pixie.stdlib/InvalidArityException")

    def invoke_with(self, args, this_fn):
        try:
            return interpret(self, args, self_obj=this_fn)
        except object.WrappedException as ex:
            ex._ex._trace.append(object.PixieCodeInfo(self._name))
            raise

    @elidable_promote()
    def get_arity(self):
        return self._arity
            
    @elidable_promote()
    def get_consts(self):
        return self._consts

    @elidable_promote()
    def get_bytecode(self):
        return self._bytecode

    @elidable_promote()
    def stack_size(self):
        return self._stack_size

    @elidable_promote()
    def get_base_code(self):
        return self
Beispiel #11
0
class Atom(object.Object):
    _type = object.Type(u"pixie.stdlib.Atom")

    def type(self):
        return Atom._type

    def __init__(self, boxed_value):
        self._boxed_value = boxed_value
Beispiel #12
0
class Nil(object.Object):
    _type = object.Type(u"pixie.stdlib.Nil")

    def __repr__(self):
        return u"nil"

    def type(self):
        return Nil._type
Beispiel #13
0
class Reduced(object.Object):
    _type = object.Type(u"pixie.stdlib.Reduced")

    def type(self):
        return Reduced._type

    def __init__(self, boxed_value):
        self._boxed_value = boxed_value
Beispiel #14
0
class Var(BaseCode):
    _type = object.Type(u"pixie.stdlib.Var")
    _immutable_fields_ = ["_rev?"]

    def type(self):
        return Var._type

    def __init__(self, ns, name):
        BaseCode.__init__(self)
        self._ns = ns
        self._name = name
        self._rev = 0
        self._root = undefined
        self._dynamic = False

    def set_root(self, o):
        affirm(o is not None, u"Invalid var set")
        self._rev += 1
        self._root = o
        return self

    def set_value(self, val):
        affirm(self._dynamic, u"Can't set the value of a non-dynamic var")
        _dynamic_vars.set_var_value(self, val)
        return self

    def set_dynamic(self):
        self._dynamic = True
        self._rev += 1

    def get_dynamic_value(self):
        return _dynamic_vars.get_var_value(self, self._root)

    @elidable_promote()
    def is_dynamic(self, rev):
        return self._dynamic

    @elidable_promote()
    def get_root(self, rev):
        return self._root

    def deref(self):
        if self.is_dynamic(self._rev):
            return self.get_dynamic_value()
        else:
            val = self.get_root(self._rev)
            affirm(val is not undefined,
                   u"Var " + self._name + u" is undefined")
            return val

    def is_defined(self):
        return self._root is not undefined

    def invoke_with(self, args, this_fn):
        return self.invoke(args)

    def invoke(self, args):
        return self.deref().invoke(args)
Beispiel #15
0
class Float(Number):
    _type = object.Type(u"pixie.stdlib.Float", Number._type)
    _immutable_fields_ = ["_float_val"]

    def __init__(self, f_val):
        self._float_val = f_val

    def float_val(self):
        return self._float_val
Beispiel #16
0
class Node(object.Object):
    _type = object.Type(u"pixie.stdlib.PersistentVectorNode")

    def type(self):
        return Node._type

    def __init__(self, edit, array=None):
        self._edit = edit
        self._array = [None] * 32 if array is None else array
Beispiel #17
0
class MapEntry(object.Object):
    _type = object.Type(u"pixie.stdlib.MapEntry")

    def type(self):
        return MapEntry._type

    def __init__(self, key, val):
        self._key = key
        self._val = val
Beispiel #18
0
class BigInteger(Number):
    _type = object.Type(u"pixie.stdlib.BigInteger", Number._type)
    _immutable_fields_ = ["_bigint_val"]

    def __init__(self, bi_val):
        self._bigint_val = bi_val

    def bigint_val(self):
        return self._bigint_val
Beispiel #19
0
class Code(BaseCode):
    """Interpreted code block. Contains consts and """
    _type = object.Type(u"pixie.stdlib.Code")
    __immutable_fields__ = ["_consts[*]", "_bytecode", "_stack_size", "_meta"]

    def type(self):
        return Code._type

    def __init__(self,
                 name,
                 bytecode,
                 consts,
                 stack_size,
                 debug_points,
                 meta=nil):
        BaseCode.__init__(self)
        self._bytecode = bytecode
        self._consts = consts
        self._name = name
        self._stack_size = stack_size
        self._debug_points = debug_points
        self._meta = meta

    def with_meta(self, meta):
        return Code(self._name, self._bytecode, self._consts, self._stack_size,
                    self._debug_points, meta)

    def get_debug_points(self):
        return self._debug_points

    def invoke(self, args):
        return self.invoke_with(args, self)

    def invoke_with(self, args, this_fn):
        try:
            return interpret(self, args, self_obj=this_fn)
        except object.WrappedException as ex:
            ex._ex._trace.append(object.PixieCodeInfo(self._name))
            raise

    @elidable_promote()
    def get_consts(self):
        return self._consts

    @elidable_promote()
    def get_bytecode(self):
        return self._bytecode

    @elidable_promote()
    def stack_size(self):
        return self._stack_size

    @elidable_promote()
    def get_base_code(self):
        return self
Beispiel #20
0
class MultiArityFn(BaseCode):
    _type = object.Type(u"pixie.stdlib.MultiArityFn")

    _immutable_fields_ = ["_arities[*]", "_required_arity", "_rest_fn"]

    def type(self):
        return MultiArityFn._type

    def __init__(self,
                 name,
                 arities,
                 required_arity=0,
                 rest_fn=None,
                 meta=nil):
        BaseCode.__init__(self)
        self._name = name
        self._arities = arities
        self._required_arity = required_arity
        self._rest_fn = rest_fn
        self._meta = meta

    def with_meta(self, meta):
        return MultiArityFn(self._name, self._arities, self._required_arity,
                            self._rest_fn, meta)

    @elidable_promote()
    def get_fn(self, arity):
        f = self._arities.get(arity, None)
        if f is not None:
            return f
        if self._rest_fn is not None and arity >= self._required_arity:
            return self._rest_fn

        acc = []
        sorted = TimSort(self.get_arities())
        sorted.sort()
        for x in sorted.list:
            acc.append(unicode(str(x)))

        if self._rest_fn:
            acc.append(unicode(str(self._rest_fn.required_arity())) + u"+")

        runtime_error(
            u"Wrong number of arguments " + unicode(str(arity)) +
            u" for function '" + unicode(self._name) + u"'. Expected " +
            join_last(acc, u"or"), u"pixie.stdlib/InvalidArityException")

    def get_arities(self):
        return self._arities.keys()

    def invoke(self, args):
        return self.invoke_with(args, self)

    def invoke_with(self, args, self_fn):
        return self.get_fn(len(args)).invoke_with(args, self_fn)
Beispiel #21
0
class PlatformReader(object.Object):
    _type = object.Type(u"PlatformReader")

    def read(self):
        assert False

    def unread(self):
        pass

    def reset_line(self):
        return self
Beispiel #22
0
class EmptyList(object.Object):
    _type = object.Type(u"pixie.stdlib.EmptyList")

    def __init__(self, meta=nil):
        self._meta = meta

    def meta(self):
        return self._meta

    def with_meta(self, meta):
        return EmptyList(meta)
Beispiel #23
0
class Atom(object.Object):
    _type = object.Type(u"pixie.stdlib.Atom")

    def with_meta(self, meta):
        return Atom(self._boxed_value, meta)

    def meta(self):
        return self._meta

    def __init__(self, boxed_value, meta=nil):
        self._boxed_value = boxed_value
        self._meta = meta
Beispiel #24
0
class Closure(BaseCode):
    _type = object.Type(u"pixie.stdlib.Closure")
    _immutable_fields_ = ["_closed_overs[*]", "_code", "_meta"]

    def type(self):
        return Closure._type

    def __init__(self, code, closed_overs, meta=nil):
        BaseCode.__init__(self)
        affirm(isinstance(code, Code),
               u"Code argument to Closure must be an instance of Code")
        self._code = code
        self._closed_overs = closed_overs
        self._meta = meta

    def with_meta(self, meta):
        return Closure(self._code, self._closed_overs, meta)

    def name(self):
        return None

    def invoke(self, args):
        return self.invoke_with(args, self)

    def invoke_with(self, args, self_fn):
        try:
            return interpret(self, args, self_obj=self_fn)
        except object.WrappedException as ex:
            code = self._code
            assert isinstance(code, Code)
            ex._ex._trace.append(object.PixieCodeInfo(code._name))
            raise

    def get_closed_over(self, idx):
        return self._closed_overs[idx]

    def get_consts(self):
        return self._code.get_consts()

    def get_bytecode(self):
        return self._code.get_bytecode()

    def stack_size(self):
        return self._code.stack_size()

    def get_closed_overs(self):
        return self._closed_overs

    def get_base_code(self):
        return self._code.get_base_code()

    def get_debug_points(self):
        return self._code.get_debug_points()
Beispiel #25
0
class Ratio(Number):
    _type = object.Type(u"pixie.stdlib.Ratio", Number._type)
    _immutable_fields_ = ["_numerator", "_denominator"]

    def __init__(self, numerator, denominator):
        assert numerator is not None and denominator is not None
        self._numerator = numerator
        self._denominator = denominator

    def numerator(self):
        return self._numerator

    def denominator(self):
        return self._denominator
Beispiel #26
0
class PersistentHashMap(object.Object):
    _type = object.Type(u"pixie.stdlib.PersistentHashMap")

    def type(self):
        return PersistentHashMap._type

    def __init__(self, cnt, root, meta=nil):
        self._cnt = cnt
        self._root = root
        self._meta = meta

    def meta(self):
        return self._meta

    def with_meta(self, meta):
        return PersistentHashMap(self._cnt, self._root, meta)

    def assoc(self, key, val):
        added_leaf = Box()

        new_root = (BitmapIndexedNode_EMPTY if self._root is None else self._root) \
                   .assoc_inode(r_uint(0), rt.hash(key) & MASK_32, key, val, added_leaf)

        if new_root is self._root:
            return self

        return PersistentHashMap(
            self._cnt if added_leaf._val is None else self._cnt + 1, new_root,
            self._meta)

    def val_at(self, key, not_found):
        return not_found if self._root is None else self._root.find(
            r_uint(0),
            rt.hash(key) & MASK_32, key, not_found)

    def without(self, key):
        if self._root is None:
            return self

        new_root = self._root.without_inode(0, rt.hash(key) & MASK_32, key)

        if new_root is self._root:
            return self
        return PersistentHashMap(self._cnt - 1, new_root, self._meta)

    def iter(self):
        if self._root is None:
            return empty_iterator
        else:
            return self._root.iter()
Beispiel #27
0
class INode(object.Object):
    _type = object.Type(u"pixie.stdlib.INode")

    def assoc_inode(self, shift, hash_val, key, val, added_leaf):
        pass

    def find(self, shift, hash_val, key, not_found):
        pass

    def reduce_inode(self, f, init):
        pass

    def without(self, shift, hash, key):
        pass
Beispiel #28
0
class NativeFn(BaseCode):
    """Wrapper for a native function"""
    _type = object.Type(u"pixie.stdlib.NativeFn")

    def __init__(self, doc=None):
        BaseCode.__init__(self)

    def invoke(self, args):
        return self.inner_invoke(args)

    def inner_invoke(self, args):
        raise NotImplementedError()

    def invoke_with(self, args, this_fn):
        return self.invoke(args)
Beispiel #29
0
class Integer(Number):
    _type = object.Type(u"pixie.stdlib.Integer", Number._type)
    _immutable_fields_ = ["_int_val"]

    def __init__(self, i_val):
        self._int_val = i_val

    def int_val(self):
        return self._int_val

    def r_uint_val(self):
        return r_uint(self._int_val)

    def promote(self):
        return Integer(jit.promote(self._int_val))
Beispiel #30
0
class ExternalLib(object.Object):
    _type = object.Type(u"pixie.stdlib.ExternalLib")

    def __init__(self, nm):
        assert isinstance(nm, unicode)
        self._name = nm
        self._is_inited = False
        self.load_lib()

    def load_lib(self):
        if not self._is_inited:
            load_paths = rt.deref(rt.deref(rt.load_paths))

            for x in range(rt.count(load_paths)):
                s = rffi.str2charp(str(rt.name(rt.nth(load_paths, rt.wrap(x)))) + "/" + str(self._name))
                try:
                    self._dyn_lib = dynload.dlopen(s)
                    self._is_inited = True
                except dynload.DLOpenError as ex:
                    continue
                finally:
                    rffi.free_charp(s)
                break

            if not self._is_inited:
                s = rffi.str2charp(str(self._name))
                try:
                    self._dyn_lib = dynload.dlopen(s)
                    self._is_inited = True
                except dynload.DLOpenError as ex:
                    raise object.runtime_error(u"Couldn't Load Library: " + self._name,
                                               u"pixie.stdlib/LibraryNotFoundException")
                finally:
                    rffi.free_charp(s)








    def get_fn_ptr(self, nm):
        assert isinstance(nm, unicode)
        s = rffi.str2charp(str(nm))
        sym = dynload.dlsym(self._dyn_lib, s)
        rffi.free_charp(s)
        return sym