我尝试阅读clojure的编译器源代码
我知道主要方法在jvm / clojure / main.java
还有一个具有主要方法的Java文件:jvm / clojure / lang / Compile.java
当我想获取clojure.jar时似乎无法编译clj文件,尽管默认情况下会编译clj文件。我可以删除pom.xml中的“ clojure-compile”部分,得到1.8 M clojure.jar,而不是4.6M clojure.jar。那也可以。我只能编译java文件,没有clj文件。
在main.java中,clojure似乎会创建许多默认的命名空间,变量,符号
然后它将使用IFn.java中定义的调用“调用” .clj文件中定义的某些方法,例如:
in_ns.invoke(USER);
refer.invoke(CLOJURE);
require.invoke(SERVER);
start_servers.invoke(System.getProperties());
REQUIRE.invoke(CLOJURE_MAIN);
MAIN.applyTo(RT.seq(args));
然后爆炸!clojure可以工作,我可以跑步(+1 1)
但是我找不到invoke方法的实现在哪里。它似乎是空的。在Var.java中,接口是这样实现的:
return fn().invoke(Util.ret1(arg1,arg1=null));
final public IFn fn(){
return (IFn) deref();
}
final public Object deref(){
TBox b = getThreadBinding();
if(b != null)
return b.val;
return root;
}
线程似乎有这个:
Var.pushThreadBindings(
RT.mapUniqueKeys(CURRENT_NS, CURRENT_NS.deref(),
WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref()
,RT.UNCHECKED_MATH, RT.UNCHECKED_MATH.deref()));
无论如何,我阅读了源代码的时间,似乎已经创建了许多数据结构,但是我不知道如何调用clj文件中定义的方法,即使我不能编译clj文件,也只能保持它们文本文件
你能教我吗?谢谢!
答案 0 :(得分:0)
目前尚不清楚您要实现的目标。您是否正在尝试从头开始编译Clojure本身?您是否要了解Clojure编译器的工作原理?
似乎您还没有从正确的课程开始。 clojure.main中的类是Clojure REPL本身,而不是编译器。实际上,您可以从Java启动它:
$ java -cp /home/denis/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar:/home/denis/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar clojure.main
Clojure 1.10.0
user=> (+ 1 2)
3
有关Clojure编译过程的参考文档可能会很有用:https://clojure.org/reference/compilation。要记住的重要一点是在文档的开头:
Clojure将您即时加载的所有代码编译为JVM字节码
每次在REPL中定义功能或加载文件时,都会生成一些字节码。这将包括一个或多个.class
文件,其中一些可能是实现IFn interface的类。