Пример #1
0
def create_type(type_name, fields):
    affirm(isinstance(type_name, Keyword), u"Type name must be a keyword")

    field_count = rt.count(fields)
    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)
Пример #2
0
def create_type(type_name, fields):
    affirm(isinstance(type_name, Keyword), u"Type name must be a keyword")

    field_count = rt.count(fields)
    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)
Пример #3
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))
Пример #4
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))
Пример #5
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)
Пример #6
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
Пример #7
0
Файл: ffi.py Проект: 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)
Пример #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
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
0
Файл: ffi.py Проект: 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)
Пример #13
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)
Пример #14
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
Пример #15
0
def compile_map_literal(form, ctx):
    ctx.push_const(code.intern_var(u"pixie.stdlib", u"hashmap"))

    rt.reduce(CompileMapRf(ctx), nil, form)

    size = rt.count(form).int_val() * 2
    ctx.bytecode.append(code.INVOKE)
    ctx.bytecode.append(r_uint(size) + 1)
Пример #16
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 ")
Пример #17
0
def write_seq(s, wtr):
    write_tag(SEQ, wtr)
    write_int_raw(rt.count(s), wtr)

    s = rt.seq(s)

    while s is not nil:
        write_object(rt.first(s), wtr)
        s = rt.next(s)
Пример #18
0
def write_seq(s, wtr):
    write_tag(SEQ, wtr)
    write_int_raw(rt.count(s), wtr)

    s = rt.seq(s)

    while s is not nil:
        write_object(rt.first(s), wtr)
        s = rt.next(s)
Пример #19
0
def call_macro(var, form, ctx):
    form = rt.next(form)
    args = [None] * rt.count(form)
    i = 0
    while form is not nil:
        args[i] = rt.first(form)
        form = rt.next(form)
        i += 1
    return var.invoke(args)
Пример #20
0
def call_macro(var, form, ctx):
    form = rt.next(form)
    args = [None] * rt.count(form)
    i = 0
    while form is not nil:
        args[i] = rt.first(form)
        form = rt.next(form)
        i += 1
    return var.invoke(args)
Пример #21
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
Пример #22
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)
Пример #23
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
Пример #24
0
def compile_fn_body(name, args, body, ctx):
    new_ctx = Context(name._str, rt.count(args).int_val(), ctx)
    required_args = add_args(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())

    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)
            if rt.next(body) is not nil:
                new_ctx.pop()
            bc += 1
            body = rt.next(body)

    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, rt.count(args).int_val()
Пример #25
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)
Пример #26
0
def compile_map_literal(form, ctx):
    ctx.push_const(code.intern_var(u"pixie.stdlib", u"hashmap"))

    rt.reduce(CompileMapRf(ctx), nil, form)

    size = rt.count(form) * 2
    ctx.bytecode.append(code.INVOKE)
    ctx.bytecode.append(r_uint(size) + 1)
    if size > 0:
        ctx.sub_sp(size)

    compile_meta(rt.meta(form), ctx)
Пример #27
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
Пример #28
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
Пример #29
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
Пример #30
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)
Пример #31
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
Пример #32
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
Пример #33
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
Пример #34
0
def macroexpand(form):
    sym = rt.first(form)
    if isinstance(sym, symbol.Symbol):
        s = rt.name(sym)
        if s.startswith(".") and s != u".":
            if rt.count(form) < 2:
                raise Exception("malformed dot expression, expecting (.member obj ...)")

            method = rt.keyword(rt.wrap(rt.name(sym)[1:]))
            obj = rt.first(rt.next(form))
            dot = rt.symbol(rt.wrap(u"."))
            call = rt.cons(dot, rt.cons(obj, rt.cons(method, rt.next(rt.next(form)))))

            return call

    return form
Пример #35
0
def macroexpand(form):
    sym = rt.first(form)
    if isinstance(sym, symbol.Symbol):
        s = rt.name(sym)
        if s.startswith(".") and s != u".":
            if rt.count(form) < 2:
                raise Exception(
                    "malformed dot expression, expecting (.member obj ...)")

            method = rt.keyword(rt.wrap(rt.name(sym)[1:]))
            obj = rt.first(rt.next(form))
            dot = rt.symbol(rt.wrap(u"."))
            call = rt.cons(
                dot, rt.cons(obj, rt.cons(method, rt.next(rt.next(form)))))

            return call

    return form
