示例#1
0
def _merge__args(args):
    affirm(len(args) > 0, u"Merge takes at least one arg")
    x = 1
    acc = args[0]
    for x in range(1, len(args)):
        acc = rt._reduce(acc, merge_fn, args[x])
    return acc
示例#2
0
文件: code.py 项目: Xsan-21/pixie
 def wrapped_fn(self, args):
     affirm(len(args) == 2, u"Expected 2 arguments to " + fn_name)
     try:
         return fn(args[0], args[1])
     except object.WrappedException as ex:
         ex._ex._trace.append(object.NativeCodeInfo(fn_name))
         raise
示例#3
0
    def pop(self):
        self.ensure_editable()
        affirm(self._cnt != 0, u"Can't pop an empty vector")

        i = self._cnt - 1

        if i & 0x01f > 0:
            self._cnt -= 1
            return self

        new_tail = self.editable_array_for(self._cnt - 1)

        new_root = self.pop_tail(self._shift, self._root)
        new_shift = self._shift

        root = self._root
        assert isinstance(root, Node)

        if new_root is None:
            new_root = Node(root._edit)

        if self._shift > 5 and new_root._array[1] is None:
            new_root = self.ensure_node_editable(new_root._array[0])
            new_shift -= 5

        self._root = new_root
        self._shift = new_shift
        self._cnt -= 1
        self._tail = new_tail

        return self
示例#4
0
def compile_if(form, ctx):
    form = form.next()
    affirm(2 <= rt.count(form) <= 3, u"If must have either 2 or 3 forms")

    test = rt.first(form)
    form = rt.next(form)
    then = rt.first(form)
    form = rt.next(form)
    els = rt.first(form)

    ctx.disable_tail_call()
    compile_form(test, ctx)
    ctx.bytecode.append(code.COND_BR)
    ctx.sub_sp(1)
    sp1 = ctx.sp()
    cond_lbl = ctx.label()

    ctx.enable_tail_call()

    compile_form(then, ctx)
    ctx.bytecode.append(code.JMP)
    ctx.sub_sp(1)
    affirm(ctx.sp() == sp1, u"If branches stacks are unequal " + unicode(str(ctx.sp())) + u", " + unicode(str(sp1)))
    else_lbl = ctx.label()

    ctx.mark(cond_lbl)
    compile_form(els, ctx)

    ctx.mark(else_lbl)
示例#5
0
文件: code.py 项目: mengjues/pixie
 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
     affirm(False, u"Wrong number of args to fn")
示例#6
0
文件: code.py 项目: Xsan-21/pixie
 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
示例#7
0
def compile_let(form, ctx):
    form = next(form)
    bindings = rt.first(form)
    affirm(isinstance(bindings, PersistentVector), u"Bindings must be a vector")
    body = next(form)

    ctc = ctx.can_tail_call
    ctx.disable_tail_call()

    binding_count = 0
    for i in range(0, rt.count(bindings).int_val(), 2):
        binding_count += 1
        name = rt.nth(bindings, numbers.Integer(i))
        affirm(isinstance(name, symbol.Symbol), u"Let locals must be symbols")
        bind = rt.nth(bindings, numbers.Integer(i + 1))

        compile_form(bind, ctx)

        ctx.add_local(name._str, LetBinding(ctx.sp()))

    if ctc:
        ctx.enable_tail_call()

    while True:
        compile_form(rt.first(body), ctx)
        body = rt.next(body)

        if body is nil:
            break
        else:
            ctx.pop()

    ctx.bytecode.append(code.POP_UP_N)
    ctx.sub_sp(binding_count)
    ctx.bytecode.append(binding_count)
示例#8
0
文件: array.py 项目: StetHD/pixie
def _nth(self, idx):
    assert isinstance(self, Array)
    ival = idx.int_val()
    if ival < len(self.list()):
        return self.list()[ival]
    else:
        affirm(False, u"Index out of Range")
