Exemple #1
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
Exemple #2
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")
Exemple #3
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 = filename._str

    affirm(path.isfile(str(filename_str)), u"File does not exist on path")

    f = open(str(filename_str))
    data = f.read()
    f.close()
    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([])
Exemple #4
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
Exemple #5
0
    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
Exemple #6
0
def c_cast(frm, to):
    if not isinstance(to, CStructType):
        runtime_error(u"Expected a CStruct type to cast to, got " + rt.name(rt.str(to)))

    if not isinstance(frm, CStruct) and not isinstance(frm, VoidP):
        runtime_error(u"From must be a CVoidP or a CStruct, got " + rt.name(rt.str(frm)))

    return to.cast_to(frm)
Exemple #7
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")
Exemple #8
0
    def fqd(self, itm):
        ns_alias = rt.namespace(itm)
        current_nms = rt.ns.deref()

        if ns_alias is None:
            return keyword(rt.name(itm), rt.name(current_nms))
        else:
            ns_fqd = current_nms.resolve_ns(ns_alias)
            return keyword(rt.name(itm), rt.name(ns_fqd))
Exemple #9
0
    def add_refer_symbol(self, sym, var):
        assert isinstance(self, Namespace)

        name = rt.name(sym)
        prev_binding = self._registry.get(name, None)
        if prev_binding is not None:
            print rt.name(rt.str(rt.wrap(u"Warning: "), sym, rt.wrap(u" already refers to "), prev_binding))

        self._registry[name] = var
        return var
Exemple #10
0
def c_cast(frm, to):
    """(cast from to)
    Converts a VoidP to a CStruct. From is either a VoidP or a CStruct, to is a CStruct type."""
    if not isinstance(to, CStructType):
        runtime_error(u"Expected a CStruct type to cast to, got " + rt.name(rt.str(to)))

    if not isinstance(frm, CStruct) and not isinstance(frm, VoidP):
        runtime_error(u"From must be a CVoidP or a CStruct, got " + rt.name(rt.str(frm)))

    return to.cast_to(frm)
Exemple #11
0
def load_reader(rdr):
    import pixie.vm.reader as reader
    import pixie.vm.compiler as compiler
    import sys

    if not we_are_translated():
        print "Loading file while interpreted, this may take time"

    val = PXIC_WRITER.deref()
    if val is nil:
        pxic_writer = None
    else:
        pxic_writer = val.get_pxic_writer()

    with compiler.with_ns(u"user"):
        compiler.NS_VAR.deref().include_stdlib()
        while True:
            if not we_are_translated():
                sys.stdout.write(".")
                sys.stdout.flush()
            form = reader.read(rdr, False)
            if form is reader.eof:
                return nil

            try:
                compiled = compiler.compile(form)

            except WrappedException as ex:
                meta = rt.meta(form)
                if meta is not nil:
                    ci = rt.interpreter_code_info(meta)
                    add_info(ex, ci.__repr__())
                add_info(ex, u"Compiling: " + rt.name(rt.str(form)))
                raise ex

            try:
                if pxic_writer is not None:
                    pxic_writer.write_object(compiled)

                compiled.invoke([])

            except WrappedException as ex:
                meta = rt.meta(form)
                if meta is not nil:
                    ci = rt.interpreter_code_info(meta)
                    add_info(ex, ci.__repr__())
                add_info(ex, u"Running: " + rt.name(rt.str(form)))
                raise ex


    if not we_are_translated():
        print "done"

    return nil
Exemple #12
0
    def __repr__(self):
        import pixie.vm.rt as rt
        s = []
        trace = self._trace[:]
        trace.reverse()
        for x in trace:
            s.append(x.__repr__())
            s.append(u"\n")
        s.extend([u"RuntimeException: " + rt.name(rt.str(self._data)) + u" " +
                  rt.name(rt.str(self._msg)) + u"\n"])

        return u"".join(s)
