美文网首页
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