コード例 #1
0
def compile_fn(form, ctx):
    form = rt.next(form)
    if isinstance(rt.first(form), symbol.Symbol):
        name = rt.first(form)
        form = rt.next(form)
    else:
        name = symbol.symbol(default_fn_name)

    if rt._satisfies_QMARK_(rt.ISeq.deref(), rt.first(form)):
        arities = []
        while form is not nil:
            required_arity, argc = compile_fn_body(name,
                                                   rt.first(rt.first(form)),
                                                   rt.next(rt.first(form)),
                                                   ctx)
            arities.append(argc if required_arity == -1 else required_arity
                           | 256)
            form = rt.next(form)

        ctx.bytecode.append(code.MAKE_MULTI_ARITY)
        ctx.bytecode.append(r_uint(len(arities)))
        arities.reverse()
        for x in arities:
            ctx.bytecode.append(r_uint(x))

        ctx.add_sp(1)  # result
        ctx.sub_sp(len(arities))

    else:
        res = compile_fn_body(name, rt.first(form), rt.next(form), ctx)
    if rt.meta(name) is not nil:
        compile_meta(rt.meta(name), ctx)
コード例 #2
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #3
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)
コード例 #4
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
def compile_fn(form, ctx):
    form = rt.next(form)
    if isinstance(rt.first(form), symbol.Symbol):
        name = rt.first(form)
        form = rt.next(form)
    else:
        name = symbol.symbol(default_fn_name)




    if rt._satisfies_QMARK_(rt.ISeq.deref(), rt.first(form)):
        arities = []
        while form is not nil:
            required_arity, argc = compile_fn_body(name, rt.first(rt.first(form)), rt.next(rt.first(form)), ctx)
            arities.append(argc if required_arity == -1 else required_arity | 256)
            form = rt.next(form)

        ctx.bytecode.append(code.MAKE_MULTI_ARITY)
        ctx.bytecode.append(r_uint(len(arities)))
        arities.reverse()
        for x in arities:
            ctx.bytecode.append(r_uint(x))

        ctx.add_sp(1) # result
        ctx.sub_sp(len(arities))

    else:
        res = compile_fn_body(name, rt.first(form), rt.next(form), ctx)
    if rt.meta(name) is not nil:
        compile_meta(rt.meta(name), ctx)
コード例 #5
0
ファイル: reader.py プロジェクト: rowhit/pixie
def expand_list_rfn(ret, item):
    if is_unquote(item):
        ret = rt.conj(ret, rt.vector(rt.first(rt.next(item))))
    elif is_unquote_splicing(item):
        ret = rt.conj(ret, rt.first(rt.next(item)))
    else:
        ret = rt.conj(ret, rt.vector(SyntaxQuoteReader.syntax_quote(item)))
    return ret
コード例 #6
0
ファイル: reader.py プロジェクト: foodhype/pixie
def expand_list_rfn(ret, item):
    if is_unquote(item):
        ret = rt.conj(ret, rt.vector(rt.first(rt.next(item))))
    elif is_unquote_splicing(item):
        ret = rt.conj(ret, rt.first(rt.next(item)))
    else:
        ret = rt.conj(ret, rt.vector(SyntaxQuoteReader.syntax_quote(item)))
    return ret
コード例 #7
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #8
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)
コード例 #9
0
def compile_do(form, ctx):
    form = rt.next(form)

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

        if form is nil:
            return
        else:
            ctx.pop()
コード例 #10
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
def compile_do(form, ctx):
    form = rt.next(form)

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

        if form is nil:
            return
        else:
            ctx.pop()
コード例 #11
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
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))
    ctx.push_const(var)
    compile_form(val, ctx)
    ctx.bytecode.append(code.SET_VAR)
    ctx.sub_sp(1)