示例#9
0
文件: code.py 项目: Xsan-21/pixie
    def resolve(self, s, use_refers=True):
        import pixie.vm.symbol as symbol
        affirm(isinstance(s, symbol.Symbol), u"Must resolve symbols")
        ns = rt.namespace(s)
        name = rt.name(s)

        if ns is not None:
            refer = self._refers.get(ns, None)
            resolved_ns = None
            if refer is not None:
                resolved_ns = refer._namespace
            if resolved_ns is None:
                resolved_ns = _ns_registry.get(ns, None)
            if resolved_ns is None:
                affirm(False, u"Unable to resolve namespace: " + ns + u" inside namespace " + self._name)
        else:
            resolved_ns = self

        assert isinstance(resolved_ns, Namespace)

        var = resolved_ns._registry.get(name, None)
        if var is None and use_refers:
            for refer_nm in self._refers:
                refer = self._refers[refer_nm]
                if name in refer._refer_syms or refer._refer_all:
                    var = refer._namespace.resolve(symbol.Symbol(name), False)
                if var is not None:
                    return var
            return None
        return var
示例#10
0
文件: reader.py 项目: foodhype/pixie
    def syntax_quote(form):
        if isinstance(form, Symbol) and compiler.is_compiler_special(form):
            ret = rt.list(QUOTE, form)

        elif isinstance(form, Symbol):
            if rt.namespace(form) is None and rt.name(form).endswith("#"):
                gmap = rt.deref(GEN_SYM_ENV)
                affirm(gmap is not nil, u"Gensym literal used outside a syntax quote")
                gs = rt.get(gmap, form)
                if gs is nil:
                    gs = rt.symbol(rt.str(form, rt.wrap(u"__"), rt.gensym()))
                    GEN_SYM_ENV.set_value(rt.assoc(gmap, form, gs))
                form = gs
            else:
                var = rt.resolve_in(compiler.NS_VAR.deref(), form)
                if var is nil:
                    form = rt.symbol(rt.str(rt.wrap(rt.name(rt.deref(compiler.NS_VAR))), rt.wrap(u"/"), form))
                else:
                    form = rt.symbol(rt.str(rt.wrap(rt.namespace(var)), rt.wrap(u"/"), rt.str(rt.wrap(rt.name(var)))))
            ret = rt.list(QUOTE, form)
        elif is_unquote(form):
            ret = rt.first(rt.next(form))
        elif is_unquote_splicing(form):
            raise Exception("Unquote splicing not used inside list")
        elif rt.vector_QMARK_(form) is true:
            ret = rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(form))
        elif rt.seq_QMARK_(form) is true:
            ret = rt.list(APPLY, LIST, rt.cons(CONCAT, SyntaxQuoteReader.expand_list(rt.seq(form))))
        else:
            ret = rt.list(QUOTE, form)
        return ret
示例#11
0
def index_of3(a, sep, start):
    affirm(isinstance(start, Integer), u"Third argument must be an integer")
    start = start.int_val()
    if start >= 0:
        return rt.wrap(rt.name(a).find(rt.name(sep), start))
    else:
        runtime_error(u"Third argument must be a non-negative integer")
示例#12
0
def _extend(proto_fn, tp, fn):
    if not isinstance(proto_fn, PolymorphicFn):
        runtime_error(u"Fist argument to extend should be a PolymorphicFn not a " + proto_fn.type().name())

    affirm(isinstance(tp, Type) or isinstance(tp, Protocol), u"Second argument to extend must be a Type or Protocol")
    affirm(isinstance(fn, BaseCode), u"Last argument to extend must be a function")
    proto_fn.extend(tp, fn)
    return nil
示例#13
0
文件: code.py 项目: Xsan-21/pixie
 def intern_or_make(self, name):
     assert name is not None
     affirm(isinstance(name, unicode), u"Var names must be unicode")
     v = self._registry.get(name, None)
     if v is None:
         v = Var(self._name, name)
         self._registry[name] = v
     return v