Пример #36
0
Файл: ffi.py Проект: 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
Пример #37
0
def maybe_oop_invoke(form):
    head = rt.first(form)
    if isinstance(rt.first(form), symbol.Symbol) and rt.name(head).startswith(".-"):
        postfix = rt.next(form)
        affirm(rt.count(postfix) == 1, u" Attribute lookups must only have one argument")
        subject = rt.first(postfix)
        kw = keyword(rt.name(head)[2:])
        fn = symbol.symbol(u"pixie.stdlib/-get-attr")
        return create_from_list([fn, subject, kw])

    elif isinstance(rt.first(form), symbol.Symbol) and rt.name(head).startswith("."):
        subject = rt.first(rt.next(form))
        postfix = rt.next(rt.next(form))
        form = cons(keyword(rt.name(head)[1:]), postfix)
        form = cons(subject, form)
        form = cons(symbol.symbol(u"pixie.stdlib/-call-method"), form)
        return form

    else:
        return form
Пример #38
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
Пример #39
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)
Пример #40
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
Пример #41
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)
Пример #42
0
def maybe_oop_invoke(form):
    head = rt.first(form)
    if isinstance(rt.first(form),
                  symbol.Symbol) and rt.name(head).startswith(".-"):
        postfix = rt.next(form)
        affirm(
            rt.count(postfix) == 1,
            u" Attribute lookups must only have one argument")
        subject = rt.first(postfix)
        kw = keyword(rt.name(head)[2:])
        fn = symbol.symbol(u"pixie.stdlib/-get-attr")
        return create_from_list([fn, subject, kw])

    elif isinstance(rt.first(form),
                    symbol.Symbol) and rt.name(head).startswith("."):
        subject = rt.first(rt.next(form))
        postfix = rt.next(rt.next(form))
        form = cons(keyword(rt.name(head)[1:]), postfix)
        form = cons(subject, form)
        form = cons(symbol.symbol(u"pixie.stdlib/-call-method"), form)
        return form

    else:
        return form
Пример #43
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 ")
Пример #44
0
def compile_in_ns(form, ctx):
    affirm(rt.count(form) == 2, u"in-ns requires an argument")
    arg = rt.first(rt.next(form))
    NS_VAR.set_value(code._ns_registry.find_or_make(rt.name(arg)))
    NS_VAR.deref().include_stdlib()
    compile_fn_call(form, ctx)
Пример #45
0
def compile_yield(form, ctx):
    affirm(rt.count(form) == 2, u"yield takes a single argument")
    arg = rt.first(rt.next(form))
    compile_form(arg, ctx)
    ctx.bytecode.append(code.YIELD)
Пример #46
0
 def next(self):
     if self._idx < rt.count(self._w_array) - 1:
         return ArraySeq(self._idx + 1, self._w_array)
     else:
         return nil
Пример #47
0
def split(a, b):
    affirm(rt.count(b) > 0, u"separator can't be empty")
    v = rt.vector()
    for s in rstring.split(rt.name(a), rt.name(b)):
        v = rt.conj(v, rt.wrap(s))
    return v
Пример #48
0
def _seq(self):
    assert isinstance(self, Array)
    if rt.count(self) > 0:
        return ArraySeq(0, self)
    else:
        return nil
Пример #49
0
def write_vector(vec, wtr):
    write_tag(VECTOR, wtr)
    write_int_raw(rt.count(vec), wtr)

    rt._reduce(vec, WriteItem(wtr), nil)
Пример #50
0
def compile_in_ns(form, ctx):
    affirm(rt.count(form) == 2, u"in-ns requires an argument")
    arg = rt.first(rt.next(form))
    NS_VAR.set_value(code._ns_registry.find_or_make(rt.name(arg)))
    NS_VAR.deref().include_stdlib()
    compile_fn_call(form, ctx)
Пример #51
0
 def next(self):
     if self._idx < rt.count(self._w_array) - 1:
         return ArraySeq(self._idx + 1, self._w_array)
     else:
         return nil
Пример #52
0
def split(a, b):
    affirm(rt.count(b) > 0, u"separator can't be empty")
    v = rt.vector()
    for s in rstring.split(rt.name(a), rt.name(b)):
        v = rt.conj(v, rt.wrap(s))
    return v
Пример #53
0
def compile_yield(form, ctx):
    affirm(rt.count(form) == 2, u"yield takes a single argument")
    arg = rt.first(rt.next(form))
    compile_form(arg, ctx)
    ctx.bytecode.append(code.YIELD)
Пример #54
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 ")
Пример #55
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
Пример #56
0
def write_map(mp, wtr):
    write_tag(MAP, wtr)
    write_int_raw(rt.count(mp), wtr)

    rt._reduce(mp, WriteParirFn(wtr), nil)
Пример #57
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