예제 #1
0
파일: helpers.py 프로젝트: j12n/clvm_tools
def run(prog, macro_lookup):
    """
    PROG => (e (com (q . PROG) (mac)) ARGS)

    The result can be evaluated with the stage_com eval
    function.
    """
    args = TOP.as_path()
    mac = quote(macro_lookup)
    return eval(prog.to([b"com", prog, mac]), args)
예제 #2
0
def build_macro_lookup_program(macro_lookup, macros, run_program):
    macro_lookup_program = macro_lookup.to([QUOTE_KW, macro_lookup])
    for macro in macros:
        macro_lookup_program = eval(
            macro_lookup.to([
                b"opt",
                [
                    b"com", [QUOTE_KW, [CONS_KW, macro, macro_lookup_program]],
                    macro_lookup_program
                ]
            ]), TOP.as_path())
        macro_lookup_program = optimize_sexp(macro_lookup_program, run_program)
    return macro_lookup_program
예제 #3
0
def build_macro_lookup_program(macro_lookup, macros, run_program):
    macro_lookup_program = macro_lookup.to(quote(macro_lookup))
    for macro in macros:
        macro_lookup_program = eval(
            macro_lookup.to([
                b"opt",
                [
                    b"com",
                    quote([CONS_ATOM, macro, macro_lookup_program]),
                    macro_lookup_program
                ]
            ]), TOP.as_path())
        macro_lookup_program = optimize_sexp(macro_lookup_program, run_program)
    return macro_lookup_program
예제 #4
0
def do_com_prog(prog, macro_lookup, symbol_table, run_program):
    """
    Turn the given program `prog` into a clvm program using
    the macros to do transformation.

    prog is an uncompiled s-expression.

    Return a new expanded s-expression PROG_EXP that is equivalent by rewriting
    based upon the operator, where "equivalent" means

    (a (com (q PROG) (MACROS)) ARGS) == (a (q PROG_EXP) ARGS)
    for all ARGS.

    Also, (opt (com (q PROG) (MACROS))) == (opt (com (q PROG_EXP) (MACROS)))
    """

    # lower "quote" to "q"
    prog = lower_quote(prog, macro_lookup, symbol_table, run_program)

    # quote atoms
    if prog.nullp() or not prog.listp():
        atom = prog.as_atom()
        if atom == b"@":
            return prog.to(TOP.as_path())
        for pair in symbol_table.as_iter():
            symbol, value = pair.first(), pair.rest().first()
            if symbol == atom:
                return prog.to(value)

        return prog.to(quote(prog))

    operator = prog.first()
    if operator.listp():
        # (com ((OP) . RIGHT)) => (a (com (q OP)) 1)
        inner_exp = eval(
            prog.to([
                b"com",
                quote(operator),
                quote(macro_lookup),
                quote(symbol_table)
            ]), TOP.as_path())
        return prog.to([inner_exp])

    as_atom = operator.as_atom()

    for macro_pair in macro_lookup.as_iter():
        macro_name = macro_pair.first().as_atom()
        if macro_name == as_atom:
            macro_code = macro_pair.rest().first()
            post_prog = brun(macro_code, prog.rest())
            return eval(
                post_prog.to([
                    b"com", post_prog,
                    quote(macro_lookup),
                    quote(symbol_table)
                ]), TOP.as_short_path())

    if as_atom in COMPILE_BINDINGS:
        f = COMPILE_BINDINGS[as_atom]
        post_prog = f(prog.rest(), macro_lookup, symbol_table, run_program)
        return eval(prog.to(quote(post_prog)), TOP.as_path())

    if operator == QUOTE_ATOM:
        return prog

    compiled_args = [
        do_com_prog(_, macro_lookup, symbol_table, run_program)
        for _ in prog.rest().as_iter()
    ]

    r = prog.to([operator] + compiled_args)

    if as_atom in PASS_THROUGH_OPERATORS or as_atom.startswith(b"_"):
        return r

    for (symbol, value) in symbol_table.as_python():
        if symbol == b"*":
            return r
        if symbol == as_atom:
            new_args = eval(
                prog.to([
                    b"opt",
                    [
                        b"com",
                        quote([b"list"] + list(prog.rest().as_iter())),
                        quote(macro_lookup),
                        quote(symbol_table)
                    ]
                ]), TOP.as_path())
            r = prog.to(
                [APPLY_ATOM, value, [CONS_ATOM,
                                     LEFT.as_path(), new_args]])
            return r

    raise SyntaxError("can't compile %s, unknown operator" % disassemble(prog))