示例#14
0
def index_of4(a, sep, start, end):
    affirm(isinstance(start, Integer) and isinstance(end, Integer), u"Third and fourth argument must be integers")
    start = start.int_val()
    end = end.int_val()
    if start >= 0 and end >= 0:
        return rt.wrap(rt.name(a).find(rt.name(sep), start, end))
    else:
        runtime_error(u"Third and fourth argument must be non-negative integers")
示例#15
0
文件: array.py 项目: Xsan-21/pixie
def _nth(self, idx):
    assert isinstance(self, ByteArray)
    affirm(isinstance(idx, Integer), u"Index must be an integer")
    ival = idx.r_uint_val()
    if 0 <= ival < self._cnt:
        return rt.wrap(ord(self._buffer[ival]))

    return nil
示例#16
0
文件: rt.py 项目: astridliu/pixie
 def wrap(x):
     if isinstance(x, int):
         return numbers.Integer(x)
     if isinstance(x, unicode):
         return String(x)
     #if isinstance(x, str):
     #    return String(unicode(x))
     affirm(False, u"Bad wrap")
示例#17
0
文件: stacklet.py 项目: StetHD/pixie
def new_handler(h, _):
    fn = global_state._val
    global_state._val = None
    h = global_state._th.switch(h)
    val = global_state._val
    fn.invoke([StackletHandle(h), val])
    affirm(False, u"TODO: What do we do now?")
    return h
示例#18
0
def substring3(a, start, end):
    affirm(isinstance(a, String), u"First argument must be a string")
    affirm(isinstance(start, Integer) and isinstance(end, Integer), u"Second and third argument must be integers")
    start = start.int_val()
    end = end.int_val()
    if start >= 0 and end >= 0:
        return rt.wrap(rt.name(a)[start:end])
    else:
        runtime_error(u"Second and third argument must be non-negative integers")
示例#19
0
    def nth(self, i, not_found=None):
        if 0 <= i < self._cnt:
            node = self.array_for(r_uint(i))
            return node[i & 0x01f]

        if not_found is None:
            affirm(False, u"Index out of Range")
        else:
            return not_found
示例#20
0
文件: code.py 项目: Xsan-21/pixie
def resize_list(lst, new_size):
    """'Resizes' a list, via reallocation and copy"""
    affirm(len(lst) < new_size, u"New list must be larger than old list")
    new_list = [None] * new_size
    i = r_uint(0)
    while i < len(lst):
        new_list[i] = lst[i]
        i += 1
    return new_list
示例#21
0
文件: array.py 项目: StetHD/pixie
def aslice(self, offset):
    affirm(isinstance(self, Array),     u"aset expects an Array as the first argument")
    affirm(isinstance(offset, Integer), u"aset expects an Integer as the second argument")

    offset = offset.int_val()
    if offset >= 0:
        return Array(self.list()[offset:])
    else:
        rt.throw(rt.wrap(u"offset must be an Integer >= 0"))
示例#22
0
    def _invoke(self, args):
        affirm(len(args) == 1, u"Only one arg to continuation allowed")
        global_state._from = global_state._to
        global_state._to = self
        global_state._op = OP_SWITCH
        global_state._val = args[0]
        global_state._h = global_state._th.switch(global_state._h)

        return global_state._val
示例#23
0
文件: stacklet.py 项目: StetHD/pixie
 def invoke(self, args):
     affirm(not self._used, u"Can only call a given stacklet handle once.")
     affirm(len(args) == 1, u"Only one arg should be handed to a stacklet handle")
     self._used = True
     global_state._val = args[0]
     new_h = StackletHandle(global_state._th.switch(self._stacklet_handle))
     val = global_state._val
     global_state._val = None
     return rt.vector(new_h, val)
示例#24
0
文件: code.py 项目: Xsan-21/pixie
 def invoke(self, args):
     affirm(len(args) >= 1, u"Wrong number of args")
     a = args[0].type()
     fn = self.get_protocol_fn(a, self._rev)
     try:
         return fn.invoke(args)
     except object.WrappedException as ex:
         ex._ex._trace.append(object.PolymorphicCodeInfo(self._name, args[0].type()))
         raise
