Esempio n. 1
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)
Esempio n. 2
0
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))
Esempio n. 3
0
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))
Esempio n. 4
0
def c_struct(name, size, spec):
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        if not isinstance(tp, CType):
            runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    return CStructType(rt.name(name), size.int_val(), d)
Esempio n. 5
0
    def _compare(self, frm, to):
        if isinstance(to, tuple):
            assert isinstance(frm, Cons)

            for x in to:
                self._compare(frm.first(), x)
                frm = frm.next()
            assert frm == nil
        elif isinstance(to, int):
            assert isinstance(frm, Integer)
            assert frm._int_val == to

        elif isinstance(to, Symbol):
            assert isinstance(frm, Symbol)
            assert frm._str == to._str

        elif isinstance(to, list):
            assert isinstance(frm, PersistentVector)

            for x in range(max(len(to), rt._count(frm)._int_val)):
                self._compare(rt.nth(frm, rt.wrap(x)), to[x])

        elif isinstance(to, dict):
            assert isinstance(frm, PersistentHashMap)
            for key in dict.keys(to):
                self._compare(frm.val_at(rt.wrap(key), ""), to[key])

            assert rt._count(frm)._int_val == len(dict.keys(to))

        elif isinstance(to, Character):
            assert isinstance(frm, Character)
            assert to._char_val == frm._char_val

        else:
            raise Exception("Don't know how to handle " + str(type(to)))
Esempio n. 6
0
    def _compare(self, frm, to):
        if isinstance(to, tuple):
            assert isinstance(frm, Cons)

            for x in to:
                self._compare(frm.first(), x)
                frm = frm.next()
            assert frm == nil
        elif isinstance(to, int):
            assert isinstance(frm, Integer)
            assert frm._int_val == to

        elif isinstance(to, Symbol):
            assert isinstance(frm, Symbol)
            assert frm._str == to._str

        elif isinstance(to, list):
            assert isinstance(frm, PersistentVector)

            for x in range(max(len(to), rt._count(frm)._int_val)):
                self._compare(rt.nth(frm, rt.wrap(x)), to[x])

        elif isinstance(to, dict):
            assert isinstance(frm, PersistentHashMap)
            for key in dict.keys(to):
                self._compare(frm.val_at(rt.wrap(key), ""), to[key])

            assert rt._count(frm)._int_val == len(dict.keys(to))

        elif isinstance(to, Character):
            assert isinstance(frm, Character)
            assert to._char_val == frm._char_val

        else:
            raise Exception("Don't know how to handle " + str(type(to)))
Esempio n. 7
0
    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)
Esempio n. 8
0
def load_ns(filename):
    import pixie.vm.string as string
    import pixie.vm.symbol as symbol
    import os.path as path

    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
Esempio n. 9
0
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
Esempio n. 10
0
File: ffi.py Progetto: kidaa/pixie
    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)
