summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-11-29 18:42:17 +0000
committerRich Hickey <richhickey@gmail.com>2008-11-29 18:42:17 +0000
commita4f923670d89fd7f4d72f39ec85ec8f46ea43bdc (patch)
tree020f7f0b93170b65c7d2a4f33772178a91172875
parent09c2d0dd2eff4fbe7962d6f68492d3dc1e07d4ff (diff)
enhancements to AOT/gen-class
AOT now only produces __init.class by default, load uses that class only must have at least (:gen-class) ns clause to create named class for ns gen-class can now be called stand-alone new options allow for control of mapping to implementing namespace, name of class, loading of implementing namespace, and method name prefix (doc ns) and (doc gen-class) and http://clojure.org/compilation for details
-rw-r--r--src/clj/clojure/core.clj32
-rw-r--r--src/clj/clojure/genclass.clj287
-rw-r--r--src/clj/clojure/main.clj1
-rw-r--r--src/jvm/clojure/lang/Compile.java14
-rw-r--r--src/jvm/clojure/lang/Compiler.java58
-rw-r--r--src/jvm/clojure/lang/RT.java151
6 files changed, 196 insertions, 347 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 8da29d1c..0d1eb723 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -6,7 +6,7 @@
; the terms of this license.
; You must not remove this notice, or any other, from this software.
-(in-ns 'clojure.core)
+(ns clojure.core)
(def
#^{:arglists '([& items])
@@ -3081,34 +3081,43 @@
[fmt & args]
(print (apply format fmt args)))
+(def gen-class)
+
(defmacro ns
"Sets *ns* to the namespace named by name (unevaluated), creating it
if needed. references can be zero or more of: (:refer-clojure ...)
(:require ...) (:use ...) (:import ...) (:load ...) (:gen-class)
with the syntax of refer-clojure/require/use/import/load/gen-class
respectively, except the arguments are unevaluated and need not be
- quoted, and the :gen-class clause does not take a name (since the
- class name corresponds to the ns name). If :refer-clojure is not
- used, a default (refer 'clojure) is used. The :gen-class directive
- is ignored when not compiling. If :gen-class is not specified, when
- compiled the generated class will have only main. Use of ns is
- preferred to individual calls to in-ns/require/use/import:
-
- (ns foo
+ quoted. (:gen-class ...), when supplied, defaults to :name
+ corresponding to the ns name, :main true, :impl-ns same as ns, and
+ :init-impl-ns true. All options of gen-class are
+ supported. The :gen-class directive is ignored when not
+ compiling. If :gen-class is not supplied, when compiled only an
+ nsname__init.class will be generated. If :refer-clojure is not used, a
+ default (refer 'clojure) is used. Use of ns is preferred to
+ individual calls to in-ns/require/use/import:
+
+ (ns foo.bar
(:refer-clojure :exclude [ancestors printf])
(:require (clojure.contrib sql sql.tests))
(:use (my.lib this that))
(:import (java.util Date Timer Random)
- (java.sql Connection Statement))
- (:load \"/mystuff/foo.clj\"))"
+ (java.sql Connection Statement)))"
+
[name & references]
(let [process-reference
(fn [[kname & args]]
`(~(symbol "clojure.core" (clojure.core/name kname))
~@(map #(list 'quote %) args)))
+ gen-class-clause (first (filter #(= :gen-class (first %)) references))
+ gen-class-call
+ (when gen-class-clause
+ (list* `gen-class :name (.replace (str name) \- \_) :impl-ns name :main true (rest gen-class-clause)))
references (remove #(= :gen-class (first %)) references)]
`(do
(clojure.core/in-ns '~name)
+ ~@(when gen-class-call (list gen-class-call))
~@(when (and (not= name 'clojure.core) (not-any? #(= :refer-clojure (first %)) references))
`((clojure.core/refer '~'clojure.core)))
~@(map process-reference references))))
@@ -3313,6 +3322,7 @@
:reload-all implies :reload and also forces loading of all libs that the
identified libs directly or indirectly load via require or use
:verbose triggers printing information about each load, alias, and refer"
+
[& args]
(apply load-libs :require args))
diff --git a/src/clj/clojure/genclass.clj b/src/clj/clojure/genclass.clj
index 77567916..d84ab614 100644
--- a/src/clj/clojure/genclass.clj
+++ b/src/clj/clojure/genclass.clj
@@ -70,108 +70,22 @@
'byte Byte/TYPE
'char Character/TYPE})
-(defn gen-class
- "This documents the :gen-class directive of the ns function, and is
- not meant to be called directly.
-
- Generates compiled bytecode for a class with the given
- package-qualified cname (which, as all names in these parameters,
- can be a string or symbol). The gen-class construct contains no
- implementation, as the implementation will be dynamically sought by
- the generated class in functions in a corresponding Clojure
- namespace. Given a generated class org.mydomain.MyClass with a
- method named mymethod, gen-class will generate an implementation
- that looks for a function named -mymethod in a Clojure namespace
- called org.mydomain.MyClass . All inherited methods, generated
- methods, and init and main functions (see :methods, :init, and :main
- below) will be found similarly. The static initializer for the
- generated class will attempt to load the Clojure support code for
- the class as a resource from the classpath, e.g. in the example
- case, org/mydomain/MyClass__init.class
-
- Note that methods with a maximum of 18 parameters are supported.
-
- In all subsequent sections taking types, the primitive types can be
- referred to by their Java names (int, float etc), and classes in the
- java.lang package can be used without a package qualifier. All other
- classes must be fully qualified.
-
- Options should be a set of key/value pairs, all of which are optional:
-
- :extends aclass
-
- Specifies the superclass, the non-private methods of which will be
- overridden by the class. If not provided, defaults to Object.
-
- :implements [interface ...]
-
- One or more interfaces, the methods of which will be implemented by the class.
-
- :init name
-
- If supplied, names a function that will be called with the arguments
- to the constructor. Must return [ [superclass-constructor-args] state]
- If not supplied, the constructor args are passed directly to
- the superclass constructor and the state will be nil
-
- :constructors {[param-types] [super-param-types], ...}
-
- By default, constructors are created for the generated class which
- match the signature(s) of the constructors for the superclass. This
- parameter may be used to explicitly specify constructors, each entry
- providing a mapping from a constructor signature to a superclass
- constructor signature. When you supply this, you must supply an :init
- specifier.
-
- :methods [ [name [param-types] return-type], ...]
-
- The generated class automatically defines all of the non-private
- methods of its superclasses/interfaces. This parameter can be used
- to specify the signatures of additional methods of the generated
- class. Static methods can be specified with #^{:static true} in the
- signature's metadata. Do not repeat superclass/interface signatures
- here.
-
- :main boolean
-
- If supplied and true, a static public main function will be
- generated. It will pass each string of the String[] argument as a
- separate argument to a function called 'main.
-
- :factory name
-
- If supplied, a (set of) public static factory function(s) will be
- created with the given name, and the same signature(s) as the
- constructor(s).
-
- :state name
-
- If supplied, a public final instance field with the given name will be
- created. You must supply an :init function in order to provide a
- value for the state. Note that, though final, the state can be a ref
- or agent, supporting the creation of Java objects with transactional
- or asynchronous mutation semantics.
-
- :exposes {protected-field-name {:get name :set name}, ...}
-
- Since the implementations of the methods of the generated class
- occur in Clojure functions, they have no access to the inherited
- protected fields of the superclass. This parameter can be used to
- generate public getter/setter methods exposing the protected field(s)
- for use in the implementation."
-
- [cname & options]
- (let [the-class (fn [x]
- (cond
- (class? x) x
- (contains? prim->class x) (prim->class x)
- :else (let [strx (str x)]
- (clojure.lang.RT/classForName
- (if (some #{\.} strx)
- strx
- (str "java.lang." strx))))))
- name (str cname)
- {:keys [extends implements constructors methods main factory state init exposes]} (apply hash-map options)
+(defn- the-class [x]
+ (cond
+ (class? x) x
+ (contains? prim->class x) (prim->class x)
+ :else (let [strx (str x)]
+ (clojure.lang.RT/classForName
+ (if (some #{\.} strx)
+ strx
+ (str "java.lang." strx))))))
+
+(defn generate-class [options-map]
+ (let [default-options {:prefix "-" :load-impl-ns true :impl-ns (ns-name *ns*)}
+ {:keys [name extends implements constructors methods main factory state init exposes
+ prefix load-impl-ns impl-ns]}
+ (merge default-options options-map)
+ name (str name)
super (if extends (the-class extends) Object)
interfaces (map the-class implements)
supers (cons super interfaces)
@@ -179,6 +93,8 @@
cv (new ClassWriter (. ClassWriter COMPUTE_MAXS))
cname (. name (replace "." "/"))
pkg-name name
+ impl-pkg-name (str impl-ns)
+ impl-cname (.. impl-pkg-name (replace "." "/") (replace \- \_))
ctype (. Type (getObjectType cname))
iname (fn [c] (.. Type (getType c) (getInternalName)))
totype (fn [c] (. Type (getType c)))
@@ -205,8 +121,8 @@
(map (fn [[m p]] {(str m) [p]}) methods)))
sigs-by-name (apply merge-with concat {} all-sigs)
overloads (into {} (filter (fn [[m s]] (rest s)) sigs-by-name))
- var-fields (concat (and init [init-name])
- (and main [main-name])
+ var-fields (concat (when init [init-name])
+ (when main [main-name])
(distinct (concat (keys sigs-by-name)
(mapcat (fn [[m s]] (map #(overload-name m %) s)) overloads)
(mapcat (comp (partial map str) vals val) exposes))))
@@ -225,7 +141,7 @@
(. gen mark end-label)))
emit-unsupported (fn [gen m]
(. gen (throwException ex-type (str (. m (getName)) " ("
- pkg-name "/" "-" (.getName m)
+ impl-pkg-name "/" prefix (.getName m)
" not defined?)"))))
emit-forwarding-method
(fn [mname pclasses rclass as-static else-gen]
@@ -310,14 +226,21 @@
nil nil cv)]
(. gen (visitCode))
(doseq [v var-fields]
- (. gen push pkg-name)
- (. gen push (str "-" v))
+ (. gen push impl-pkg-name)
+ (. gen push (str prefix v))
(. gen (invokeStatic var-type (. Method (getMethod "clojure.lang.Var internPrivate(String,String)"))))
(. gen putStatic ctype (var-name v) var-type))
- (. gen push (str name "__init"))
- (. gen (invokeStatic class-type (. Method (getMethod "Class forName(String)"))))
- (. gen pop)
+ (when load-impl-ns
+ (. gen push "clojure.core")
+ (. gen push "load")
+ (. gen (invokeStatic rt-type (. Method (getMethod "clojure.lang.Var var(String,String)"))))
+ (. gen push (str "/" impl-cname))
+ (. gen (invokeInterface ifn-type (new Method "invoke" obj-type (to-types [Object]))))
+; (. gen push (str (.replace impl-pkg-name \- \_) "__init"))
+; (. gen (invokeStatic class-type (. Method (getMethod "Class forName(String)"))))
+ (. gen pop))
+
(. gen (returnValue))
(. gen (endMethod)))
@@ -373,7 +296,7 @@
(. gen goTo end-label)
;no init found
(. gen mark no-init-label)
- (. gen (throwException ex-type (str init-name " not defined")))
+ (. gen (throwException ex-type (str impl-pkg-name "/" prefix init-name " not defined")))
(. gen mark end-label))
(if (= pclasses super-pclasses)
(do
@@ -444,7 +367,7 @@
(. gen goTo end-label)
;no main found
(. gen mark no-main-label)
- (. gen (throwException ex-type (str pkg-name "/" "-" main-name " not defined")))
+ (. gen (throwException ex-type (str impl-pkg-name "/" prefix main-name " not defined")))
(. gen mark end-label)
(. gen (returnValue))
(. gen (endMethod))))
@@ -471,7 +394,124 @@
(. gen (endMethod))))))
;finish class def
(. cv (visitEnd))
- {:name name :bytecode (. cv (toByteArray))}))
+ [cname (. cv (toByteArray))]))
+
+(defmacro gen-class
+ "When compiling, generates compiled bytecode for a class with the
+ given package-qualified :name (which, as all names in these
+ parameters, can be a string or symbol), and writes the .class file
+ to the *compile-path* directory. When not compiling, does
+ nothing. The gen-class construct contains no implementation, as the
+ implementation will be dynamically sought by the generated class in
+ functions in an implementing Clojure namespace. Given a generated
+ class org.mydomain.MyClass with a method named mymethod, gen-class
+ will generate an implementation that looks for a function named by
+ (str prefix mymethod) (default prefix: \"-\") in a
+ Clojure namespace specified by :impl-ns
+ (defaults to the current namespace). All inherited methods,
+ generated methods, and init and main functions (see :methods, :init,
+ and :main below) will be found similarly prefixed. By default, the
+ static initializer for the generated class will attempt to load the
+ Clojure support code for the class as a resource from the classpath,
+ e.g. in the example case, org/mydomain/MyClass__init.class. This
+ behavior can be controlled by :load-impl-ns
+
+ Note that methods with a maximum of 18 parameters are supported.
+
+ In all subsequent sections taking types, the primitive types can be
+ referred to by their Java names (int, float etc), and classes in the
+ java.lang package can be used without a package qualifier. All other
+ classes must be fully qualified.
+
+ Options should be a set of key/value pairs, all except for :name are optional:
+
+ :name aname
+
+ The package-qualified name of the class to be generated
+
+ :extends aclass
+
+ Specifies the superclass, the non-private methods of which will be
+ overridden by the class. If not provided, defaults to Object.
+
+ :implements [interface ...]
+
+ One or more interfaces, the methods of which will be implemented by the class.
+
+ :init name
+
+ If supplied, names a function that will be called with the arguments
+ to the constructor. Must return [ [superclass-constructor-args] state]
+ If not supplied, the constructor args are passed directly to
+ the superclass constructor and the state will be nil
+
+ :constructors {[param-types] [super-param-types], ...}
+
+ By default, constructors are created for the generated class which
+ match the signature(s) of the constructors for the superclass. This
+ parameter may be used to explicitly specify constructors, each entry
+ providing a mapping from a constructor signature to a superclass
+ constructor signature. When you supply this, you must supply an :init
+ specifier.
+
+ :methods [ [name [param-types] return-type], ...]
+
+ The generated class automatically defines all of the non-private
+ methods of its superclasses/interfaces. This parameter can be used
+ to specify the signatures of additional methods of the generated
+ class. Static methods can be specified with #^{:static true} in the
+ signature's metadata. Do not repeat superclass/interface signatures
+ here.
+
+ :main boolean
+
+ If supplied and true, a static public main function will be generated. It will
+ pass each string of the String[] argument as a separate argument to
+ a function called (str prefix main).
+
+ :factory name
+
+ If supplied, a (set of) public static factory function(s) will be
+ created with the given name, and the same signature(s) as the
+ constructor(s).
+
+ :state name
+
+ If supplied, a public final instance field with the given name will be
+ created. You must supply an :init function in order to provide a
+ value for the state. Note that, though final, the state can be a ref
+ or agent, supporting the creation of Java objects with transactional
+ or asynchronous mutation semantics.
+
+ :exposes {protected-field-name {:get name :set name}, ...}
+
+ Since the implementations of the methods of the generated class
+ occur in Clojure functions, they have no access to the inherited
+ protected fields of the superclass. This parameter can be used to
+ generate public getter/setter methods exposing the protected field(s)
+ for use in the implementation.
+
+ :prefix string
+
+ Default: \"-\" Methods called e.g. Foo will be looked up in vars called
+ prefixFoo in the implementing ns.
+
+ :impl-ns name
+
+ Default: the name of the current ns. Implementations of methods will be looked up in this namespace.
+
+ :load-impl-ns boolean
+
+ Default: true. Causes the static initializer for the generated class
+ to reference the load code for the implementing namespace. Should be
+ true when implementing-ns is the default, false if you intend to
+ load the code via some other method."
+
+ [& options]
+ (when *compile-files*
+ (let [options-map (apply hash-map options)
+ [cname bytecode] (generate-class options-map)]
+ (clojure.lang.Compiler/writeClassFile cname bytecode))))
(comment
@@ -483,22 +523,11 @@
desired namespaces just like any other class. See gen-class for a
description of the options."
- [name & options]
- (let [{:keys [name bytecode]}
- (apply gen-class (str name) options)]
- (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass (str name) bytecode))))
-
-(defn gen-and-save-class
- "Generates the bytecode for the named class and stores in a .class
- file in a subpath of the supplied path, the directories for which
- must already exist. See gen-class for a description of the options"
-
- [path name & options]
- (let [{:keys [name bytecode]} (apply gen-class (str name) options)
- file (java.io.File. path (str (. name replace \. (. java.io.File separatorChar)) ".class"))]
- (.createNewFile file)
- (with-open [f (java.io.FileOutputStream. file)]
- (.write f bytecode))))
+ [& options]
+ (let [options-map (apply hash-map options)
+ [cname bytecode] (generate-class options-map)]
+ (.. clojure.lang.RT ROOT_CLASSLOADER (defineClass cname bytecode))))
+
)
(comment
diff --git a/src/clj/clojure/main.clj b/src/clj/clojure/main.clj
index 2232633c..e369abf0 100644
--- a/src/clj/clojure/main.clj
+++ b/src/clj/clojure/main.clj
@@ -9,6 +9,7 @@
;; Originally contributed by Stephen C. Gilardi
(ns clojure.main
+ (:gen-class)
(:import (clojure.lang Compiler Compiler$CompilerException RT)))
(defmacro with-bindings
diff --git a/src/jvm/clojure/lang/Compile.java b/src/jvm/clojure/lang/Compile.java
index d31b3569..7dbf6822 100644
--- a/src/jvm/clojure/lang/Compile.java
+++ b/src/jvm/clojure/lang/Compile.java
@@ -45,18 +45,16 @@ public static void main(String[] args) throws Exception{
{
Var.pushThreadBindings(RT.map(compile_path, path));
- out.write("Compiling " + count + " " +
- ((count == 1) ? "lib" : "libs") +
- " to " + path);
- out.flush();
-
for(String lib : args)
- compile.invoke(Symbol.intern(lib));
-
- Var.popThreadBindings();
+ {
+ out.write("Compiling " + lib + " to " + path + "\n");
+ out.flush();
+ compile.invoke(Symbol.intern(lib));
+ }
}
finally
{
+ Var.popThreadBindings();
try
{
out.flush();
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 5d5c7b9e..aee53673 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -4061,6 +4061,8 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti
return analyze(context, me, name);
Object op = RT.first(form);
+ if(op == null)
+ throw new IllegalArgumentException("Can't call nil");
IFn inline = isInline(op, RT.count(RT.rest(form)));
if(inline != null)
return analyze(context, inline.applyTo(RT.rest(form)));
@@ -4498,43 +4500,10 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
try
{
- //use genclass for the stub
- String classname = sourcePath.substring(0, sourcePath.lastIndexOf('.')).replace('/', '.');
- Object r = LispReader.read(pushbackReader, false, EOF, false);
- Object genclassArgs = null;
- if(r instanceof IPersistentList
- && (Util.equal(RT.first(r), Symbol.create("ns"))
- || Util.equal(RT.first(r), Symbol.create("clojure.core", "ns"))))
- {
- Keyword gk = Keyword.intern(null, "gen-class");
- Symbol nssym = (Symbol) RT.second(r);
- if(!nssym.toString().replace('-','_').equals(classname))
- throw new Exception(String.format("Namespace name must match file, had: %s and %s",
- nssym, sourcePath));
- for(ISeq s = RT.rest(RT.rest(r)); s != null; s = s.rest())
- {
- Object entry = s.first();
- if(RT.first(entry).equals(gk))
- {
- genclassArgs = RT.rest(entry);
- break;
- }
- }
- }
-
- if(genclassArgs == null)
- genclassArgs = RT.list(Keyword.intern(null, "main"), RT.T);
-
- genclassArgs = RT.cons(classname, genclassArgs);
- Var genclass = RT.var("clojure.core", "gen-class");
- IPersistentMap gret = (IPersistentMap) genclass.applyTo(RT.seq(genclassArgs));
- writeClassFile(sourcePath.substring(0, sourcePath.lastIndexOf('.')),
- (byte[]) RT.get(gret, Keyword.intern(null, "bytecode")));
-
//generate loader class
FnExpr fn = new FnExpr(null);
fn.internalName = sourcePath.replace(File.separator, "/").substring(0, sourcePath.lastIndexOf('.'))
- + "__init";
+ + RT.LOADER_SUFFIX;
fn.fntype = Type.getObjectType(fn.internalName);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@@ -4549,7 +4518,7 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
cv);
gen.visitCode();
- for(; r != EOF;
+ for(Object r = LispReader.read(pushbackReader, false, EOF, false); r != EOF;
r = LispReader.read(pushbackReader, false, EOF, false))
{
LINE_AFTER.set(pushbackReader.getLineNumber());
@@ -4606,25 +4575,6 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t
clinitgen.returnValue();
clinitgen.endMethod();
- //main
-// GeneratorAdapter maingen = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC,
-// Method.getMethod("void main (String[])"),
-// null,
-// null,
-// cv);
-// maingen.visitCode();
-// maingen.push(fn.internalName.replace('/', '.'));
-// maingen.push("main");
-// maingen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.Var var(String,String)"));
-// maingen.loadArgs();
-// maingen.invokeStatic(RT_TYPE, Method.getMethod("clojure.lang.ISeq seq(Object)"));
-// maingen.invokeInterface(IFN_TYPE, new Method("applyTo", OBJECT_TYPE, new Type[]{Type.getType(ISeq.class)}));
-// maingen.pop();
-//
-// //end of main
-// maingen.returnValue();
-// maingen.endMethod();
-
//end of class
cv.visitEnd();
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index f6139d1b..aca1bee2 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -34,6 +34,7 @@ public class RT{
static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null, "t"));
static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t"));
+static final public String LOADER_SUFFIX = "__init";
//simple-symbol->class
final static IPersistentMap DEFAULT_IMPORTS = map(
@@ -193,9 +194,6 @@ final static public Var USE_CONTEXT_CLASSLOADER =
final static Symbol LOAD_FILE = Symbol.create("load-file");
final static Symbol IN_NAMESPACE = Symbol.create("in-ns");
final static Symbol NAMESPACE = Symbol.create("ns");
-//final static Symbol EXPORTS = Symbol.create("*exports*");
-//final static Var EXPORTS_VAR = Var.intern(CLOJURE_NS, EXPORTS, PersistentHashMap.EMPTY);
-//final static Symbol EQL_REF = Symbol.create("eql-ref?");
static final Symbol IDENTICAL = Symbol.create("identical?");
final static Var CMD_LINE_ARGS = Var.intern(CLOJURE_NS, Symbol.create("*command-line-args*"), null);
//symbol
@@ -219,16 +217,6 @@ final static IFn inNamespace = new AFn(){
Symbol nsname = (Symbol) arg1;
Namespace ns = Namespace.findOrCreate(nsname);
CURRENT_NS.set(ns);
-// Var refers = Var.intern(null,Symbol.intern(nsname.name, "*refers*"));
-//
-// Var imports = Var.intern(null,Symbol.intern(nsname.name, "*imports*"), DEFAULT_IMPORTS, false);
-// NS_REFERS.set(refers);
-// NS_IMPORTS.set(imports);
-// if(!refers.isBound())
-// {
-// refers.bindRoot(PersistentHashMap.EMPTY);
-// Compiler.eval(list(Symbol.create("clojure.core", "refer"), EXPORTS));
-// }
return ns;
}
};
@@ -243,28 +231,7 @@ public static List<String> processCommandLine(String[] args){
}
return arglist;
}
-//simple-symbol->var
-//final static Var REFERS =
-// Var.intern(CLOJURE_NS, Symbol.create("*refers*"),
-// map(
-// IN_NAMESPACE, Var.intern(CLOJURE_NS, IN_NAMESPACE, inNamespace),
-// LOAD_FILE, Var.intern(CLOJURE_NS, LOAD_FILE,
-// new AFn(){
-// public Object invoke(Object arg1) throws Exception{
-// return Compiler.loadFile((String) arg1);
-// }
-// }),
-// IDENTICAL, Var.intern(CLOJURE_NS, IDENTICAL,
-// new AFn(){
-// public Object invoke(Object arg1, Object arg2)
-// throws Exception{
-// return arg1 == arg2 ? RT.T : RT.F;
-// }
-// })
-// ));
-
-//static Var NS_IMPORTS = Var.intern(CLOJURE_NS,Symbol.create("*ns-imports*"), IMPORTS);
-//static Var NS_REFERS = Var.intern(CLOJURE_NS,Symbol.create("*ns-refers*"), REFERS);
+
static public final Object[] EMPTY_ARRAY = new Object[]{};
static public final Comparator DEFAULT_COMPARATOR = new Comparator(){
public int compare(Object o1, Object o2){
@@ -272,7 +239,6 @@ static public final Comparator DEFAULT_COMPARATOR = new Comparator(){
}
};
-//static public final Character[] chars;
static AtomicInteger id = new AtomicInteger(1);
static final public DynamicClassLoader ROOT_CLASSLOADER = new DynamicClassLoader();
@@ -291,7 +257,8 @@ static
AGENT.setTag(Symbol.create("clojure.lang.Agent"));
MATH_CONTEXT.setTag(Symbol.create("java.math.MathContext"));
//during bootstrap ns same as in-ns
- Var.intern(CLOJURE_NS, NAMESPACE, inNamespace);
+ Var nv = Var.intern(CLOJURE_NS, NAMESPACE, inNamespace);
+ nv.setMacro();
Var v;
v = Var.intern(CLOJURE_NS, IN_NAMESPACE, inNamespace);
v.setMeta(map(dockw, "Sets *ns* to the namespace named by the symbol, creating it if needed.",
@@ -313,16 +280,6 @@ static
});
v.setMeta(map(dockw, "Tests if 2 arguments are the same object",
arglistskw, list(vector(Symbol.create("x"), Symbol.create("y")))));
-// try
-// {
-// InputStream ins = RT.class.getResourceAsStream("/boot.clj");
-// Compiler.load(new InputStreamReader(ins));
-// }
-// catch(Exception e)
-// {
-// throw new IllegalStateException("Error loading boot.clj", e);
-// }
-
try
{
doInit();
@@ -332,12 +289,6 @@ static
throw new RuntimeException(e);
}
}
-//static
-// {
-// chars = new Character[256];
-// for(int i = 0; i < chars.length; i++)
-// chars[i] = new Character((char) i);
-// }
static public Var var(String ns, String name){
@@ -425,7 +376,7 @@ static public void load(String scriptbase) throws Exception{
}
static public void load(String scriptbase, boolean failIfNotFound) throws Exception{
- String classfile = scriptbase + ".class";
+ String classfile = scriptbase + LOADER_SUFFIX + ".class";
String cljfile = scriptbase + ".clj";
URL classURL = baseLoader().getResource(classfile);
URL cljURL = baseLoader().getResource(cljfile);
@@ -439,7 +390,7 @@ static public void load(String scriptbase, boolean failIfNotFound) throws Except
Var.pushThreadBindings(
RT.map(CURRENT_NS, CURRENT_NS.get(),
WARN_ON_REFLECTION, WARN_ON_REFLECTION.get()));
- loadClassForName(scriptbase.replace('/','.'));
+ loadClassForName(scriptbase.replace('/','.') + LOADER_SUFFIX);
}
finally
{
@@ -462,23 +413,6 @@ static void doInit() throws Exception{
load("clojure/zip",false);
load("clojure/xml",false);
load("clojure/set",false);
-// try
-// {
-// Reflector.invokeStaticMethod("clojure.core", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.zip", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.xml", "load", EMPTY_ARRAY);
-// Reflector.invokeStaticMethod("clojure.set", "load", EMPTY_ARRAY);
-// }
-// finally
-// {
-// Var.popThreadBindings();
-// }
-// loadResourceScript(RT.class, "clojure/core.clj");
-// loadResourceScript(RT.class, "clojure/proxy.clj", false);
-// loadResourceScript(RT.class, "clojure/genclass.clj", false);
-// loadResourceScript(RT.class, "clojure/zip.clj", false);
-// loadResourceScript(RT.class, "clojure/xml.clj", false);
-// loadResourceScript(RT.class, "clojure/set.clj", false);
Var.pushThreadBindings(
RT.map(CURRENT_NS, CURRENT_NS.get(),
@@ -504,38 +438,6 @@ static public int nextID(){
return id.getAndIncrement();
}
-//static public Object eq(Object arg1, Object arg2){
-// return (arg1 == arg2) ? Boolean.TRUE : null;
-//}
-//
-//static public Object eql(Object arg1, Object arg2){
-// if(arg1 == arg2)
-// return Boolean.TRUE;
-// if(arg1 == null || arg2 == null)
-// return null;
-// if(arg1 instanceof Num
-// && arg1.getClass() == arg2.getClass()
-// && arg1.equals(arg2))
-// return Boolean.TRUE;
-// if(arg1.getClass() == Character.class
-// && arg2.getClass() == Character.class
-// && arg1.equals(arg2))
-// return Boolean.TRUE;
-// return null;
-//}
-
-// static public Object equal(Object arg1, Object arg2) {
-// if(arg1 == null)
-// return arg2 == null ? Boolean.TRUE : null;
-// else if(arg2 == null)
-// return null;
-// return (eql(arg1,arg2) != null
-// || (arg1.getClass() == Cons.class
-// && arg2.getClass() == Cons.class
-// && equal(((Cons)arg1)._first,((Cons)arg2)._first)!=null
-// && equal(((Cons)arg1)._rest,((Cons)arg2)._rest)!=null))
-// ?Boolean.TRUE:null;
-// }
////////////// Collections support /////////////////////////////////
@@ -559,10 +461,6 @@ static ISeq seqFrom(Object coll){
return StringSeq.create((String) coll);
else if(coll instanceof Map)
return seq(((Map) coll).entrySet());
-// else if(coll instanceof Iterator)
-// return IteratorSeq.create((Iterator) coll);
-// else if(coll instanceof Enumeration)
-// return EnumerationSeq.create(((Enumeration) coll));
else
throw new IllegalArgumentException("Don't know how to create ISeq from: " + coll.getClass().getSimpleName());
}
@@ -680,7 +578,6 @@ static public Object get(Object coll, Object key){
}
return null;
- //throw new UnsupportedOperationException("get not supported on this type");
}
static public Object get(Object coll, Object key, Object notFound){
@@ -709,7 +606,6 @@ static public Object get(Object coll, Object key, Object notFound){
}
return notFound;
-// throw new UnsupportedOperationException("get not supported on this type");
}
static public Associative assoc(Object coll, Object key, Object val){
@@ -736,7 +632,6 @@ static public Object contains(Object coll, Object key){
return n >= 0 && n < count(coll);
}
return F;
- //throw new UnsupportedOperationException("contains not supported on this type");
}
static public Object find(Object coll, Object key){
@@ -890,24 +785,6 @@ static public Object assocN(int n, Object val, Object coll){
return null;
}
-/*
-static public Iter iter(Object coll){
- if(coll == null || coll instanceof Iter)
- return (Iter) coll;
- else if(coll instanceof Iterator)
- {
- Iterator i = (Iterator) coll;
- if(i.hasNext())
- return new IteratorIter(i);
- return null;
- }
- else if(coll instanceof Iterable)
- return new IteratorIter(((Iterable) coll).iterator());
-
- else
- throw new IllegalArgumentException("Don't know how to create Iter from arg");
-}
- */
static boolean hasTag(Object o, Object tag){
if(!(o instanceof IObj))
return false;
@@ -1357,12 +1234,6 @@ static public void print(Object x, Writer w) throws Exception{
w.write('"');
}
}
-// else if(x instanceof ArgVector)
-// {
-// w.write('|');
-// printInnerSeq(seq(x), w);
-// w.write('|');
-// }
else if(x instanceof IPersistentMap)
{
w.write('{');
@@ -1400,16 +1271,6 @@ static public void print(Object x, Writer w) throws Exception{
}
w.write('}');
}
-// else if(x instanceof Map.Entry)
-// {
-// Map.Entry e = (Map.Entry) x;
-// w.write('{');
-// print(e.getKey(),w);
-// w.write(' ');
-// print(e.getValue(),w);
-//
-// w.write('}');
-// }
else if(x instanceof Character)
{
char c = ((Character) x).charValue();