示例#25
0
def _run_blocking__args(args):
    affirm(len(args) > 0, u"At least one arg must be supplied to blocking-call")
    fn = args[0]
    argc = len(args) - 1
    new_args = [None] * argc
    for x in range(argc):
        new_args[x] = args[x + 1]

    from pixie.vm.stacklet import execute_uv_func
    return execute_uv_func(RunFFIFunc(fn, new_args))
示例#26
0
def create_type(type_name, fields):
    affirm(isinstance(type_name, Keyword), u"Type name must be a keyword")

    acc = {}
    for i in range(rt.count(fields)):
        val = rt.nth(fields, rt.wrap(i))
        affirm(isinstance(val, Keyword), u"Field names must be keywords")
        acc[val] = i

    return CustomType(rt.name(type_name), acc)
示例#27
0
文件: code.py 项目: zen3d/pixie
 def invoke(self, args):
     affirm(len(args) >= 1, u"Wrong number of args")
     a = args[0].type()
     fn = self.get_protocol_fn(a, self._rev)
     try:
         return fn.invoke(args)
     except object.WrappedException as ex:
         ex._ex._trace.append(
             object.PolymorphicCodeInfo(self._name, args[0].type()))
         raise
示例#28
0
文件: code.py 项目: jmglov/pixie
 def resolve_ns(self, ns_alias):
     refer = self._refers.get(ns_alias, None)
     resolved_ns = None
     if refer is not None:
         resolved_ns = refer._namespace
     if resolved_ns is None:
         resolved_ns = _ns_registry.get(ns_alias, None)
     if resolved_ns is None:
         affirm(False, u"Unable to resolve namespace: " + ns_alias + u" inside namespace " + self._name)
     return resolved_ns
示例#29
0
def create_type(type_name, fields):
    affirm(isinstance(type_name, Keyword), u"Type name must be a keyword")

    acc = {}
    for i in range(rt.count(fields)):
        val = rt.nth(fields, rt.wrap(i))
        affirm(isinstance(val, Keyword), u"Field names must be keywords")
        acc[val] = i

    return CustomType(rt.name(type_name), acc)
示例#30
0
 def resolve_ns(self, ns_alias):
     refer = self._refers.get(ns_alias, None)
     resolved_ns = None
     if refer is not None:
         resolved_ns = refer._namespace
     if resolved_ns is None:
         resolved_ns = _ns_registry.get(ns_alias, None)
     if resolved_ns is None:
         affirm(False, u"Unable to resolve namespace: " + ns_alias + u" inside namespace " + self._name)
     return resolved_ns
示例#31
0
文件: stdlib.py 项目: rowhit/pixie
def type_satisfies(proto, type):
    affirm(isinstance(type, Type), u"type must be a Type")
    if proto.satisfies(type):
        return true
    elif type == Object._type:
        # top level type do not recurse
        return false
    elif type.parent():
        return type_satisfies(proto, type.parent())
    else:
        return false
示例#32
0
文件: string.py 项目: zen3d/pixie
def index_of4(a, sep, start, end):
    affirm(
        isinstance(start, Integer) and isinstance(end, Integer),
        u"Third and fourth argument must be integers")
    start = start.int_val()
    end = end.int_val()
    if start >= 0 and end >= 0:
        return rt.wrap(rt.name(a).find(rt.name(sep), start, end))
    else:
        runtime_error(
            u"Third and fourth argument must be non-negative integers")
示例#33
0
文件: array.py 项目: zen3d/pixie
def aslice(self, offset):
    affirm(isinstance(self, Array),
           u"aset expects an Array as the first argument")
    affirm(isinstance(offset, Integer),
           u"aset expects an Integer as the second argument")

    offset = offset.int_val()
    if offset >= 0:
        return Array(self.list()[offset:])
    else:
        rt.throw(rt.wrap(u"offset must be an Integer >= 0"))