コード例 #12
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))
コード例 #13
0
ファイル: compiler.py プロジェクト: Xsan-21/pixie
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))
コード例 #14
0
def compile_fn_call(form, ctx):
    macro = is_macro_call(form, ctx)
    if macro:
        return compile_form(call_macro(macro, form, ctx), ctx)

    meta = rt.meta(form)

    cnt = 0
    ctc = ctx.can_tail_call
    while form is not nil:
        ctx.disable_tail_call()
        compile_form(rt.first(form), ctx)
        cnt += 1
        form = rt.next(form)

    if ctc:
        ctx.enable_tail_call()

    #if ctx.can_tail_call:
    #    ctx.bytecode.append(code.TAIL_CALL)
    #else:
    if meta is not nil:
        ctx.debug_points[len(ctx.bytecode)] = rt.interpreter_code_info(meta)
    ctx.bytecode.append(code.INVOKE)

    ctx.bytecode.append(cnt)
    ctx.sub_sp(r_uint(cnt - 1))
コード例 #15
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
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)
コード例 #16
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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
コード例 #17
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
def compile_cons(form, ctx):
    if isinstance(form.first(), symbol.Symbol) and form.first()._str in builtins:
        return builtins[form.first()._str](form, ctx)

    macro = is_macro_call(form, ctx)
    if macro:
        return compile_form(call_macro(macro, form, ctx), ctx)

    cnt = 0
    ctc = ctx.can_tail_call
    while form is not nil:
        ctx.disable_tail_call()
        compile_form(rt.first(form), ctx)
        cnt += 1
        form = rt.next(form)

    if ctc:
        ctx.enable_tail_call()

    #if ctx.can_tail_call:
    #    ctx.bytecode.append(code.TAIL_CALL)
    #else:
    ctx.bytecode.append(code.INVOKE)

    ctx.bytecode.append(cnt)
    ctx.sub_sp(cnt - 1)
コード例 #18
0
ファイル: compiler.py プロジェクト: codeape2/pixie
def compile_cons(form, ctx):
    if isinstance(rt.first(form), symbol.Symbol):
        special = compiler_special(rt.first(form))
        if special is not None:
            return special(form, ctx)

    macro = is_macro_call(form, ctx)
    if macro:
        return compile_form(call_macro(macro, form, ctx), ctx)

    meta = rt.meta(form)

    cnt = 0
    ctc = ctx.can_tail_call
    while form is not nil:
        ctx.disable_tail_call()
        compile_form(rt.first(form), ctx)
        cnt += 1
        form = rt.next(form)

    if ctc:
        ctx.enable_tail_call()

    #if ctx.can_tail_call:
    #    ctx.bytecode.append(code.TAIL_CALL)
    #else:
    if meta is not nil:
        ctx.debug_points[len(ctx.bytecode)] = meta
    ctx.bytecode.append(code.INVOKE)

    ctx.bytecode.append(cnt)
    ctx.sub_sp(cnt - 1)
コード例 #19
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
def compile_fn_call(form, ctx):
    macro = is_macro_call(form, ctx)
    if macro:
        return compile_form(call_macro(macro, form, ctx), ctx)

    meta = rt.meta(form)

    cnt = 0
    ctc = ctx.can_tail_call
    while form is not nil:
        ctx.disable_tail_call()
        compile_form(rt.first(form), ctx)
        cnt += 1
        form = rt.next(form)

    if ctc:
        ctx.enable_tail_call()

    #if ctx.can_tail_call:
    #    ctx.bytecode.append(code.TAIL_CALL)
    #else:
    if meta is not nil:
        ctx.debug_points[len(ctx.bytecode)] = rt.interpreter_code_info(meta)
    ctx.bytecode.append(code.INVOKE)

    ctx.bytecode.append(cnt)
    ctx.sub_sp(r_uint(cnt - 1))
コード例 #20
0
ファイル: reader.py プロジェクト: rowhit/pixie
    def syntax_quote(form):
        if isinstance(form, Symbol) and compiler.is_compiler_special(form):
            ret = rt.list(QUOTE, form)

        elif isinstance(form, Symbol):
            if rt.namespace(form) is None and rt.name(form).endswith("#"):
                gmap = rt.deref(GEN_SYM_ENV)
                affirm(gmap is not nil, u"Gensym literal used outside a syntax quote")
                gs = rt.get(gmap, form)
                if gs is nil:
                    gs = rt.symbol(rt.str(form, rt.wrap(u"__"), rt.gensym()))
                    GEN_SYM_ENV.set_value(rt.assoc(gmap, form, gs))
                form = gs
            else:
                var = rt.resolve_in(compiler.NS_VAR.deref(), form)
                if var is nil:
                    form = rt.symbol(rt.str(rt.wrap(rt.name(rt.deref(compiler.NS_VAR))), rt.wrap(u"/"), form))
                else:
                    form = rt.symbol(rt.str(rt.wrap(rt.namespace(var)), rt.wrap(u"/"), rt.str(rt.wrap(rt.name(var)))))
            ret = rt.list(QUOTE, form)
        elif is_unquote(form):
            ret = rt.first(rt.next(form))
        elif is_unquote_splicing(form):
            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