Esempio n. 11
0
def _ffi_fn__args(args):
    affirm(len(args) >= 4, u"ffi-fn requires at least 4 arguments")
    lib, nm, arg_types, ret_type = args[:4]

    affirm(isinstance(lib, ExternalLib), u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(arg_types)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(arg_types, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    kwargs = args[4:]
    affirm(len(kwargs) & 0x1 == 0, u"ffi-fn requires even number of options")

    is_variadic = False
    for i in range(0, len(kwargs)/2, 2):
        key = kwargs[i]
        val = kwargs[i+1]
        
        affirm(isinstance(key, Keyword), u"ffi-fn options should be keyword/bool pairs")
        affirm(val is true or val is false, u"ffi-fn options should be keyword/bool pairs")

        k = rt.name(key)
        if k == u"variadic?":
            is_variadic = True if val is true else False
        else:
            affirm(False, u"unknown ffi-fn option: :" + k)

    f = FFIFn(lib, rt.name(nm), new_args, ret_type, is_variadic)
    return f
Esempio n. 12
0
def compile_form(form, ctx):
    if form is nil:
        ctx.push_const(nil)
        return

    if rt.instance_QMARK_(rt.ISeq.deref(), form) and form is not nil:
        return compile_cons(form, ctx)
    if isinstance(form, numbers.Integer):
        ctx.push_const(form)
        return

    if isinstance(form, symbol.Symbol):
        name = form._str
        loc = resolve_local(ctx, name)
        if loc is None:
            var = resolve_var(ctx, form)

            if var is None:
                var = NS_VAR.deref().intern_or_make(name)

            ctx.push_const(var)

            ctx.bytecode.append(code.DEREF_VAR)
            return
        loc.emit(ctx)
        return

    if isinstance(form, Bool) or form is nil:
        ctx.push_const(form)
        return

    if isinstance(form, Keyword):
        ctx.push_const(form)
        return

    if isinstance(form, PersistentVector):
        vector_var = rt.vector()
        size = rt.count(form).int_val()
        #assert rt.count(form).int_val() == 0
        ctx.push_const(code.intern_var(u"pixie.stdlib", u"vector"))
        for x in range(size):
            compile_form(rt.nth(form, numbers.Integer(x)), ctx)

        ctx.bytecode.append(code.INVOKE)
        ctx.bytecode.append(r_uint(size + 1))
        ctx.sub_sp(size)
        return

    if rt.instance_QMARK_(rt.IMap.deref(), form):
        compile_map_literal(form, ctx)
        return

    if isinstance(form, String):
        ctx.push_const(form)
        return

    raise Exception("Can't compile ")
Esempio n. 13
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)
Esempio n. 14
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)
Esempio n. 15
0
def compile_local_macro(form, ctx):
    form = rt.next(form)
    binding = rt.first(form)
    body = rt.next(form)

    sym = rt.nth(binding, rt.wrap(0))
    bind_form = rt.nth(binding, rt.wrap(1))

    ctx.add_local(rt.name(sym), LocalMacro(bind_form))

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

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

    ctx.pop_locals()
Esempio n. 16
0
File: ffi.py Progetto: kidaa/pixie
def c_struct(name, size, spec):
    """(c-struct name size spec)
       Creates a CStruct named name, of size size, with the given spec. Spec is a vector
       of vectors. Each row of the format [field-name type offset]"""
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        #if not isinstance(tp, CType):
        #    runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    tp = CStructType(rt.name(name), size.int_val(), d)
    proto._dispose_BANG_.extend(tp, _dispose_cstruct)
    return tp
Esempio n. 17
0
def c_struct(name, size, spec):
    """(c-struct name size spec)
       Creates a CStruct named name, of size size, with the given spec. Spec is a vector
       of vectors. Each row of the format [field-name type offset]"""
    d = {}
    for x in range(rt.count(spec)):
        row = rt.nth(spec, rt.wrap(x))
        nm = rt.nth(row, rt.wrap(0))
        tp = rt.nth(row, rt.wrap(1))
        offset = rt.nth(row, rt.wrap(2))

        affirm(isinstance(nm, Keyword), u"c-struct field names must be keywords")
        #if not isinstance(tp, CType):
        #    runtime_error(u"c-struct field types must be c types, got: " + rt.name(rt.str(tp)))

        d[nm] = (tp, offset.int_val())

    tp = CStructType(rt.name(name), size.int_val(), d)
    proto._dispose_BANG_.extend(tp, _dispose_cstruct)
    return tp
Esempio n. 18
0
def compile_local_macro(form, ctx):
    form = rt.next(form)
    binding = rt.first(form)
    body = rt.next(form)

    sym = rt.nth(binding, rt.wrap(0))
    bind_form = rt.nth(binding, rt.wrap(1))

    ctx.add_local(rt.name(sym), LocalMacro(bind_form))

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

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

    ctx.pop_locals()
Esempio n. 19
0
def compile_loop(form, ctx):
    form = rt.next(form)
    bindings = rt.first(form)
    affirm(isinstance(bindings, PersistentVector),
           u"Loop bindings must be a vector")
    body = rt.next(form)
    ctx.enable_tail_call()
    ctc = ctx.can_tail_call
    ctx.disable_tail_call()

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

        compile_form(bind, ctx)

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

    if ctc:
        ctx.enable_tail_call()

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

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

    ctx.pop_recur_point()
    ctx.bytecode.append(code.POP_UP_N)
    ctx.sub_sp(binding_count)
    ctx.bytecode.append(binding_count)
    ctx.pop_locals(binding_count)