示例#34
0
def compile_platform_eq(form, ctx):
    form = form.next()

    affirm(rt.count(form) == 2, u"TODO: REMOVE")
    while form is not nil:
        compile_form(form.first(), ctx)
        form = form.next()

    ctx.bytecode.append(code.EQ)
    ctx.sub_sp(1)
    return ctx
示例#35
0
文件: stacklet.py 项目: zen3d/pixie
 def invoke(self, args):
     affirm(not self._used, u"Can only call a given stacklet handle once.")
     affirm(
         len(args) == 1,
         u"Only one arg should be handed to a stacklet handle")
     self._used = True
     global_state._val = args[0]
     new_h = StackletHandle(global_state._th.switch(self._stacklet_handle))
     val = global_state._val
     global_state._val = None
     return rt.vector(new_h, val)
示例#36
0
文件: stdlib.py 项目: stuarth/pixie
def type_satisfies(proto, type):
    affirm(isinstance(type, Type), u"type must be a Type")
    if proto.satisfies(type):
        return true
    elif type == Object._type:
        # top level type do not recurse
        return false
    elif type.parent():
        return type_satisfies(proto, type.parent())
    else:
        return false
示例#37
0
def compile_ns(form, ctx):
    affirm(rt.count(form).int_val() == 2, u"ns only takes one argument, a symbol")

    nm = rt.first(rt.next(form))

    affirm(isinstance(nm, symbol.Symbol), u"Namespace name must be a symbol")

    str_name = rt.name(nm)

    NS_VAR.set_value(code._ns_registry.find_or_make(str_name))
    ctx.push_const(nil)
示例#38
0
def compile_platform_eq(form, ctx):
    form = form.next()

    affirm(rt.count(form) == 2, u"TODO: REMOVE")
    while form is not nil:
        compile_form(form.first(), ctx)
        form = form.next()

    ctx.bytecode.append(code.EQ)
    ctx.sub_sp(1)
    return ctx
示例#39
0
 def invoke(self, args):
     tp = args[0].type()
     assert isinstance(tp, object.Type)
     pfn = self._pfn
     if isinstance(pfn, PolymorphicFn):
         protocol = pfn._protocol
     elif isinstance(pfn, DoublePolymorphicFn):
         protocol = pfn._protocol
     else:
         assert False
     assert isinstance(protocol, Protocol)
     affirm(False, u"No override for " + tp._name + u" on " + self._pfn._name + u" in protocol " + protocol._name)
示例#40
0
文件: string.py 项目: zen3d/pixie
def substring3(a, start, end):
    affirm(isinstance(a, String), u"First argument must be a string")
    affirm(
        isinstance(start, Integer) and isinstance(end, Integer),
        u"Second and third argument must be integers")
    start = start.int_val()
    end = end.int_val()
    if start >= 0 and end >= 0:
        return rt.wrap(rt.name(a)[start:end])
    else:
        runtime_error(
            u"Second and third argument must be non-negative integers")
示例#41
0
def compile_var(form, ctx):
    form = rt.next(form)
    name = rt.first(form)

    affirm(isinstance(name, symbol.Symbol), u"var name must be a symbol")

    if rt.namespace(name) is not None:
        var = code._ns_registry.find_or_make(rt.namespace(name))
    else:
        var = NS_VAR.deref().intern_or_make(rt.name(name))

    ctx.push_const(var)
示例#42
0
def compile_ns(form, ctx):
    affirm(rt.count(form) == 2, u"ns only takes one argument, a symbol")

    nm = rt.first(rt.next(form))

    affirm(isinstance(nm, symbol.Symbol), u"Namespace name must be a symbol")

    str_name = rt.name(nm)

    NS_VAR.set_value(code._ns_registry.find_or_make(str_name))
    NS_VAR.deref().include_stdlib()
    ctx.push_const(nil)
示例#43
0
    def editable_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 = self.ensure_node_editable(node._array[(i >> level) & 0x1f])

                level -= 5
            return node._array

        affirm(False, u"Index out of bounds")