Exemple #13
0
    def ffi_set_value(self, ptr, val):
        if isinstance(val, CCallback):
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = val.get_raw_closure()
        elif val is nil:
            casted = rffi.cast(rffi.VOIDPP, ptr)
            casted[0] = rffi.cast(rffi.VOIDP, 0)
        else:
            frm_name = rt.name(rt.str(val.type()))
            to_name = rt.name(rt.str(self))
            affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)

        return None
Exemple #14
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
Exemple #15
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)
Exemple #16
0
    def set_field(self, name, val):
        idx = self._custom_type.get_slot_idx(name)
        if idx == -1:
            runtime_error(
                u"Invalid field named " + rt.name(rt.str(name)) + u" on type " + rt.name(rt.str(self.type())),
                u"pixie.stdlib/InvalidFieldException",
            )

        old_val = self.get_field_by_idx(idx)
        if isinstance(old_val, AbstractMutableCell):
            old_val.set_mutable_cell_value(self._custom_type, self, name, idx, val)
        else:
            self._custom_type.set_mutable(name)
            self.set_field_by_idx(idx, val)
        return self
Exemple #17
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
Exemple #18
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))
Exemple #19
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))
Exemple #20
0
def in_ns(ns_name):
    from pixie.vm.compiler import NS_VAR

    NS_VAR.set_value(code._ns_registry.find_or_make(rt.name(ns_name)))
    NS_VAR.deref().include_stdlib()

    return nil
Exemple #21
0
def run_load_stdlib():
    global stdlib_loaded
    if stdlib_loaded.is_true():
        return
    import pixie.vm.compiler as compiler
    import pixie.vm.reader as reader
    f = open(rpath.rjoin(str(rt.name(load_path.deref())), "pixie/stdlib.pxi"))
    data = f.read()
    f.close()
    rdr = reader.MetaDataReader(reader.StringReader(unicode(data)), u"pixie/stdlib.pxi")
    result = nil

    if not we_are_translated():
        print "Loading stdlib while interpreted, this will take some time..."

    with compiler.with_ns(u"pixie.stdlib"):
        while True:
            if not we_are_translated():
                sys.stdout.write(".")
                sys.stdout.flush()
            form = reader.read(rdr, False)
            if form is reader.eof:
                break
            result = compiler.compile(form).invoke([])

    if not we_are_translated():
        print "done"

    stdlib_loaded.set_true()
Exemple #22
0
    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
Exemple #23
0
def struct_size(tp):
    """(struct-size tp)
    Gives the size of the given CStruct type tp, in bytes."""
    if not isinstance(tp, CStructType):
        runtime_error(u"Expected a CStruct type to get the size of, got " + rt.name(rt.str(tp)))

    return rt.wrap(tp.get_size())
Exemple #24
0
def prep_string(s):
    """Takes a Pixie string and returns a VoidP to that string. The string should be freed via dispose!, otherwise
    memory leaks could result."""
    affirm(isinstance(s, String), u"Can only prep strings with prep-string")
    utf8 = unicode_to_utf8(rt.name(s))
    raw = rffi.str2charp(utf8)
    return VoidP(rffi.cast(rffi.VOIDP, raw))
Exemple #25
0
def _repr(self):
    assert isinstance(self, Character)
    cv = self.char_val()
    if cv < 128:
        return rt.wrap(u"\\"+unicode(chr(cv)))
    hexv = rt.name(rt.bit_str(rt.wrap(self.char_val()), rt.wrap(4)))
    return rt.wrap(u"\\u" + u"0" * (4 - len(hexv)) + hexv)
Exemple #26
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
Exemple #27
0
def compiler_special(s):
    if isinstance(s, symbol.Symbol):
        ns = rt.namespace(s)
        if ns is None or ns == u"pixie.stdlib":
            return builtins.get(rt.name(s), None)

    return None