Esempio n. 20
0
def add_args(args, ctx):
    required_args = -1
    local_idx = 0
    for x in range(rt.count(args).int_val()):
        arg = rt.nth(args, numbers.Integer(x))
        affirm(isinstance(arg, symbol.Symbol), u"Argument names must be symbols")
        if arg._str == u"&":

            required_args = x
            continue
        ctx.add_local(arg._str, Arg(local_idx))
        local_idx += 1
    return required_args
Esempio n. 21
0
def compile_loop(form, ctx):
    form = rt.next(form)
    bindings = rt.first(form)
    affirm(isinstance(bindings, PersistentVector), u"Loop bindings must be a vector")
    body = rt.next(form)

    ctc = ctx.can_tail_call
    ctx.disable_tail_call()

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

        compile_form(bind, ctx)

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

    if ctc:
        ctx.enable_tail_call()

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

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

    ctx.pop_recur_point()
    ctx.bytecode.append(code.POP_UP_N)
    ctx.sub_sp(binding_count)
    ctx.bytecode.append(binding_count)
    ctx.pop_locals(binding_count)
Esempio n. 22
0
def _ffi_fn(lib, nm, args, ret_type):
    affirm(isinstance(lib, ExternalLib), u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(args)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(args, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    f = FFIFn(lib, rt.name(nm), new_args, ret_type)
    return f
Esempio n. 23
0
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 arg._str == u"&":

            required_args = intmask(x)
            continue
        ctx.add_local(arg._str, Arg(local_idx))
        local_idx += 1
    return required_args
Esempio n. 24
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))
Esempio n. 25
0
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
Esempio n. 26
0
def _ffi_fn(lib, nm, args, ret_type):
    affirm(isinstance(lib, ExternalLib),
           u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(args)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(args, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    f = FFIFn(lib, rt.name(nm), new_args, ret_type)
    return f
Esempio n. 27
0
def load_file(filename):
    import pixie.vm.reader as reader
    import pixie.vm.compiler as compiler
    import pixie.vm.string as string
    import pixie.vm.symbol as symbol
    import os.path as path
    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".lisp"

        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 = open(str(full_path))
            break

    if f is None:
        affirm(False, u"File does not exist in any directory found in load-paths")
    else:
        data = f.read()
        f.close()

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

        with compiler.with_ns(u"user"):
            while True:
                form = reader.read(rdr, False)
                if form is reader.eof:
                    return nil
                result = compiler.compile(form).invoke([])
    return nil
Esempio n. 28
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))
Esempio n. 29
0
File: ffi.py Progetto: kidaa/pixie
def ffi_callback(args, ret_type):
    """(ffi-callback args ret-type)
       Creates a ffi callback type. Args is a vector of CType args. Ret-type is the CType return
       type of the callback. Returns a ffi callback type that can be used with ffi-prep-callback."""
    args_w = [None] * rt.count(args)

    for x in range(rt.count(args)):
        arg = rt.nth(args, rt.wrap(x))
        if not isinstance(arg, object.Type):
            runtime_error(u"Expected type, got " + rt.name(rt.str(arg)))
        args_w[x] = arg

    if not isinstance(ret_type, object.Type):
        runtime_error(u"Expected type, got " + rt.name(rt.str(ret_type)))

    return CFunctionType(args_w, ret_type)
Esempio n. 30
0
def ffi_callback(args, ret_type):
    """(ffi-callback args ret-type)
       Creates a ffi callback type. Args is a vector of CType args. Ret-type is the CType return
       type of the callback. Returns a ffi callback type that can be used with ffi-prep-callback."""
    args_w = [None] * rt.count(args)

    for x in range(rt.count(args)):
        arg = rt.nth(args, rt.wrap(x))
        if not isinstance(arg, object.Type):
            runtime_error(u"Expected type, got " + rt.name(rt.str(arg)))
        args_w[x] = arg

    if not isinstance(ret_type, object.Type):
        runtime_error(u"Expected type, got " + rt.name(rt.str(ret_type)))

    return CFunctionType(args_w, ret_type)