コード例 #21
0
ファイル: reader.py プロジェクト: foodhype/pixie
    def syntax_quote(form):
        if isinstance(form, Symbol) and compiler.is_compiler_special(form):
            ret = rt.list(QUOTE, form)

        elif isinstance(form, Symbol):
            if rt.namespace(form) is None and rt.name(form).endswith("#"):
                gmap = rt.deref(GEN_SYM_ENV)
                affirm(gmap is not nil, u"Gensym literal used outside a syntax quote")
                gs = rt.get(gmap, form)
                if gs is nil:
                    gs = rt.symbol(rt.str(form, rt.wrap(u"__"), rt.gensym()))
                    GEN_SYM_ENV.set_value(rt.assoc(gmap, form, gs))
                form = gs
            else:
                var = rt.resolve_in(compiler.NS_VAR.deref(), form)
                if var is nil:
                    form = rt.symbol(rt.str(rt.wrap(rt.name(rt.deref(compiler.NS_VAR))), rt.wrap(u"/"), form))
                else:
                    form = rt.symbol(rt.str(rt.wrap(rt.namespace(var)), rt.wrap(u"/"), rt.str(rt.wrap(rt.name(var)))))
            ret = rt.list(QUOTE, form)
        elif is_unquote(form):
            ret = rt.first(rt.next(form))
        elif is_unquote_splicing(form):
            raise Exception("Unquote splicing not used inside list")
        elif rt.vector_QMARK_(form) is true:
            ret = rt.list(APPLY, CONCAT, SyntaxQuoteReader.expand_list(form))
        elif rt.seq_QMARK_(form) is true:
            ret = rt.list(APPLY, LIST, rt.cons(CONCAT, SyntaxQuoteReader.expand_list(rt.seq(form))))
        else:
            ret = rt.list(QUOTE, form)
        return ret
コード例 #22
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)
コード例 #23
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)
コード例 #24
0
ファイル: writer.py プロジェクト: StetHD/pixie
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)
コード例 #25
0
ファイル: compiler.py プロジェクト: qyqx/pixie
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)
コード例 #26
0
ファイル: compiler.py プロジェクト: kgann/pixie
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
コード例 #27
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()
コード例 #28
0
ファイル: compiler.py プロジェクト: bendlas/pixie
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
コード例 #29
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
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)
コード例 #30
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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()
コード例 #31
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
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()
コード例 #32
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #33
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)
コード例 #34
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)
コード例 #35
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)
コード例 #36
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #37
0
ファイル: reader.py プロジェクト: esaul/pixie
 def syntax_quote(form):
     if isinstance(form, Symbol):
         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
コード例 #38
0
def _eq(self, obj):
    assert isinstance(self, PersistentHashSet)
    if self is obj:
        return true
    if not isinstance(obj, PersistentHashSet):
        return false
    if self._map._cnt != obj._map._cnt:
        return false

    seq = rt.seq(obj)
    while seq is not nil:
        if rt._contains_key(self, rt.first(seq)) is false:
            return false
        seq = rt.next(seq)
    return true
コード例 #39
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
コード例 #40
0
ファイル: persistent_hash_set.py プロジェクト: stuarth/pixie
def _eq(self, obj):
    assert isinstance(self, PersistentHashSet)
    if self is obj:
        return true
    if not isinstance(obj, PersistentHashSet):
        return false
    if self._map._cnt != obj._map._cnt:
        return false

    seq = rt.seq(obj)
    while seq is not nil:
        if rt._contains_key(self, rt.first(seq)) is false:
            return false
        seq = rt.next(seq)
    return true