示例#44
0
def _extend(proto_fn, tp, fn):
    if not isinstance(proto_fn, PolymorphicFn):
        runtime_error(
            u"Fist argument to extend should be a PolymorphicFn not a " +
            proto_fn.type().name())

    affirm(
        isinstance(tp, Type) or isinstance(tp, Protocol),
        u"Second argument to extend must be a Type or Protocol")
    affirm(isinstance(fn, BaseCode),
           u"Last argument to extend must be a function")
    proto_fn.extend(tp, fn)
    return nil
示例#45
0
文件: stdlib.py 项目: rowhit/pixie
def load_ns(filename):
    import pixie.vm.string as string
    import pixie.vm.symbol as symbol

    if isinstance(filename, symbol.Symbol):
        affirm(
            rt.namespace(filename) is None,
            u"load-file takes a un-namespaced symbol")
        filename_str = rt.name(filename).replace(u".", u"/") + u".pxi"

        loaded_ns = code._ns_registry.get(rt.name(filename), None)
        if loaded_ns is not None:
            return loaded_ns
    else:
        affirm(isinstance(filename, string.String), u"Filename must be string")
        filename_str = rt.name(filename)

    paths = rt.deref(rt.deref(rt.load_paths))
    f = None
    for x in range(rt.count(paths)):
        path_x = rt.nth(paths, rt.wrap(x))
        affirm(isinstance(path_x, string.String),
               u"Contents of load-paths must be strings")
        full_path = path.join(str(rt.name(path_x)), str(filename_str))
        if path.isfile(full_path):
            f = full_path
            break

    if f is None:
        affirm(
            False, u"File '" + rt.name(filename) +
            u"' does not exist in any directory found in load-paths")
    else:
        rt.load_file(rt.wrap(f))
    return nil
示例#46
0
文件: stdlib.py 项目: rowhit/pixie
def _throw(ex):
    from pixie.vm.keyword import keyword
    if isinstance(ex, RuntimeException):
        raise WrappedException(ex)
    if rt._satisfies_QMARK_(IVector, ex):
        data = rt.nth(ex, rt.wrap(0))
        msg = rt.nth(ex, rt.wrap(1))
    elif rt._satisfies_QMARK_(ILookup, ex):
        data = rt._val_at(ex, keyword(u"data"), nil)
        msg = rt._val_at(ex, keyword(u"msg"), nil)
    else:
        affirm(False, u"Can only throw vectors, maps and exceptions")
        return nil
    raise WrappedException(RuntimeException(msg, data))
示例#47
0
    def array_for(self, i):
        if 0 <= i < self._cnt:
            if i >= self.tailoff():
                return self._tail

            node = self._root
            level = self._shift
            while level > 0:
                assert isinstance(node, Node)
                node = node._array[(i >> level) & 0x01f]
                level -= 5
            return node._array

        affirm(False, u"Index out of Range")
示例#48
0
 def deref(self):
     if self.is_dynamic():
         if we_are_translated():
             return self.get_dynamic_value()
         else:
             ## NOT RPYTHON
             if globals().has_key("_dynamic_vars"):
                 return self.get_dynamic_value()
             else:
                 return self.get_root(self._rev)
     else:
         val = self.get_root(self._rev)
         affirm(val is not undefined, u"Var " + self._name + u" is undefined")
         return val
