美文网首页
clojure eval compile

clojure eval compile

作者: onedam | 来源:发表于2021-03-09 17:36 被阅读0次

无论 eval 还是 直接 compile 都生成了jvm字节码类. compile 会在磁盘上生成文件. eval
直接load 不会生成类.

public static Object eval(Object form, boolean freshLoader) {
    boolean createdLoader = false;
    if(true)//!LOADER.isBound())
        {
        Var.pushThreadBindings(RT.map(LOADER, RT.makeClassLoader()));
        createdLoader = true;
        }
    try
        {
        IPersistentMap meta = RT.meta(form);
        Object line = (meta != null ? meta.valAt(RT.LINE_KEY, LINE.deref()) : LINE.deref());
        Object column = (meta != null ? meta.valAt(RT.COLUMN_KEY, COLUMN.deref()) : COLUMN.deref());
        IPersistentMap bindings = RT.mapUniqueKeys(LINE, line, COLUMN, column);
        if(meta != null) {
            Object eval_file = meta.valAt(RT.EVAL_FILE_KEY);
            if(eval_file != null) {
                bindings = bindings.assoc(SOURCE_PATH, eval_file);
                try {
                    bindings = bindings.assoc(SOURCE, new File((String)eval_file).getName());
                } catch (Throwable t) {
                }
            }
        }
        Var.pushThreadBindings(bindings);
        try
            {
            form = macroexpand(form);
            if(form instanceof ISeq && Util.equals(RT.first(form), DO))
                {
                ISeq s = RT.next(form);
                for(; RT.next(s) != null; s = RT.next(s))
                    eval(RT.first(s), false);
                return eval(RT.first(s), false);
                }
            else if((form instanceof IType) ||
                    (form instanceof IPersistentCollection
                    && !(RT.first(form) instanceof Symbol
                        && ((Symbol) RT.first(form)).name.startsWith("def"))))
                {
                ObjExpr fexpr = (ObjExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form),
                                                    "eval" + RT.nextID());
                IFn fn = (IFn) fexpr.eval();
                return fn.invoke();
                }
            else
                {
                Expr expr = analyze(C.EVAL, form);
                return expr.eval();  //需要返回
                }
            }
        finally
            {
            Var.popThreadBindings();
            }
        }

    finally
        {
        if(createdLoader)
            Var.popThreadBindings();
        }
}
static void compile1(GeneratorAdapter gen, ObjExpr objx, Object form) {
    Object line = lineDeref();
    Object column = columnDeref();
    if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY))
        line = RT.meta(form).valAt(RT.LINE_KEY);
    if(RT.meta(form) != null && RT.meta(form).containsKey(RT.COLUMN_KEY))
        column = RT.meta(form).valAt(RT.COLUMN_KEY);
    Var.pushThreadBindings(
            RT.map(LINE, line, COLUMN, column
                   ,LOADER, RT.makeClassLoader()
            ));
    try
        {
        form = macroexpand(form);
        if(form instanceof ISeq && Util.equals(RT.first(form), DO))
            {
            for(ISeq s = RT.next(form); s != null; s = RT.next(s))
                {
                compile1(gen, objx, RT.first(s));
                }
            }
        else
            {
            Expr expr = analyze(C.EVAL, form);
            objx.keywords = (IPersistentMap) KEYWORDS.deref();
            objx.vars = (IPersistentMap) VARS.deref();
            objx.constants = (PersistentVector) CONSTANTS.deref();
            expr.emit(C.EXPRESSION, objx, gen);
            expr.eval();      // 不需要返回 ,但 eval 和compile 都会 eval .
                                               //这就是clojure文件中写了调用函数都会执行的原因
            }
        }
    finally
        {
        Var.popThreadBindings();
        }
}

相关文章

网友评论

      本文标题:clojure eval compile

      本文链接:https://www.haomeiwen.com/subject/czhbqltx.html