Exemple #28
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)
Exemple #29
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)
Exemple #30
0
def trimr(a):
    a = rt.name(a)
    j = len(a)
    while j > 0 and unicodedb.isspace(ord(a[j - 1])):
        j -= 1
    if j <= 0:
        return rt.wrap(u"")
    return rt.wrap(a[0:j])
Exemple #31
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)
Exemple #32
0
def refer(ns, refer, alias):
    from pixie.vm.symbol import Symbol
    from pixie.vm.string import String

    if isinstance(ns, Symbol) or isinstance(ns, String):
        ns = _ns_registry.find_or_make(rt.name(ns))

    if isinstance(refer, Symbol) or isinstance(refer, String):
        refer = _ns_registry.find_or_make(rt.name(refer))

    affirm(isinstance(ns, code.Namespace),
           u"First argument must be a namespace")
    if not isinstance(refer, code.Namespace):
        runtime_error(u"Second argument must be a namespace not a " +
                      refer.type().name())

    affirm(isinstance(alias, Symbol), u"Third argument must be a symbol")

    ns.add_refer(refer, rt.name(alias))
    return nil
Exemple #33
0
def trim(a):
    a = rt.name(a)
    i = 0
    while i < len(a) and unicodedb.isspace(ord(a[i])):
        i += 1
    j = len(a)
    while j > 0 and unicodedb.isspace(ord(a[j - 1])):
        j -= 1
    if j <= i:
        return rt.wrap(u"")
    return rt.wrap(a[i:j])
Exemple #34
0
 def ffi_set_value(self, ptr, val):
     pnt = rffi.cast(rffi.VOIDPP, ptr)
     if isinstance(val, String):
         pnt = rffi.cast(rffi.CCHARPP, ptr)
         utf8 = unicode_to_utf8(rt.name(val))
         raw = rffi.str2charp(utf8)
         pnt[0] = raw
         return CCharPToken(raw)
     elif isinstance(val, Buffer):
         pnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         pnt[0] = val.raw_data()
     elif val is nil:
         pnt[0] = rffi.cast(rffi.VOIDP, 0)
     elif isinstance(val, CStruct):
         pnt[0] = rffi.cast(rffi.VOIDP, val.raw_data())
     else:
         frm_name = rt.name(rt.str(val.type()))
         to_name = rt.name(rt.str(self))
         affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)
Exemple #35
0
def _ici(meta):
    import pixie.vm.reader as reader
    line = rt._val_at(meta, reader.LINE_KW, nil)
    line_number = rt._val_at(meta, reader.LINE_NUMBER_KW, nil)
    col_number = rt._val_at(meta, reader.COLUMN_NUMBER_KW, nil)
    file = rt._val_at(meta, reader.FILE_KW, nil)

    return InterpreterCodeInfo(
        line,
        line_number.int_val() if line_number is not nil else 0,
        col_number.int_val() if col_number is not nil else 0,
        rt.name(file) if file is not nil else u"<unknown>")
Exemple #36
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")
Exemple #37
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)
Exemple #38
0
    def read(self):
        if self._string_reader is None:
            result = _readline(str(rt.name(rt.ns.deref())) + " => ")
            if result == u"":
                raise EOFError()
            self._string_reader = StringReader(result)

        try:
            return self._string_reader.read()
        except EOFError:
            self._string_reader = None
            return self.read()
Exemple #39
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)
Exemple #40
0
    def __repr__(self):
        import pixie.vm.rt as rt
        s = []
        trace = self._trace[:]
        trace.reverse()
        for x in trace:
            s.append(x.__repr__())
            s.append(u"\n")

        s.extend([u"RuntimeException: " + rt.name(rt.str(self._data)) + u"\n"])

        return u"".join(s)
Exemple #41
0
def is_macro_call(form, ctx):
    if rt.seq_QMARK_(form) is true and isinstance(rt.first(form),
                                                  symbol.Symbol):
        name = rt.name(rt.first(form))
        if resolve_local(ctx, name):
            return None
        var = resolve_var(rt.first(form))

        if var and var.is_defined():
            val = var.deref()
            if isinstance(val, code.BaseCode) and val.is_macro():
                return val
    return None
