Как clojure вызывает методы в файле clj при вызове функции, определенной в интерфейсе IFn? - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь прочитать исходный код компилятора clojure

Я знаю, что основной метод находится в jvm / clojure / main.java

Существует также файл Java, у которого есть метод main: jvm / clojure/lang/Compile.java

Кажется, я не могу скомпилировать файлы clj, когда я хочу получить clojure.jar, хотя по умолчанию файлы clj будут скомпилированы. Я могу удалить "clojure-compile"раздел в pom.xml, получите 1.8M clojure.jar, а не 4.6M clojure.jar. Это тоже может работать. Я могу только скомпилировать файл java, без файла clj.

В main.javaКажется, что clojure создаст много пространств имен по умолчанию, Vars, Symbols

Затем он "вызовет" некоторый метод, определенный в файле .clj, используя invoke, определенный в IFn.java, например:

in_ns.invoke(USER);
refer.invoke(CLOJURE);
require.invoke(SERVER);
start_servers.invoke(System.getProperties());
REQUIRE.invoke(CLOJURE_MAIN);
MAIN.applyTo(RT.seq(args));

затем bang! 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, оставьте их только в текстовом файле

Ты можешь научить меня? Спасибо!

1 Ответ

0 голосов
/ 06 июля 2019

Не очень понятно, чего вы пытаетесь достичь.Вы пытаетесь скомпилировать Clojure с нуля?Вы пытаетесь понять, как работает компилятор Clojure?

Также кажется, что вы не начинаете с подходящего класса.Класс в clojure.main - это сам REPL Clojure, а не компилятор.Фактически, вы можете запустить его из 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...