Esempio n. 31
0
def _ffi_fn__args(args):
    affirm(len(args) >= 4, u"ffi-fn requires at least 4 arguments")
    lib, nm, arg_types, ret_type = args[:4]

    affirm(isinstance(lib, ExternalLib),
           u"First argument must be an ExternalLib")
    affirm(isinstance(ret_type, object.Type), u"Ret type must be a type")
    affirm(rt.namespace(nm) is None, u"Name must not be namespaced")

    cnt = rt.count(arg_types)
    new_args = [None] * cnt
    for x in range(cnt):
        t = rt.nth(arg_types, rt.wrap(x))
        affirm(isinstance(t, object.Type), u"Arg defs must be types")
        new_args[x] = t

    kwargs = args[4:]
    affirm(len(kwargs) & 0x1 == 0, u"ffi-fn requires even number of options")

    is_variadic = False
    for i in range(0, len(kwargs) / 2, 2):
        key = kwargs[i]
        val = kwargs[i + 1]

        affirm(isinstance(key, Keyword),
               u"ffi-fn options should be keyword/bool pairs")
        affirm(val is true or val is false,
               u"ffi-fn options should be keyword/bool pairs")

        k = rt.name(key)
        if k == u"variadic?":
            is_variadic = True if val is true else False
        else:
            affirm(False, u"unknown ffi-fn option: :" + k)

    tp = CFunctionType(new_args, ret_type, is_variadic)
    nm = rt.name(nm)
    f = FFIFn(nm, lib.get_fn_ptr(nm), tp)
    return f
Esempio n. 32
0
    def _compare(self, frm, to):
        if isinstance(to, tuple):
            assert isinstance(frm, Cons)

            for x in to:
                self._compare(frm.first(), x)
                frm = frm.next()
        elif isinstance(to, int):
            assert isinstance(frm, Integer)
            assert frm._int_val == to

        elif isinstance(to, Symbol):
            assert isinstance(frm, Symbol)
            assert frm._str == to._str

        elif isinstance(to, list):
            assert isinstance(frm, PersistentVector)

            for x in range(len(to)):
                self._compare(rt.nth(frm, rt.wrap(x)), to[x])

        else:
            raise Exception("Don't know how to handle " + str(type(to)))
Esempio n. 33
0
    def _compare(self, frm, to):
        if isinstance(to, tuple):
            assert isinstance(frm, Cons)

            for x in to:
                self._compare(frm.first(), x)
                frm = frm.next()
        elif isinstance(to, int):
            assert isinstance(frm, Integer)
            assert frm._int_val == to

        elif isinstance(to, Symbol):
            assert isinstance(frm, Symbol)
            assert frm._str == to._str

        elif isinstance(to, list):
            assert isinstance(frm, PersistentVector)

            for x in range(len(to)):
                self._compare(rt.nth(frm, rt.wrap(x)), to[x])

        else:
            raise Exception("Don't know how to handle " + str(type(to)))