コード例 #41
0
def _eq(self, obj):
    if self is obj:
        return true
    elif isinstance(obj, PersistentVector):
        if self._cnt != obj._cnt:
            return false
        for i in range(0, intmask(self._cnt)):
            if not rt.eq(self.nth(i), obj.nth(i)):
                return false
        return true
    else:
        if not rt.satisfies_QMARK_(proto.ISeqable, obj):
            return false
        seq = rt.seq(obj)
        for i in range(0, intmask(self._cnt)):
            if seq is nil or not rt.eq(self.nth(i), rt.first(seq)):
                return false
            seq = rt.next(seq)
        if seq is not nil:
            return false
        return true
コード例 #42
0
def _eq(self, obj):
    assert isinstance(self, PersistentVector)
    if self is obj:
        return true
    elif isinstance(obj, PersistentVector):
        if self._cnt != obj._cnt:
            return false
        for i in range(0, intmask(self._cnt)):
            if not rt.eq(self.nth(i), obj.nth(i)):
                return false
        return true
    else:
        if obj is nil or not rt.satisfies_QMARK_(proto.ISeqable, obj):
            return false
        seq = rt.seq(obj)
        for i in range(0, intmask(self._cnt)):
            if seq is nil or not rt.eq(self.nth(i), rt.first(seq)):
                return false
            seq = rt.next(seq)
        if seq is not nil:
            return false
        return true
コード例 #43
0
def compile_cons(form, ctx):
    if isinstance(form, EmptyList):
        ctx.push_const(form)
        return

    if isinstance(rt.first(form), symbol.Symbol):
        special = compiler_special(rt.first(form))
        if special is not None:
            return special(form, ctx)

    macro = is_macro_call(form, ctx)
    if macro:
        return compile_form(call_macro(macro, form, ctx), ctx)

    meta = rt.meta(form)

    cnt = 0
    ctc = ctx.can_tail_call
    while form is not nil:
        ctx.disable_tail_call()
        compile_form(rt.first(form), ctx)
        cnt += 1
        form = rt.next(form)

    if ctc:
        ctx.enable_tail_call()

    #if ctx.can_tail_call:
    #    ctx.bytecode.append(code.TAIL_CALL)
    #else:
    if meta is not nil:
        ctx.debug_points[len(ctx.bytecode)] = rt.interpreter_code_info(meta)
    ctx.bytecode.append(code.INVOKE)

    ctx.bytecode.append(cnt)
    ctx.sub_sp(r_uint(cnt - 1))
コード例 #44
0
def compile_quote(form, ctx):
    data = rt.first(rt.next(form))
    ctx.push_const(data)

    if rt.meta(form) is not nil:
        compile_meta(rt.meta(form), ctx)
コード例 #45
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)
コード例 #46
0
ファイル: reader.py プロジェクト: rowhit/pixie
def flatten_map_rfn(ret, item):
    return rt.conj(rt.conj(ret, rt.first(item)), rt.first(rt.next(item)))
コード例 #47
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
def compile_quote(form, ctx):
    data = rt.first(rt.next(form))
    ctx.push_const(data)

    if rt.meta(form) is not nil:
        compile_meta(rt.meta(form), ctx)
コード例 #48
0
ファイル: code.py プロジェクト: discoverfly/pixie
 def pop_binding_frame(self):
     self._vars = rt.next(self._vars)
コード例 #49
0
ファイル: lazy_seq.py プロジェクト: Hardikus/pixie
def _next(self):
    assert isinstance(self, LazySeq)
    rt.seq(self)
    return rt.next(self._s)
コード例 #50
0
ファイル: compiler.py プロジェクト: cloudshill/pixie
def compile_quote(form, ctx):
    data = rt.first(rt.next(form))
    ctx.push_const(data)
コード例 #51
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #52
0
ファイル: compiler.py プロジェクト: discoverfly/pixie
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)
コード例 #53
0
def _next(self):
    assert isinstance(self, LazySeq)
    rt.seq(self)
    return rt.next(self._s)
コード例 #54
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)