예제 #1
0
class IndexedSeq(ASeq):
    _type = id_gen.next_id()

    def type(self):
        return self._type

    def __init__(self, v, idx, meta=nil):
        ASeq.__init__(meta)
        self._v = v
        self._idx = idx

    def rt_first(self):
        return RT.nth.invoke1(self._v, wrap_int(self._idx))

    def rt_next(self):
        ## todo cast int
        if self._idx + 1 < RT.count.invoke1()._int_value:
            return IndexedSeq(self._v, self._idx + 1)
        return nil

    def rt_index(self):
        return wrap_int(self._idx)

    def rt_count(self):
        return wrap_int(RT.count.invoke1(self._v)._int_value - 1)

    def rt_with_meta(self, meta):
        return IndexedSeq(self._v, self._idx, meta)

    def rt_meta(self, meta):
        return self._meta
예제 #2
0
class Namespace(Object):
    _type = id_gen.next_id()
    def type(self):
        return Namespace._type

    def __init__(self, name):
        assert isinstance(name, Symbol)
        self._name = name
        self._vars = {}

    def _str_for_name(self, name):
        assert isinstance(name, Symbol)
        return UT.name(name)._str_value

    def find_var(self, name):
        assert isinstance(name, Symbol)
        if UT.namespace(name) is not nil:
            raise ValueError("Var names cannot have namespaces")

        return self._vars.get(name, self._str_for_name(name))

    def find_or_create_var(self, name):
        assert isinstance(name, Symbol)
        var = self.find_var(name)
        if var is not None:
            return var

        sname = self._str_for_name(name)
        var = Var(name)
        self._vars[sname] = var

        return var
예제 #3
0
파일: fn.py 프로젝트: gyim/clojure-metal
class PolymorphicFn(IFn):
    _type = id_gen.next_id()
    def __init__(self, name, protocol):
        self._name = name
        self._table = {}
        self._protocol = protocol

    def type(self):
        return PolymorphicFn._type

    def extend(self, tp, fn):
        self._table[tp] = fn
        self._protocol.extend(tp)

    def invoke1(self, a):
        f = self._table[a.type()]
        return f.invoke1(a)

    def invoke2(self, a, b):
        f = self._table[a.type()]
        return f.invoke2(a, b)

    def invoke3(self, a, b, c):
        f = self._table[a.type()]
        return f.invoke3(a, b, c)
예제 #4
0
class String(Object):
    _type = id_gen.next_id()

    def type(self):
        return String._type

    def __init__(self, str_value):
        self._str_value = str_value

    def get_str_value(self):
        return self._str_value

    def rt_name(self):
        return self._str_value

    def rt_namespace(self):
        return nil

    def rt_hash(self):
        return wrap_int(int(hash_int(r_uint32(hash(self._str_value)))))

    def rt_equiv(self, other):
        if not isinstance(other, String):
            return false
        return true if self._str_value is other._str_value else false
예제 #5
0
class WInt(Object):
    _type = id_gen.next_id()
    def type(self):
        return WInt._type

    def __init__(self, int_value):
        self._int_value = int_value
예제 #6
0
class WBigInt(Object):
    _type = id_gen.next_id()

    def type(self):
        return WBigInt._type

    def __init__(self, bigint_value):
        self._bigint_value = bigint_value
예제 #7
0
class Var(Object):
    _type = id_gen.next_id()
    def type(self):
        return Var._type

    def __init__(self, sym):
        self._sym = sym
        self._root = None
예제 #8
0
파일: cons.py 프로젝트: gyim/clojure-metal
class Cons(ASeq):
    def __init__(self, first, more, meta=nil):
        ASeq.__init__(self)
        self._first = first
        self._more = more
        self._meta = meta

    _type = id_gen.next_id()

    def type(self):
        return Cons._type
예제 #9
0
class LazySeq(ASeq):
    _type = id_gen.next_id()

    def type(self):
        return LazySeq._type

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

    def rt_with_meta(self, meta):
        return LazySeq(self._fn, self._meta)

    def rt_meta(self):
        return self._meta

    ## TODO: syncronize?
    def sval(self):
        if self._fn is not None:
            self._sv = self._fn.invoke0()
            self._fn = None
        if self._sv is not None:
            return self._sv
        return self._s

    ## TODO: syncronize?
    def rt_seq(self):
        self.sval()
        if self._sv is not None:
            ls = self._sv
            self._sv = None
            while isinstance(ls, LazySeq):
                ls = ls.sval()
            self._s = RT.seq.invoke1(ls)
        return self._s

    def rt_first(self):
        self.seq()
        if self._s is None:
            return nil
        return RT.first.invoke1(self._s)

    def rt_next(self):
        self.seq()
        if self._s is None:
            return nil
        return RT.next.invoke1(self._s)