示例#49
0
def compile_fn_body(name, args, body, ctx):
    new_ctx = Context(rt.name(name), rt.count(args), ctx)
    required_args = add_args(rt.name(name), args, new_ctx)
    bc = 0

    if name is not None:
        affirm(isinstance(name, symbol.Symbol),
               u"Function names must be symbols")
        #new_ctx.add_local(name._str, Self())

    arg_syms = EMPTY
    for x in range(rt.count(args)):
        sym = rt.nth(args, rt.wrap(x))
        if not rt.name(sym) == u"&":
            arg_syms = rt.conj(rt.conj(arg_syms, sym), sym)

    body = rt.list(rt.cons(LOOP, rt.cons(arg_syms, body)))

    #new_ctx.push_recur_point(FunctionRecurPoint())

    new_ctx.disable_tail_call()
    if body is nil:
        compile_form(body, new_ctx)
    else:
        while body is not nil:
            if rt.next(body) is nil:
                new_ctx.enable_tail_call()
            compile_form(rt.first(body), new_ctx)
            body = rt.next(body)
            if body is not nil:
                new_ctx.pop()

    new_ctx.bytecode.append(code.RETURN)
    closed_overs = new_ctx.closed_overs
    if len(closed_overs) == 0:
        ctx.push_const(new_ctx.to_code(required_args))
    else:
        ctx.push_const(new_ctx.to_code(required_args))
        for x in closed_overs:
            x.emit(ctx)
        ctx.bytecode.append(code.MAKE_CLOSURE)
        ctx.bytecode.append(r_uint(len(closed_overs)))
        ctx.sub_sp(len(closed_overs))

    if required_args >= 0:
        ctx.bytecode.append(code.MAKE_VARIADIC)
        ctx.bytecode.append(r_uint(required_args))

    return required_args, intmask(rt.count(args))
示例#50
0
def hashmap__args(args):
    affirm(len(args) & 0x1 == 0, u"hashmap requires even number of args")

    idx = 0
    acc = EMPTY

    while idx < len(args):
        key = args[idx]
        val = args[idx + 1]

        acc = acc.assoc(key, val)

        idx += 2

    return acc
示例#51
0
def make_multi_arity(frame, argc):
    d = {}
    required_arity = 0
    rest_fn = None
    for i in range(argc):
        a = frame.get_inst()
        if a & 256:
            affirm(rest_fn is None, u"Can't have multiple rest_fns")
            required_arity = a & 0xFF
            rest_fn = frame.pop()
        else:
            fn = frame.pop()
            d[a] = fn

    return code.MultiArityFn(d, required_arity, rest_fn)
示例#52
0
文件: compiler.py 项目: kgann/pixie
def add_args(name, args, ctx):
    required_args = -1
    local_idx = 0
    ctx.add_local(name, Self())
    for x in range(rt.count(args)):
        arg = rt.nth(args, rt.wrap(x))
        affirm(isinstance(arg, symbol.Symbol),
               u"Argument names must be symbols")
        if rt.name(arg) == u"&":

            required_args = intmask(x)
            continue
        ctx.add_local(rt.name(arg), Arg(local_idx))
        local_idx += 1
    return required_args
示例#53
0
 def invoke_with(self, args, self_fn):
     from pixie.vm.array import array
     argc = len(args)
     if self._required_arity == 0:
         return self._code.invoke_with([array(args)], self_fn)
     if argc == self._required_arity:
         new_args = resize_list(args, len(args) + 1)
         new_args[len(args)] = array([])
         return self._code.invoke_with(new_args, self_fn)
     elif argc > self._required_arity:
         start = slice_from_start(args, self._required_arity, 1)
         rest = slice_to_end(args, self._required_arity)
         start[self._required_arity] = array(rest)
         return self._code.invoke_with(start, self_fn)
     affirm(False, u"Got " + unicode(str(argc)) + u" arg(s) need at least " + unicode(str(self._required_arity)))
示例#54
0
文件: code.py 项目: mwfogleman/pixie
    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 = []
        for x in self._arities:
            acc.append(unicode(str(x)))

        if self._rest_fn:
            acc.append(u" or more")

        affirm(
            False, u"Wrong number of args to fn: got " + unicode(str(arity)) +
            u" expected " + u",".join(acc))
