Exemple #1
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 rt.map_QMARK_(form) is true:
            mes = SyntaxQuoteReader.flatten_map(form)
            ret = rt.list(APPLY, HASHMAP, rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(mes)))
        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 #2
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 #3
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 #4
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 #5
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
Exemple #6
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 #7
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 #8
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 #9
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 #10
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 #11
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 #12
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 #13
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 #14
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 #15
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 #16
0
def refer_symbol(ns, sym, var):
    from pixie.vm.symbol import Symbol

    affirm(isinstance(ns, code.Namespace), u"First argument must be a namespace")
    affirm(isinstance(sym, Symbol) and rt.namespace(sym) is None, u"Second argument must be a non-namespaced symbol")
    affirm(isinstance(var, code.Var), u"Third argument must be a var")

    ns.add_refer_symbol(sym, var)
    return nil
Exemple #17
0
 def invoke(self, rdr, ch):
     ch = rdr.read()
     if ch == u":":
         itm = read_inner(rdr, True)
         return self.fqd(itm)
     else:
         rdr.unread()
         itm = read_inner(rdr, True)
         return keyword(rt.name(itm), rt.namespace(itm))
Exemple #18
0
    def invoke(self, rdr, ch):
        ch = rdr.read()
        if ch == u":":
            ch = rdr.read()
            itm = read_symbol(rdr, ch, False)
            return self.fqd(itm)
        else:
            itm = read_symbol(rdr, ch, False)

            return keyword(rt.name(itm), rt.namespace(itm))
Exemple #19
0
def refer_symbol(ns, sym, var):
    from pixie.vm.symbol import Symbol

    affirm(isinstance(ns, Namespace), u"First argument must be a namespace")
    affirm(
        isinstance(sym, Symbol) and rt.namespace(sym) is None,
        u"Second argument must be a non-namespaced symbol")
    affirm(isinstance(var, Var), u"Third argument must be a var")

    ns.add_refer_symbol(sym, var)
    return nil
Exemple #20
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 #21
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 #22
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 #23
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 #24
0
def the_ns(ns_name):
    affirm(rt.namespace(ns_name) is None, u"the-ns takes a un-namespaced symbol")

    return code._ns_registry.get(rt.name(ns_name), nil)
Exemple #25
0
def the_ns(ns_name):
    affirm(
        rt.namespace(ns_name) is None, u"the-ns takes a un-namespaced symbol")

    return code._ns_registry.get(rt.name(ns_name), nil)
Exemple #26
0
def _var(nm):
    var = get_var_if_defined(rt.namespace(nm), rt.name(nm), nil)
    return var
Exemple #27
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 ")
Exemple #28
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 ")