美文网首页
Clojure 编译器实现(1)

Clojure 编译器实现(1)

作者: zacone | 来源:发表于2022-08-11 23:15 被阅读0次

Clojure编译的起点

Clojure项目可以使用maven编译,从maven的配置看,是通过maven-antrun-plugin插件触发的Clojure官方库编译。

  • pom.xml
      <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.6</version>
    <executions>
      <execution>
        <id>clojure-compile</id>
        <phase>compile</phase>
        <goals>
          <goal>run</goal>
        </goals>
        <configuration>
          <target>
                <property name="maven.compile.classpath" refid="maven.compile.classpath" />
        <ant target="compile-clojure" />
          </target>
        </configuration>
      </execution>
      <execution>
        <id>clojure-test</id>
        <phase>test</phase>
        <goals>
          <goal>run</goal>
        </goals>
        <configuration>
          <target>
                <property name="maven.test.classpath" refid="maven.test.classpath" />
        <ant target="test" />
          </target>
        </configuration>
      </execution>
    </executions>
      </plugin>

这是一个执行ant命令的插件,实际执行了ant的compile-clojure

  • build.xml
  <target name="compile-clojure"
          description="Compile Clojure sources.">
    <java classname="clojure.lang.Compile"
          classpath="${maven.compile.classpath}:${build}:${cljsrc}"
          failonerror="true"
          fork="true">
      <sysproperty key="clojure.compile.path" value="${build}"/>
         <!--<sysproperty key="clojure.compiler.elide-meta" value="[:doc :file :line :added]"/>-->
         <!--<sysproperty key="clojure.compiler.disable-locals-clearing" value="true"/>-->
       <!--<sysproperty key="clojure.compile.warn-on-reflection" value="true"/>-->
        <sysproperty key="clojure.compiler.direct-linking" value="true"/>
      <sysproperty key="java.awt.headless" value="true"/>
      <arg value="clojure.core"/>
      <arg value="clojure.core.protocols"/>
      <arg value="clojure.core.server"/>
      <arg value="clojure.main"/>
      <arg value="clojure.set"/>
      <arg value="clojure.edn"/>
      <arg value="clojure.xml"/>
      <arg value="clojure.zip"/>
      <arg value="clojure.inspector"/>
      <arg value="clojure.walk"/>
      <arg value="clojure.stacktrace"/>
      <arg value="clojure.template"/>
      <arg value="clojure.test"/>
      <arg value="clojure.test.tap"/>
      <arg value="clojure.test.junit"/>
      <arg value="clojure.pprint"/>
      <arg value="clojure.java.io"/>
      <arg value="clojure.repl"/>
      <arg value="clojure.java.browse"/>
      <arg value="clojure.java.javadoc"/>
      <arg value="clojure.java.shell"/>
      <arg value="clojure.java.browse-ui"/>
      <arg value="clojure.string"/>
      <arg value="clojure.data"/>
      <arg value="clojure.reflect"/>
      <arg value="clojure.datafy"/>
      <arg value="clojure.instant"/>
      <arg value="clojure.uuid"/>
      <arg value="clojure.core.reducers"/>
      <arg value="clojure.math"/>
    </java>
  </target>

可见最终调用了java类clojure.lang.Compilemain方法执行了编译,同时在classpath配置了clojure.compile.path作为Clojure编译器的输出目录,并将需要编译的Clojure官方库需要编译的namespace通过main方法传入

  • Compile.java
public static void main(String[] args) throws IOException, ClassNotFoundException{
    RT.init();
    OutputStreamWriter out = (OutputStreamWriter) RT.OUT.deref();
    PrintWriter err = RT.errPrintWriter();
    String path = System.getProperty(PATH_PROP);
    int count = args.length;

    if(path == null)
        {
        err.println("ERROR: Must set system property " + PATH_PROP +
                    "\nto the location for compiled .class files." +
                    "\nThis directory must also be on your CLASSPATH.");
        System.exit(1);
        }

    boolean warnOnReflection = System.getProperty(REFLECTION_WARNING_PROP, "false").equals("true");
    String uncheckedMathProp = System.getProperty(UNCHECKED_MATH_PROP);
    Object uncheckedMath = Boolean.FALSE;
    if("true".equals(uncheckedMathProp))
        uncheckedMath = Boolean.TRUE;
    else if("warn-on-boxed".equals(uncheckedMathProp))
        uncheckedMath = Keyword.intern("warn-on-boxed");

    // force load to avoid transitive compilation during lazy load
    RT.load("clojure/core/specs/alpha");

    try
        {
               Var.pushThreadBindings(RT.map(compile_path, path,
                       warn_on_reflection, warnOnReflection,
                       unchecked_math, uncheckedMath));

        for(String lib : args)
        {
            out.write("Compiling " + lib + " to " + path + "\n");
            out.flush();
            compile.invoke(Symbol.intern(lib));
        }
        }
    finally
        {
        Var.popThreadBindings();
        try
            {
            out.flush();
            }
        catch(IOException e)
            {
            e.printStackTrace(err);
            }
        }
}

相关文章

网友评论

      本文标题:Clojure 编译器实现(1)

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