Esempio n. 34
0
def compile_form(form, ctx):
    if form is nil:
        ctx.push_const(nil)
        return

    if rt._satisfies_QMARK_(rt.ISeq.deref(), form) and form is not nil:

        form = maybe_oop_invoke(form)

        return compile_cons(form, ctx)
    if isinstance(form, numbers.Integer):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.BigInteger):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.Float):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.Ratio):
        ctx.push_const(form)
        return

    if isinstance(form, symbol.Symbol):
        name = rt.name(form)
        ns = rt.namespace(form)

        loc = resolve_local(ctx, name)
        var = resolve_var(form)

        if var is None and loc:
            loc.emit(ctx)
            return

        if var and loc and ns is None:
            loc.emit(ctx)
            return

        if var is None:
            name = rt.name(form)
            var = NS_VAR.deref().intern_or_make(name)

        ctx.push_const(var)

        meta = rt.meta(form)
        if meta is not nil:
            ctx.debug_points[len(
                ctx.bytecode)] = rt.interpreter_code_info(meta)

        ctx.bytecode.append(code.DEREF_VAR)
        return

    if isinstance(form, Bool) or form is nil:
        ctx.push_const(form)
        return

    if isinstance(form, Keyword):
        ctx.push_const(form)
        return

    if isinstance(form, PersistentVector):
        size = rt.count(form)
        #assert rt.count(form).int_val() == 0
        ctx.push_const(code.intern_var(u"pixie.stdlib", u"vector"))
        for x in range(size):
            compile_form(rt.nth(form, rt.wrap(x)), ctx)

        ctx.bytecode.append(code.INVOKE)
        ctx.bytecode.append(r_uint(size + 1))
        ctx.sub_sp(size)

        compile_meta(rt.meta(form), ctx)

        return

    if isinstance(form, PersistentHashSet):
        compile_set_literal(form, ctx)
        return

    if rt._satisfies_QMARK_(rt.IMap.deref(), form):
        compile_map_literal(form, ctx)
        return

    if isinstance(form, String):
        ctx.push_const(form)
        return

    if isinstance(form, Character):
        ctx.push_const(form)
        return

    raise Exception("Can't compile ")
Esempio n. 35
0
 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
Esempio n. 36
0
 def first(self):
     return rt.nth(self._w_array, rt.wrap(self._idx))
Esempio n. 37
0
def compile_form(form, ctx):
    if form is nil:
        ctx.push_const(nil)
        return

    if rt._satisfies_QMARK_(rt.ISeq.deref(), form) and form is not nil:
        form = macroexpand(form)
        return compile_cons(form, ctx)
    if isinstance(form, numbers.Integer):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.BigInteger):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.Float):
        ctx.push_const(form)
        return
    if isinstance(form, numbers.Ratio):
        ctx.push_const(form)
        return

    if isinstance(form, symbol.Symbol):
        name = rt.name(form)
        ns = rt.namespace(form)

        loc = resolve_local(ctx, name)
        var = resolve_var(ctx, form)

        if var is None and loc:
            loc.emit(ctx)
            return

        if var and loc and ns is None:
            loc.emit(ctx)
            return
        
        if var is None:
            name = rt.name(form)
            var = NS_VAR.deref().intern_or_make(name)

        ctx.push_const(var)

        meta = rt.meta(form)
        if meta is not nil:
            ctx.debug_points[len(ctx.bytecode)] = rt.interpreter_code_info(meta)

        ctx.bytecode.append(code.DEREF_VAR)
        return

    if isinstance(form, Bool) or form is nil:
        ctx.push_const(form)
        return

    if isinstance(form, Keyword):
        ctx.push_const(form)
        return

    if isinstance(form, PersistentVector):
        vector_var = rt.vector()
        size = rt.count(form)
        #assert rt.count(form).int_val() == 0
        ctx.push_const(code.intern_var(u"pixie.stdlib", u"vector"))
        for x in range(size):
            compile_form(rt.nth(form, rt.wrap(x)), ctx)

        ctx.bytecode.append(code.INVOKE)
        ctx.bytecode.append(r_uint(size + 1))
        ctx.sub_sp(size)

        compile_meta(rt.meta(form), ctx)

        return

    if isinstance(form, PersistentHashSet):
        compile_set_literal(form, ctx)
        return

    if rt._satisfies_QMARK_(rt.IMap.deref(), form):
        compile_map_literal(form, ctx)
        return

    if isinstance(form, String):
        ctx.push_const(form)
        return

    if isinstance(form, Character):
        ctx.push_const(form)
        return

    raise Exception("Can't compile ")
Esempio n. 38
0
def ratio_read(obj):
    return Ratio(
        rt.nth(obj, rt.wrap(0)).int_val(),
        rt.nth(obj, rt.wrap(1)).int_val())
Esempio n. 39
0
 def first(self):
     return rt.nth(self._w_array, rt.wrap(self._idx))
Esempio n. 40
0
 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
Esempio n. 41
0
def ratio_read(obj):
    return Ratio(rt.nth(obj, rt.wrap(0)).int_val(), rt.nth(obj, rt.wrap(1)).int_val())