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)
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
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)
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
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
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)
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
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
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
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
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
class Nil(object.Object): _type = object.Type(u"pixie.stdlib.Nil") def __repr__(self): return u"nil" def type(self): return Nil._type
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
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)
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
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
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
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
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
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)
class PlatformReader(object.Object): _type = object.Type(u"PlatformReader") def read(self): assert False def unread(self): pass def reset_line(self): return self
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)
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
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()
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
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()
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
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)
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))
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