示例#55
0
文件: stdlib.py 项目: rowhit/pixie
def _load_file(filename, compile=False):
    from pixie.vm.string import String
    from pixie.vm.util import unicode_from_utf8
    import pixie.vm.reader as reader
    import pixie.vm.libs.pxic.writer as pxic_writer

    affirm(isinstance(filename, String), u"filename must be a string")
    filename = str(rt.name(filename))

    if filename.endswith(".pxic"):
        load_pxic_file(filename)
        return nil

    if path.isfile(filename + "c") and not compile:
        load_pxic_file(filename + "c")
        return nil

    affirm(path.isfile(filename), unicode(filename) + u" does not exist")

    f = open(filename)
    data = f.read()
    f.close()

    if data.startswith("#!"):
        newline_pos = data.find("\n")
        if newline_pos > 0:
            data = data[newline_pos:]

    if compile:
        pxic_f = open(filename + "c", "wb")
        wtr = pxic_writer.Writer(pxic_f, True)
        with code.bindings(PXIC_WRITER, pxic_writer.WriterBox(wtr)):
            rt.load_reader(
                reader.MetaDataReader(
                    reader.StringReader(unicode_from_utf8(data)),
                    unicode(filename)))
        wtr.finish()
        pxic_f.close()
    else:
        with code.bindings(PXIC_WRITER, nil):
            rt.load_reader(
                reader.MetaDataReader(
                    reader.StringReader(unicode_from_utf8(data)),
                    unicode(filename)))

    return nil
示例#56
0
def compile_def(form, ctx):
    form = rt.next(form)
    name = rt.first(form)
    form = rt.next(form)
    val = rt.first(form)

    affirm(isinstance(name, symbol.Symbol), u"Def'd name must be a symbol")

    var = NS_VAR.deref().intern_or_make(rt.name(name))

    if rt._val_at(rt.meta(name), DYNAMIC_KW, nil) is true:
        assert isinstance(var, code.Var)
        var.set_dynamic()

    ctx.push_const(var)
    compile_form(val, ctx)
    ctx.bytecode.append(code.SET_VAR)
    ctx.sub_sp(1)
示例#57
0
    def invoke(self, rdr, ch):
        nms = u""
        ch = rdr.read()
        if ch == u":":
            itm = read_inner(rdr, True)
            nms = rt.name(rt.ns.deref())
        else:
            rdr.unread()
            itm = read_inner(rdr, True)

        affirm(isinstance(itm, Symbol), u"Can't keyword quote a non-symbol")
        if nms:
            affirm(
                rt.namespace(itm) is None,
                u"Kewyword cannot have two namespaces")
            return keyword(rt.name(itm), nms)
        else:
            return keyword(rt.name(itm), rt.namespace(itm))
示例#58
0
文件: stdlib.py 项目: rowhit/pixie
def ns_aliases(ns):
    from pixie.vm.symbol import Symbol
    affirm(
        isinstance(ns, Namespace) or isinstance(ns, Symbol),
        u"ns must be a symbol or a namespace")

    if isinstance(ns, Symbol):
        ns = rt.the_ns(ns)
        if ns is nil:
            return nil

    if isinstance(ns, Namespace):
        m = rt.hashmap()
        for alias in ns._refers:
            refered_ns = ns._refers[alias]._namespace
            m = rt.assoc(m, rt.symbol(rt.wrap(alias)), refered_ns)
        return m

    return nil
示例#59
0
文件: stdlib.py 项目: rowhit/pixie
def ns_map(ns):
    from pixie.vm.symbol import Symbol
    affirm(
        isinstance(ns, Namespace) or isinstance(ns, Symbol),
        u"ns must be a symbol or a namespace")

    if isinstance(ns, Symbol):
        ns = rt.the_ns(ns)
        if ns is nil:
            return nil

    if isinstance(ns, Namespace):
        m = rt.hashmap()
        for name in ns._registry:
            var = ns._registry.get(name, nil)
            m = rt.assoc(m, rt.symbol(rt.wrap(name)), var)
        return m

    return nil
示例#60
0
def _div(n, d):
    assert isinstance(n, Integer) and isinstance(d, Integer)
    nv = n.int_val()
    dv = d.int_val()
    object.affirm(dv != 0, u"Divide by zero")
    g = gcd(nv, dv)
    if g == 0:
        return rt.wrap(0)
    nv = nv / g
    dv = dv / g
    if dv == 1:
        return rt.wrap(nv)
    elif dv == -1:
        return rt.wrap(-1 * nv)
    else:
        if dv < 0:
            nv = nv * -1
            dv = dv * -1
        return Ratio(nv, dv)