예제 #10
0
class Array(Object):
    _type = id_gen.next_id()
    def type(self):
        return Array._type

    def __init__(self, lst_w):
        self._lst_w = lst_w

    def count(self):
        return len(self._lst_w)

    def set(self, idx, val):
        self._lst_w[idx] = val

    def get(self, idx):
        if 0 >= idx < len(self._lst_w):
            return self._lst_w[idx]
        raise IndexOutOfBoundsException()
예제 #11
0
class Symbol(Object):
    _type = id_gen.next_id()
    def type(self):
        return Symbol._type

    def __init__(self, ns, name):
        self._name = name
        self._ns = ns

    def rt_name(self):
        return self._name

    def rt_namespace(self):
        return self._ns

    def rt_hash(self):
        h = hash_combine(r_uint32(UT.hash(self._name)._int_value), r_uint32(UT.hash(self._ns)._int_value))
        return wrap_int(int(h))

    def rt_equiv(self, other):
        if not isinstance(other, Symbol):
            return false
        return true if self._name is other._name and \
                    self._ns is other._ns else false
예제 #12
0
파일: fn.py 프로젝트: gyim/clojure-metal
class AFn(IFn):
    def type(self):
        return AFn._type
    _type = id_gen.next_id()
예제 #13
0
class PersistentVector(Object):
    _type = id_gen.next_id()

    def type(self):
        return PersistentVector._type

    def __init__(self, meta, cnt, shift, root, tail):
        self._meta = meta
        self._cnt = cnt
        self._shift = shift
        self._root = root
        self._tail = tail

    def tailoff(self):
        if (self._cnt < 32):
            return 0
        return ((self._cnt - 1) >> 5) << 5

    def array_for(self, i):
        if i >= 0 and i < self._cnt:
            if i >= self.tailoff():
                return self._tail
            node = self._root
            level = self._shift
            while level > 0:
                node = node._array[(i >> level) & 0x1f]
                level -= 5
            return node._array
        raise IndexOutOfBoundsException()

    def nth(self, i, not_found=None):
        if not_found is not None:
            if 0 <= i < self._cnt:
                return self.nth(i, None)
            return not_found
        else:
            node = self.array_for(i)
            return node[i & 0x01f]

    def assoc_n(self, i, val):
        if 0 <= i < self._cnt:
            if i >= self.tailoff():
                new_tail = self._tail[:]
                new_tail[i & 0x1f] = val
                return PersistentVector(self._meta, self._cnt, self._shift,
                                        self._root, new_tail)
            new_root = self.do_assoc(self._shift, self._root, i, val)
            return PersistentVector(self._meta, self._cnt, self._shift,
                                    new_root, self._tail)

        if i == self._cnt:
            return self.cons(val)

        raise IndexOutOfBoundsException()

    def do_assoc(self, level, node, i, val):
        ret = Node(node._edit, node._array[:])
        if level == 0:
            ret._array[i & 0x01f] = val
        else:
            subidx = (i >> level) & 0x1f
            ret._array[subidx] = self.do_assoc(level - 5, node._array[subidx],
                                               i, val)
        return ret

    def count(self):
        return self._cnt

    def with_meta(self, meta):
        return PersistentVector(meta, self._cnt, self._shift, self._root,
                                self._tail)

    def meta(self):
        return self._meta

    def cons(self, val):
        i = self._cnt
        if self._cnt - self.tailoff() < 32:
            new_tail = self._tail[:]
            new_tail.append(val)
            return PersistentVector(self._meta, self._cnt + 1, self._shift,
                                    self._root, new_tail)

        tail_node = Node(self._root._edit, self._tail)
        new_shift = self._shift
        if (self._cnt >> 5) > (1 << self._shift):
            new_root = Node(self._root._edit)
            new_root._array[0] = self._root
            new_root._array[1] = self.new_path(self._root._edit, self._shift,
                                               tail_node)
            new_shift += 5

        else:
            new_root = self.push_tail(self._shift, self._root, tail_node)

        return PersistentVector(self._meta, self._cnt + 1, new_shift, new_root,
                                [val])

    def push_tail(self, level, parent, tail_node):
        sub_idx = ((self._cnt - 1) >> level) & 0x01f
        ret = Node(parent._edit, parent._array[:])
        if level == 5:
            node_to_insert = tail_node
        else:
            child = parent._array[sub_idx]
            if child is not None:
                node_to_insert = self.push_tail(level - 5, child, tail_node)
            else:
                node_to_insert = self.new_path(self._root._edit, level - 5,
                                               tail_node)

        ret._array[sub_idx] = node_to_insert
        return ret

    def new_path(self, edit, level, node):
        if level == 0:
            return node
        ret = Node(edit)
        ret._array[0] = self.new_path(edit, level - 5, node)
        return ret

    def rt_conj(self, b):
        return self.cons(b)