Exemple #42
0
    def read(self):
        if self._string_reader is None:
            result = rt.name(self._reader_fn.invoke([]))
            code._dynamic_vars.set_var_value(READING_FORM_VAR, rt.wrap(READING_FORM_VAR.deref().int_val() + 1))
            if result == u"":
                raise EOFError()
            self._string_reader = StringReader(result)

        try:
            return self._string_reader.read()
        except EOFError:
            self._string_reader = None
            return self.read()
Exemple #43
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
Exemple #44
0
    def set_field(self, name, val):
        idx = self._custom_type.get_slot_idx(name)
        if idx == -1:
            runtime_error(u"Invalid field named " + rt.name(rt.str(name)) + u" on type " + rt.name(rt.str(self.type())),
                          u"pixie.stdlib/InvalidFieldException")

        old_val = self.get_field_by_idx(idx)
        if isinstance(old_val, AbstractMutableCell):
            old_val.set_mutable_cell_value(self._custom_type, self, name, idx, val)
        else:
            self._custom_type.set_mutable(name)
            self.set_field_by_idx(idx, val)
        return self
Exemple #45
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
Exemple #46
0
    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):
            return runtime_error(u"Unquote splicing not used inside list")
        elif rt.vector_QMARK_(form) is true:
            ret = rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(form))
        elif form is not nil and 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
Exemple #47
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
Exemple #48
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
Exemple #49
0
    def get_field(self, name):
        idx = self._custom_type.get_slot_idx(name)
        if idx == -1:
            runtime_error(u"Invalid field named " + rt.name(rt.str(name)) + u" on type " + rt.name(rt.str(self.type())),
                          u"pixie.stdlib/InvalidFieldException")

        if self._custom_type.is_mutable(name):
            value = self.get_field_by_idx(idx)
        else:
            value = self.get_field_immutable(idx)

        if isinstance(value, AbstractMutableCell):
            return value.get_mutable_cell_value()
        else:
            return value
Exemple #50
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
Exemple #51
0
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
Exemple #52
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)
Exemple #53
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()
Exemple #54
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)
Exemple #55
0
 def ffi_set_value(self, ptr, val):
     if isinstance(val, String):
         pnt = rffi.cast(rffi.CCHARPP, ptr)
         utf8 = unicode_to_utf8(rt.name(val))
         raw = rffi.str2charp(utf8)
         pnt[0] = raw
         return CCharPToken(raw)
     elif isinstance(val, Buffer):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = val.buffer()
     elif isinstance(val, VoidP):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = val.raw_data()
     elif val is nil:
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = rffi.cast(rffi.VOIDP, 0)
     elif isinstance(val, CStruct):
         vpnt = rffi.cast(rffi.VOIDPP, ptr)
         vpnt[0] = rffi.cast(rffi.VOIDP, val.raw_data())
     else:
         print val
         affirm(False, u"Cannot encode this type")
Exemple #56
0
    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:
            resolved_ns = self.resolve_ns(ns)
        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
Exemple #57
0
def load_file(filename):
    from pixie.vm.string import String
    from pixie.vm.util import unicode_from_utf8
    import pixie.vm.reader as reader
    import os.path as path

    affirm(isinstance(filename, String), u"filename must be a string")
    filename = str(rt.name(filename))
    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:]

    rt.load_reader(
        reader.MetaDataReader(reader.StringReader(unicode_from_utf8(data)),
                              unicode(filename)))
    return nil
Exemple #58
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)
Exemple #59
0
def _ffi_library(ns):
    nm = rt.name(ns)
    return ExternalLib(nm)
Exemple #60
0
def _ffi_voidp(lib, nm):
    affirm(isinstance(lib, ExternalLib),
           u"First argument to ffi-voidp should be an external library")
    name = rt.name(nm)
    return VoidP(lib.get_fn_ptr(name))