rlm@10
|
1 /**
|
rlm@10
|
2 * Copyright (c) Rich Hickey. All rights reserved.
|
rlm@10
|
3 * The use and distribution terms for this software are covered by the
|
rlm@10
|
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
rlm@10
|
5 * which can be found in the file epl-v10.html at the root of this distribution.
|
rlm@10
|
6 * By using this software in any fashion, you are agreeing to be bound by
|
rlm@10
|
7 * the terms of this license.
|
rlm@10
|
8 * You must not remove this notice, or any other, from this software.
|
rlm@10
|
9 **/
|
rlm@10
|
10
|
rlm@10
|
11 /* rich Mar 25, 2006 4:28:27 PM */
|
rlm@10
|
12
|
rlm@10
|
13 package clojure.lang;
|
rlm@10
|
14
|
rlm@10
|
15 import java.util.concurrent.atomic.AtomicInteger;
|
rlm@10
|
16 import java.util.concurrent.Callable;
|
rlm@10
|
17 import java.util.*;
|
rlm@10
|
18 import java.util.regex.Matcher;
|
rlm@10
|
19 import java.util.regex.Pattern;
|
rlm@10
|
20 import java.io.*;
|
rlm@10
|
21 import java.lang.reflect.Array;
|
rlm@10
|
22 import java.math.BigDecimal;
|
rlm@10
|
23 import java.math.BigInteger;
|
rlm@10
|
24 import java.security.AccessController;
|
rlm@10
|
25 import java.security.PrivilegedAction;
|
rlm@10
|
26 import java.net.URL;
|
rlm@10
|
27 import java.net.JarURLConnection;
|
rlm@10
|
28 import java.nio.charset.Charset;
|
rlm@10
|
29
|
rlm@10
|
30 public class RT{
|
rlm@10
|
31
|
rlm@10
|
32 static final public Boolean T = Boolean.TRUE;//Keyword.intern(Symbol.create(null, "t"));
|
rlm@10
|
33 static final public Boolean F = Boolean.FALSE;//Keyword.intern(Symbol.create(null, "t"));
|
rlm@10
|
34 static final public String LOADER_SUFFIX = "__init";
|
rlm@10
|
35
|
rlm@10
|
36 //simple-symbol->class
|
rlm@10
|
37 final static IPersistentMap DEFAULT_IMPORTS = map(
|
rlm@10
|
38 // Symbol.create("RT"), "clojure.lang.RT",
|
rlm@10
|
39 // Symbol.create("Num"), "clojure.lang.Num",
|
rlm@10
|
40 // Symbol.create("Symbol"), "clojure.lang.Symbol",
|
rlm@10
|
41 // Symbol.create("Keyword"), "clojure.lang.Keyword",
|
rlm@10
|
42 // Symbol.create("Var"), "clojure.lang.Var",
|
rlm@10
|
43 // Symbol.create("Ref"), "clojure.lang.Ref",
|
rlm@10
|
44 // Symbol.create("IFn"), "clojure.lang.IFn",
|
rlm@10
|
45 // Symbol.create("IObj"), "clojure.lang.IObj",
|
rlm@10
|
46 // Symbol.create("ISeq"), "clojure.lang.ISeq",
|
rlm@10
|
47 // Symbol.create("IPersistentCollection"),
|
rlm@10
|
48 // "clojure.lang.IPersistentCollection",
|
rlm@10
|
49 // Symbol.create("IPersistentMap"), "clojure.lang.IPersistentMap",
|
rlm@10
|
50 // Symbol.create("IPersistentList"), "clojure.lang.IPersistentList",
|
rlm@10
|
51 // Symbol.create("IPersistentVector"), "clojure.lang.IPersistentVector",
|
rlm@10
|
52 Symbol.create("Boolean"), Boolean.class,
|
rlm@10
|
53 Symbol.create("Byte"), Byte.class,
|
rlm@10
|
54 Symbol.create("Character"), Character.class,
|
rlm@10
|
55 Symbol.create("Class"), Class.class,
|
rlm@10
|
56 Symbol.create("ClassLoader"), ClassLoader.class,
|
rlm@10
|
57 Symbol.create("Compiler"), Compiler.class,
|
rlm@10
|
58 Symbol.create("Double"), Double.class,
|
rlm@10
|
59 Symbol.create("Enum"), Enum.class,
|
rlm@10
|
60 Symbol.create("Float"), Float.class,
|
rlm@10
|
61 Symbol.create("InheritableThreadLocal"), InheritableThreadLocal.class,
|
rlm@10
|
62 Symbol.create("Integer"), Integer.class,
|
rlm@10
|
63 Symbol.create("Long"), Long.class,
|
rlm@10
|
64 Symbol.create("Math"), Math.class,
|
rlm@10
|
65 Symbol.create("Number"), Number.class,
|
rlm@10
|
66 Symbol.create("Object"), Object.class,
|
rlm@10
|
67 Symbol.create("Package"), Package.class,
|
rlm@10
|
68 Symbol.create("Process"), Process.class,
|
rlm@10
|
69 Symbol.create("ProcessBuilder"), ProcessBuilder.class,
|
rlm@10
|
70 Symbol.create("Runtime"), Runtime.class,
|
rlm@10
|
71 Symbol.create("RuntimePermission"), RuntimePermission.class,
|
rlm@10
|
72 Symbol.create("SecurityManager"), SecurityManager.class,
|
rlm@10
|
73 Symbol.create("Short"), Short.class,
|
rlm@10
|
74 Symbol.create("StackTraceElement"), StackTraceElement.class,
|
rlm@10
|
75 Symbol.create("StrictMath"), StrictMath.class,
|
rlm@10
|
76 Symbol.create("String"), String.class,
|
rlm@10
|
77 Symbol.create("StringBuffer"), StringBuffer.class,
|
rlm@10
|
78 Symbol.create("StringBuilder"), StringBuilder.class,
|
rlm@10
|
79 Symbol.create("System"), System.class,
|
rlm@10
|
80 Symbol.create("Thread"), Thread.class,
|
rlm@10
|
81 Symbol.create("ThreadGroup"), ThreadGroup.class,
|
rlm@10
|
82 Symbol.create("ThreadLocal"), ThreadLocal.class,
|
rlm@10
|
83 Symbol.create("Throwable"), Throwable.class,
|
rlm@10
|
84 Symbol.create("Void"), Void.class,
|
rlm@10
|
85 Symbol.create("Appendable"), Appendable.class,
|
rlm@10
|
86 Symbol.create("CharSequence"), CharSequence.class,
|
rlm@10
|
87 Symbol.create("Cloneable"), Cloneable.class,
|
rlm@10
|
88 Symbol.create("Comparable"), Comparable.class,
|
rlm@10
|
89 Symbol.create("Iterable"), Iterable.class,
|
rlm@10
|
90 Symbol.create("Readable"), Readable.class,
|
rlm@10
|
91 Symbol.create("Runnable"), Runnable.class,
|
rlm@10
|
92 Symbol.create("Callable"), Callable.class,
|
rlm@10
|
93 Symbol.create("BigInteger"), BigInteger.class,
|
rlm@10
|
94 Symbol.create("BigDecimal"), BigDecimal.class,
|
rlm@10
|
95 Symbol.create("ArithmeticException"), ArithmeticException.class,
|
rlm@10
|
96 Symbol.create("ArrayIndexOutOfBoundsException"), ArrayIndexOutOfBoundsException.class,
|
rlm@10
|
97 Symbol.create("ArrayStoreException"), ArrayStoreException.class,
|
rlm@10
|
98 Symbol.create("ClassCastException"), ClassCastException.class,
|
rlm@10
|
99 Symbol.create("ClassNotFoundException"), ClassNotFoundException.class,
|
rlm@10
|
100 Symbol.create("CloneNotSupportedException"), CloneNotSupportedException.class,
|
rlm@10
|
101 Symbol.create("EnumConstantNotPresentException"), EnumConstantNotPresentException.class,
|
rlm@10
|
102 Symbol.create("Exception"), Exception.class,
|
rlm@10
|
103 Symbol.create("IllegalAccessException"), IllegalAccessException.class,
|
rlm@10
|
104 Symbol.create("IllegalArgumentException"), IllegalArgumentException.class,
|
rlm@10
|
105 Symbol.create("IllegalMonitorStateException"), IllegalMonitorStateException.class,
|
rlm@10
|
106 Symbol.create("IllegalStateException"), IllegalStateException.class,
|
rlm@10
|
107 Symbol.create("IllegalThreadStateException"), IllegalThreadStateException.class,
|
rlm@10
|
108 Symbol.create("IndexOutOfBoundsException"), IndexOutOfBoundsException.class,
|
rlm@10
|
109 Symbol.create("InstantiationException"), InstantiationException.class,
|
rlm@10
|
110 Symbol.create("InterruptedException"), InterruptedException.class,
|
rlm@10
|
111 Symbol.create("NegativeArraySizeException"), NegativeArraySizeException.class,
|
rlm@10
|
112 Symbol.create("NoSuchFieldException"), NoSuchFieldException.class,
|
rlm@10
|
113 Symbol.create("NoSuchMethodException"), NoSuchMethodException.class,
|
rlm@10
|
114 Symbol.create("NullPointerException"), NullPointerException.class,
|
rlm@10
|
115 Symbol.create("NumberFormatException"), NumberFormatException.class,
|
rlm@10
|
116 Symbol.create("RuntimeException"), RuntimeException.class,
|
rlm@10
|
117 Symbol.create("SecurityException"), SecurityException.class,
|
rlm@10
|
118 Symbol.create("StringIndexOutOfBoundsException"), StringIndexOutOfBoundsException.class,
|
rlm@10
|
119 Symbol.create("TypeNotPresentException"), TypeNotPresentException.class,
|
rlm@10
|
120 Symbol.create("UnsupportedOperationException"), UnsupportedOperationException.class,
|
rlm@10
|
121 Symbol.create("AbstractMethodError"), AbstractMethodError.class,
|
rlm@10
|
122 Symbol.create("AssertionError"), AssertionError.class,
|
rlm@10
|
123 Symbol.create("ClassCircularityError"), ClassCircularityError.class,
|
rlm@10
|
124 Symbol.create("ClassFormatError"), ClassFormatError.class,
|
rlm@10
|
125 Symbol.create("Error"), Error.class,
|
rlm@10
|
126 Symbol.create("ExceptionInInitializerError"), ExceptionInInitializerError.class,
|
rlm@10
|
127 Symbol.create("IllegalAccessError"), IllegalAccessError.class,
|
rlm@10
|
128 Symbol.create("IncompatibleClassChangeError"), IncompatibleClassChangeError.class,
|
rlm@10
|
129 Symbol.create("InstantiationError"), InstantiationError.class,
|
rlm@10
|
130 Symbol.create("InternalError"), InternalError.class,
|
rlm@10
|
131 Symbol.create("LinkageError"), LinkageError.class,
|
rlm@10
|
132 Symbol.create("NoClassDefFoundError"), NoClassDefFoundError.class,
|
rlm@10
|
133 Symbol.create("NoSuchFieldError"), NoSuchFieldError.class,
|
rlm@10
|
134 Symbol.create("NoSuchMethodError"), NoSuchMethodError.class,
|
rlm@10
|
135 Symbol.create("OutOfMemoryError"), OutOfMemoryError.class,
|
rlm@10
|
136 Symbol.create("StackOverflowError"), StackOverflowError.class,
|
rlm@10
|
137 Symbol.create("ThreadDeath"), ThreadDeath.class,
|
rlm@10
|
138 Symbol.create("UnknownError"), UnknownError.class,
|
rlm@10
|
139 Symbol.create("UnsatisfiedLinkError"), UnsatisfiedLinkError.class,
|
rlm@10
|
140 Symbol.create("UnsupportedClassVersionError"), UnsupportedClassVersionError.class,
|
rlm@10
|
141 Symbol.create("VerifyError"), VerifyError.class,
|
rlm@10
|
142 Symbol.create("VirtualMachineError"), VirtualMachineError.class,
|
rlm@10
|
143 Symbol.create("Thread$UncaughtExceptionHandler"), Thread.UncaughtExceptionHandler.class,
|
rlm@10
|
144 Symbol.create("Thread$State"), Thread.State.class,
|
rlm@10
|
145 Symbol.create("Deprecated"), Deprecated.class,
|
rlm@10
|
146 Symbol.create("Override"), Override.class,
|
rlm@10
|
147 Symbol.create("SuppressWarnings"), SuppressWarnings.class
|
rlm@10
|
148
|
rlm@10
|
149 // Symbol.create("Collection"), "java.util.Collection",
|
rlm@10
|
150 // Symbol.create("Comparator"), "java.util.Comparator",
|
rlm@10
|
151 // Symbol.create("Enumeration"), "java.util.Enumeration",
|
rlm@10
|
152 // Symbol.create("EventListener"), "java.util.EventListener",
|
rlm@10
|
153 // Symbol.create("Formattable"), "java.util.Formattable",
|
rlm@10
|
154 // Symbol.create("Iterator"), "java.util.Iterator",
|
rlm@10
|
155 // Symbol.create("List"), "java.util.List",
|
rlm@10
|
156 // Symbol.create("ListIterator"), "java.util.ListIterator",
|
rlm@10
|
157 // Symbol.create("Map"), "java.util.Map",
|
rlm@10
|
158 // Symbol.create("Map$Entry"), "java.util.Map$Entry",
|
rlm@10
|
159 // Symbol.create("Observer"), "java.util.Observer",
|
rlm@10
|
160 // Symbol.create("Queue"), "java.util.Queue",
|
rlm@10
|
161 // Symbol.create("RandomAccess"), "java.util.RandomAccess",
|
rlm@10
|
162 // Symbol.create("Set"), "java.util.Set",
|
rlm@10
|
163 // Symbol.create("SortedMap"), "java.util.SortedMap",
|
rlm@10
|
164 // Symbol.create("SortedSet"), "java.util.SortedSet"
|
rlm@10
|
165 );
|
rlm@10
|
166
|
rlm@10
|
167 // single instance of UTF-8 Charset, so as to avoid catching UnsupportedCharsetExceptions everywhere
|
rlm@10
|
168 static public Charset UTF8 = Charset.forName("UTF-8");
|
rlm@10
|
169
|
rlm@10
|
170 static public final Namespace CLOJURE_NS = Namespace.findOrCreate(Symbol.create("clojure.core"));
|
rlm@10
|
171 //static final Namespace USER_NS = Namespace.findOrCreate(Symbol.create("user"));
|
rlm@10
|
172 final static public Var OUT =
|
rlm@10
|
173 Var.intern(CLOJURE_NS, Symbol.create("*out*"), new OutputStreamWriter(System.out));
|
rlm@10
|
174 final static public Var IN =
|
rlm@10
|
175 Var.intern(CLOJURE_NS, Symbol.create("*in*"),
|
rlm@10
|
176 new LineNumberingPushbackReader(new InputStreamReader(System.in)));
|
rlm@10
|
177 final static public Var ERR =
|
rlm@10
|
178 Var.intern(CLOJURE_NS, Symbol.create("*err*"),
|
rlm@10
|
179 new PrintWriter(new OutputStreamWriter(System.err), true));
|
rlm@10
|
180 final static Keyword TAG_KEY = Keyword.intern(null, "tag");
|
rlm@10
|
181 final static public Var AGENT = Var.intern(CLOJURE_NS, Symbol.create("*agent*"), null);
|
rlm@10
|
182 final static public Var READEVAL = Var.intern(CLOJURE_NS, Symbol.create("*read-eval*"), T);
|
rlm@10
|
183 final static public Var ASSERT = Var.intern(CLOJURE_NS, Symbol.create("*assert*"), T);
|
rlm@10
|
184 final static public Var MATH_CONTEXT = Var.intern(CLOJURE_NS, Symbol.create("*math-context*"), null);
|
rlm@10
|
185 static Keyword LINE_KEY = Keyword.intern(null, "line");
|
rlm@10
|
186 static Keyword FILE_KEY = Keyword.intern(null, "file");
|
rlm@10
|
187 static Keyword DECLARED_KEY = Keyword.intern(null, "declared");
|
rlm@10
|
188 final static public Var USE_CONTEXT_CLASSLOADER =
|
rlm@10
|
189 Var.intern(CLOJURE_NS, Symbol.create("*use-context-classloader*"), T);
|
rlm@10
|
190 //final static public Var CURRENT_MODULE = Var.intern(Symbol.create("clojure.core", "current-module"),
|
rlm@10
|
191 // Module.findOrCreateModule("clojure/user"));
|
rlm@10
|
192
|
rlm@10
|
193 final static Symbol LOAD_FILE = Symbol.create("load-file");
|
rlm@10
|
194 final static Symbol IN_NAMESPACE = Symbol.create("in-ns");
|
rlm@10
|
195 final static Symbol NAMESPACE = Symbol.create("ns");
|
rlm@10
|
196 static final Symbol IDENTICAL = Symbol.create("identical?");
|
rlm@10
|
197 final static Var CMD_LINE_ARGS = Var.intern(CLOJURE_NS, Symbol.create("*command-line-args*"), null);
|
rlm@10
|
198 //symbol
|
rlm@10
|
199 final public static Var CURRENT_NS = Var.intern(CLOJURE_NS, Symbol.create("*ns*"),
|
rlm@10
|
200 CLOJURE_NS);
|
rlm@10
|
201
|
rlm@10
|
202 final static Var FLUSH_ON_NEWLINE = Var.intern(CLOJURE_NS, Symbol.create("*flush-on-newline*"), T);
|
rlm@10
|
203 final static Var PRINT_META = Var.intern(CLOJURE_NS, Symbol.create("*print-meta*"), F);
|
rlm@10
|
204 final static Var PRINT_READABLY = Var.intern(CLOJURE_NS, Symbol.create("*print-readably*"), T);
|
rlm@10
|
205 final static Var PRINT_DUP = Var.intern(CLOJURE_NS, Symbol.create("*print-dup*"), F);
|
rlm@10
|
206 final static Var WARN_ON_REFLECTION = Var.intern(CLOJURE_NS, Symbol.create("*warn-on-reflection*"), F);
|
rlm@10
|
207 final static Var ALLOW_UNRESOLVED_VARS = Var.intern(CLOJURE_NS, Symbol.create("*allow-unresolved-vars*"), F);
|
rlm@10
|
208
|
rlm@10
|
209 final static Var IN_NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("in-ns"), F);
|
rlm@10
|
210 final static Var NS_VAR = Var.intern(CLOJURE_NS, Symbol.create("ns"), F);
|
rlm@10
|
211 static final Var PRINT_INITIALIZED = Var.intern(CLOJURE_NS, Symbol.create("print-initialized"));
|
rlm@10
|
212 static final Var PR_ON = Var.intern(CLOJURE_NS, Symbol.create("pr-on"));
|
rlm@10
|
213 //final static Var IMPORTS = Var.intern(CLOJURE_NS, Symbol.create("*imports*"), DEFAULT_IMPORTS);
|
rlm@10
|
214 final static IFn inNamespace = new AFn(){
|
rlm@10
|
215 public Object invoke(Object arg1) throws Exception{
|
rlm@10
|
216 Symbol nsname = (Symbol) arg1;
|
rlm@10
|
217 Namespace ns = Namespace.findOrCreate(nsname);
|
rlm@10
|
218 CURRENT_NS.set(ns);
|
rlm@10
|
219 return ns;
|
rlm@10
|
220 }
|
rlm@10
|
221 };
|
rlm@10
|
222
|
rlm@10
|
223 final static IFn bootNamespace = new AFn(){
|
rlm@10
|
224 public Object invoke(Object __form, Object __env,Object arg1) throws Exception{
|
rlm@10
|
225 Symbol nsname = (Symbol) arg1;
|
rlm@10
|
226 Namespace ns = Namespace.findOrCreate(nsname);
|
rlm@10
|
227 CURRENT_NS.set(ns);
|
rlm@10
|
228 return ns;
|
rlm@10
|
229 }
|
rlm@10
|
230 };
|
rlm@10
|
231
|
rlm@10
|
232 public static List<String> processCommandLine(String[] args){
|
rlm@10
|
233 List<String> arglist = Arrays.asList(args);
|
rlm@10
|
234 int split = arglist.indexOf("--");
|
rlm@10
|
235 if(split >= 0) {
|
rlm@10
|
236 CMD_LINE_ARGS.bindRoot(RT.seq(arglist.subList(split + 1, args.length)));
|
rlm@10
|
237 return arglist.subList(0, split);
|
rlm@10
|
238 }
|
rlm@10
|
239 return arglist;
|
rlm@10
|
240 }
|
rlm@10
|
241
|
rlm@10
|
242 // duck typing stderr plays nice with e.g. swank
|
rlm@10
|
243 public static PrintWriter errPrintWriter(){
|
rlm@10
|
244 Writer w = (Writer) ERR.deref();
|
rlm@10
|
245 if (w instanceof PrintWriter) {
|
rlm@10
|
246 return (PrintWriter) w;
|
rlm@10
|
247 } else {
|
rlm@10
|
248 return new PrintWriter(w);
|
rlm@10
|
249 }
|
rlm@10
|
250 }
|
rlm@10
|
251
|
rlm@10
|
252 static public final Object[] EMPTY_ARRAY = new Object[]{};
|
rlm@10
|
253 static public final Comparator DEFAULT_COMPARATOR = new DefaultComparator();
|
rlm@10
|
254
|
rlm@10
|
255 private static final class DefaultComparator implements Comparator, Serializable {
|
rlm@10
|
256 public int compare(Object o1, Object o2){
|
rlm@10
|
257 return Util.compare(o1, o2);
|
rlm@10
|
258 }
|
rlm@10
|
259
|
rlm@10
|
260 private Object readResolve() throws ObjectStreamException {
|
rlm@10
|
261 // ensures that we aren't hanging onto a new default comparator for every
|
rlm@10
|
262 // sorted set, etc., we deserialize
|
rlm@10
|
263 return DEFAULT_COMPARATOR;
|
rlm@10
|
264 }
|
rlm@10
|
265 }
|
rlm@10
|
266
|
rlm@10
|
267 static AtomicInteger id = new AtomicInteger(1);
|
rlm@10
|
268
|
rlm@10
|
269 static public void addURL(Object url) throws Exception{
|
rlm@10
|
270 URL u = (url instanceof String) ? (new URL((String) url)) : (URL) url;
|
rlm@10
|
271 ClassLoader ccl = Thread.currentThread().getContextClassLoader();
|
rlm@10
|
272 if(ccl instanceof DynamicClassLoader)
|
rlm@10
|
273 ((DynamicClassLoader)ccl).addURL(u);
|
rlm@10
|
274 else
|
rlm@10
|
275 throw new IllegalAccessError("Context classloader is not a DynamicClassLoader");
|
rlm@10
|
276 }
|
rlm@10
|
277
|
rlm@10
|
278 static{
|
rlm@10
|
279 Keyword dockw = Keyword.intern(null, "doc");
|
rlm@10
|
280 Keyword arglistskw = Keyword.intern(null, "arglists");
|
rlm@10
|
281 Symbol namesym = Symbol.create("name");
|
rlm@10
|
282 OUT.setTag(Symbol.create("java.io.Writer"));
|
rlm@10
|
283 CURRENT_NS.setTag(Symbol.create("clojure.lang.Namespace"));
|
rlm@10
|
284 AGENT.setMeta(map(dockw, "The agent currently running an action on this thread, else nil"));
|
rlm@10
|
285 AGENT.setTag(Symbol.create("clojure.lang.Agent"));
|
rlm@10
|
286 MATH_CONTEXT.setTag(Symbol.create("java.math.MathContext"));
|
rlm@10
|
287 Var nv = Var.intern(CLOJURE_NS, NAMESPACE, bootNamespace);
|
rlm@10
|
288 nv.setMacro();
|
rlm@10
|
289 Var v;
|
rlm@10
|
290 v = Var.intern(CLOJURE_NS, IN_NAMESPACE, inNamespace);
|
rlm@10
|
291 v.setMeta(map(dockw, "Sets *ns* to the namespace named by the symbol, creating it if needed.",
|
rlm@10
|
292 arglistskw, list(vector(namesym))));
|
rlm@10
|
293 v = Var.intern(CLOJURE_NS, LOAD_FILE,
|
rlm@10
|
294 new AFn(){
|
rlm@10
|
295 public Object invoke(Object arg1) throws Exception{
|
rlm@10
|
296 return Compiler.loadFile((String) arg1);
|
rlm@10
|
297 }
|
rlm@10
|
298 });
|
rlm@10
|
299 v.setMeta(map(dockw, "Sequentially read and evaluate the set of forms contained in the file.",
|
rlm@10
|
300 arglistskw, list(vector(namesym))));
|
rlm@10
|
301 try {
|
rlm@10
|
302 doInit();
|
rlm@10
|
303 }
|
rlm@10
|
304 catch(Exception e) {
|
rlm@10
|
305 throw new RuntimeException(e);
|
rlm@10
|
306 }
|
rlm@10
|
307 }
|
rlm@10
|
308
|
rlm@10
|
309
|
rlm@10
|
310 static public Var var(String ns, String name){
|
rlm@10
|
311 return Var.intern(Namespace.findOrCreate(Symbol.intern(null, ns)), Symbol.intern(null, name));
|
rlm@10
|
312 }
|
rlm@10
|
313
|
rlm@10
|
314 static public Var var(String ns, String name, Object init){
|
rlm@10
|
315 return Var.intern(Namespace.findOrCreate(Symbol.intern(null, ns)), Symbol.intern(null, name), init);
|
rlm@10
|
316 }
|
rlm@10
|
317
|
rlm@10
|
318 public static void loadResourceScript(String name) throws Exception{
|
rlm@10
|
319 loadResourceScript(name, true);
|
rlm@10
|
320 }
|
rlm@10
|
321
|
rlm@10
|
322 public static void maybeLoadResourceScript(String name) throws Exception{
|
rlm@10
|
323 loadResourceScript(name, false);
|
rlm@10
|
324 }
|
rlm@10
|
325
|
rlm@10
|
326 public static void loadResourceScript(String name, boolean failIfNotFound) throws Exception{
|
rlm@10
|
327 loadResourceScript(RT.class, name, failIfNotFound);
|
rlm@10
|
328 }
|
rlm@10
|
329
|
rlm@10
|
330 public static void loadResourceScript(Class c, String name) throws Exception{
|
rlm@10
|
331 loadResourceScript(c, name, true);
|
rlm@10
|
332 }
|
rlm@10
|
333
|
rlm@10
|
334 public static void loadResourceScript(Class c, String name, boolean failIfNotFound) throws Exception{
|
rlm@10
|
335 int slash = name.lastIndexOf('/');
|
rlm@10
|
336 String file = slash >= 0 ? name.substring(slash + 1) : name;
|
rlm@10
|
337 InputStream ins = baseLoader().getResourceAsStream(name);
|
rlm@10
|
338 if(ins != null) {
|
rlm@10
|
339 try {
|
rlm@10
|
340 Compiler.load(new InputStreamReader(ins, UTF8), name, file);
|
rlm@10
|
341 }
|
rlm@10
|
342 finally {
|
rlm@10
|
343 ins.close();
|
rlm@10
|
344 }
|
rlm@10
|
345 }
|
rlm@10
|
346 else if(failIfNotFound) {
|
rlm@10
|
347 throw new FileNotFoundException("Could not locate Clojure resource on classpath: " + name);
|
rlm@10
|
348 }
|
rlm@10
|
349 }
|
rlm@10
|
350
|
rlm@10
|
351 static public void init() throws Exception{
|
rlm@10
|
352 RT.errPrintWriter().println("No need to call RT.init() anymore");
|
rlm@10
|
353 }
|
rlm@10
|
354
|
rlm@10
|
355 static public long lastModified(URL url, String libfile) throws Exception{
|
rlm@10
|
356 if(url.getProtocol().equals("jar")) {
|
rlm@10
|
357 return ((JarURLConnection) url.openConnection()).getJarFile().getEntry(libfile).getTime();
|
rlm@10
|
358 }
|
rlm@10
|
359 else {
|
rlm@10
|
360 return url.openConnection().getLastModified();
|
rlm@10
|
361 }
|
rlm@10
|
362 }
|
rlm@10
|
363
|
rlm@10
|
364 static void compile(String cljfile) throws Exception{
|
rlm@10
|
365 InputStream ins = baseLoader().getResourceAsStream(cljfile);
|
rlm@10
|
366 if(ins != null) {
|
rlm@10
|
367 try {
|
rlm@10
|
368 Compiler.compile(new InputStreamReader(ins, UTF8), cljfile,
|
rlm@10
|
369 cljfile.substring(1 + cljfile.lastIndexOf("/")));
|
rlm@10
|
370 }
|
rlm@10
|
371 finally {
|
rlm@10
|
372 ins.close();
|
rlm@10
|
373 }
|
rlm@10
|
374
|
rlm@10
|
375 }
|
rlm@10
|
376 else
|
rlm@10
|
377 throw new FileNotFoundException("Could not locate Clojure resource on classpath: " + cljfile);
|
rlm@10
|
378 }
|
rlm@10
|
379
|
rlm@10
|
380 static public void load(String scriptbase) throws Exception{
|
rlm@10
|
381 load(scriptbase, true);
|
rlm@10
|
382 }
|
rlm@10
|
383
|
rlm@10
|
384 static public void load(String scriptbase, boolean failIfNotFound) throws Exception{
|
rlm@10
|
385 String classfile = scriptbase + LOADER_SUFFIX + ".class";
|
rlm@10
|
386 String cljfile = scriptbase + ".clj";
|
rlm@10
|
387 URL classURL = baseLoader().getResource(classfile);
|
rlm@10
|
388 URL cljURL = baseLoader().getResource(cljfile);
|
rlm@10
|
389 boolean loaded = false;
|
rlm@10
|
390
|
rlm@10
|
391 if((classURL != null &&
|
rlm@10
|
392 (cljURL == null
|
rlm@10
|
393 || lastModified(classURL, classfile) > lastModified(cljURL, cljfile)))
|
rlm@10
|
394 || classURL == null) {
|
rlm@10
|
395 try {
|
rlm@10
|
396 Var.pushThreadBindings(
|
rlm@10
|
397 RT.map(CURRENT_NS, CURRENT_NS.deref(),
|
rlm@10
|
398 WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref()));
|
rlm@10
|
399 loaded = (loadClassForName(scriptbase.replace('/', '.') + LOADER_SUFFIX) != null);
|
rlm@10
|
400 }
|
rlm@10
|
401 finally {
|
rlm@10
|
402 Var.popThreadBindings();
|
rlm@10
|
403 }
|
rlm@10
|
404 }
|
rlm@10
|
405 if(!loaded && cljURL != null) {
|
rlm@10
|
406 if(booleanCast(Compiler.COMPILE_FILES.deref()))
|
rlm@10
|
407 compile(cljfile);
|
rlm@10
|
408 else
|
rlm@10
|
409 loadResourceScript(RT.class, cljfile);
|
rlm@10
|
410 }
|
rlm@10
|
411 else if(!loaded && failIfNotFound)
|
rlm@10
|
412 throw new FileNotFoundException(String.format("Could not locate %s or %s on classpath: ", classfile, cljfile));
|
rlm@10
|
413 }
|
rlm@10
|
414
|
rlm@10
|
415 static void doInit() throws Exception{
|
rlm@10
|
416 load("clojure/core");
|
rlm@10
|
417 load("clojure/zip", false);
|
rlm@10
|
418 load("clojure/xml", false);
|
rlm@10
|
419 load("clojure/set", false);
|
rlm@10
|
420
|
rlm@10
|
421 Var.pushThreadBindings(
|
rlm@10
|
422 RT.map(CURRENT_NS, CURRENT_NS.deref(),
|
rlm@10
|
423 WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref()));
|
rlm@10
|
424 try {
|
rlm@10
|
425 Symbol USER = Symbol.create("user");
|
rlm@10
|
426 Symbol CLOJURE = Symbol.create("clojure.core");
|
rlm@10
|
427
|
rlm@10
|
428 Var in_ns = var("clojure.core", "in-ns");
|
rlm@10
|
429 Var refer = var("clojure.core", "refer");
|
rlm@10
|
430 in_ns.invoke(USER);
|
rlm@10
|
431 refer.invoke(CLOJURE);
|
rlm@10
|
432 maybeLoadResourceScript("user.clj");
|
rlm@10
|
433 }
|
rlm@10
|
434 finally {
|
rlm@10
|
435 Var.popThreadBindings();
|
rlm@10
|
436 }
|
rlm@10
|
437 }
|
rlm@10
|
438
|
rlm@10
|
439 static public int nextID(){
|
rlm@10
|
440 return id.getAndIncrement();
|
rlm@10
|
441 }
|
rlm@10
|
442
|
rlm@10
|
443
|
rlm@10
|
444 ////////////// Collections support /////////////////////////////////
|
rlm@10
|
445
|
rlm@10
|
446 static public ISeq seq(Object coll){
|
rlm@10
|
447 if(coll instanceof ASeq)
|
rlm@10
|
448 return (ASeq) coll;
|
rlm@10
|
449 else if(coll instanceof LazySeq)
|
rlm@10
|
450 return ((LazySeq) coll).seq();
|
rlm@10
|
451 else
|
rlm@10
|
452 return seqFrom(coll);
|
rlm@10
|
453 }
|
rlm@10
|
454
|
rlm@10
|
455 static ISeq seqFrom(Object coll){
|
rlm@10
|
456 if(coll instanceof Seqable)
|
rlm@10
|
457 return ((Seqable) coll).seq();
|
rlm@10
|
458 else if(coll == null)
|
rlm@10
|
459 return null;
|
rlm@10
|
460 else if(coll instanceof Iterable)
|
rlm@10
|
461 return IteratorSeq.create(((Iterable) coll).iterator());
|
rlm@10
|
462 else if(coll.getClass().isArray())
|
rlm@10
|
463 return ArraySeq.createFromObject(coll);
|
rlm@10
|
464 else if(coll instanceof CharSequence)
|
rlm@10
|
465 return StringSeq.create((CharSequence) coll);
|
rlm@10
|
466 else if(coll instanceof Map)
|
rlm@10
|
467 return seq(((Map) coll).entrySet());
|
rlm@10
|
468 else {
|
rlm@10
|
469 Class c = coll.getClass();
|
rlm@10
|
470 Class sc = c.getSuperclass();
|
rlm@10
|
471 throw new IllegalArgumentException("Don't know how to create ISeq from: " + c.getName());
|
rlm@10
|
472 }
|
rlm@10
|
473 }
|
rlm@10
|
474
|
rlm@10
|
475 static public ISeq keys(Object coll){
|
rlm@10
|
476 return APersistentMap.KeySeq.create(seq(coll));
|
rlm@10
|
477 }
|
rlm@10
|
478
|
rlm@10
|
479 static public ISeq vals(Object coll){
|
rlm@10
|
480 return APersistentMap.ValSeq.create(seq(coll));
|
rlm@10
|
481 }
|
rlm@10
|
482
|
rlm@10
|
483 static public IPersistentMap meta(Object x){
|
rlm@10
|
484 if(x instanceof IMeta)
|
rlm@10
|
485 return ((IMeta) x).meta();
|
rlm@10
|
486 return null;
|
rlm@10
|
487 }
|
rlm@10
|
488
|
rlm@10
|
489 public static int count(Object o){
|
rlm@10
|
490 if(o instanceof Counted)
|
rlm@10
|
491 return ((Counted) o).count();
|
rlm@10
|
492 return countFrom(Util.ret1(o, o = null));
|
rlm@10
|
493 }
|
rlm@10
|
494
|
rlm@10
|
495 static int countFrom(Object o){
|
rlm@10
|
496 if(o == null)
|
rlm@10
|
497 return 0;
|
rlm@10
|
498 else if(o instanceof IPersistentCollection) {
|
rlm@10
|
499 ISeq s = seq(o);
|
rlm@10
|
500 o = null;
|
rlm@10
|
501 int i = 0;
|
rlm@10
|
502 for(; s != null; s = s.next()) {
|
rlm@10
|
503 if(s instanceof Counted)
|
rlm@10
|
504 return i + s.count();
|
rlm@10
|
505 i++;
|
rlm@10
|
506 }
|
rlm@10
|
507 return i;
|
rlm@10
|
508 }
|
rlm@10
|
509 else if(o instanceof CharSequence)
|
rlm@10
|
510 return ((CharSequence) o).length();
|
rlm@10
|
511 else if(o instanceof Collection)
|
rlm@10
|
512 return ((Collection) o).size();
|
rlm@10
|
513 else if(o instanceof Map)
|
rlm@10
|
514 return ((Map) o).size();
|
rlm@10
|
515 else if(o.getClass().isArray())
|
rlm@10
|
516 return Array.getLength(o);
|
rlm@10
|
517
|
rlm@10
|
518 throw new UnsupportedOperationException("count not supported on this type: " + o.getClass().getSimpleName());
|
rlm@10
|
519 }
|
rlm@10
|
520
|
rlm@10
|
521 static public IPersistentCollection conj(IPersistentCollection coll, Object x){
|
rlm@10
|
522 if(coll == null)
|
rlm@10
|
523 return new PersistentList(x);
|
rlm@10
|
524 return coll.cons(x);
|
rlm@10
|
525 }
|
rlm@10
|
526
|
rlm@10
|
527 static public ISeq cons(Object x, Object coll){
|
rlm@10
|
528 //ISeq y = seq(coll);
|
rlm@10
|
529 if(coll == null)
|
rlm@10
|
530 return new PersistentList(x);
|
rlm@10
|
531 else if(coll instanceof ISeq)
|
rlm@10
|
532 return new Cons(x, (ISeq) coll);
|
rlm@10
|
533 else
|
rlm@10
|
534 return new Cons(x, seq(coll));
|
rlm@10
|
535 }
|
rlm@10
|
536
|
rlm@10
|
537 static public Object first(Object x){
|
rlm@10
|
538 if(x instanceof ISeq)
|
rlm@10
|
539 return ((ISeq) x).first();
|
rlm@10
|
540 ISeq seq = seq(x);
|
rlm@10
|
541 if(seq == null)
|
rlm@10
|
542 return null;
|
rlm@10
|
543 return seq.first();
|
rlm@10
|
544 }
|
rlm@10
|
545
|
rlm@10
|
546 static public Object second(Object x){
|
rlm@10
|
547 return first(next(x));
|
rlm@10
|
548 }
|
rlm@10
|
549
|
rlm@10
|
550 static public Object third(Object x){
|
rlm@10
|
551 return first(next(next(x)));
|
rlm@10
|
552 }
|
rlm@10
|
553
|
rlm@10
|
554 static public Object fourth(Object x){
|
rlm@10
|
555 return first(next(next(next(x))));
|
rlm@10
|
556 }
|
rlm@10
|
557
|
rlm@10
|
558 static public ISeq next(Object x){
|
rlm@10
|
559 if(x instanceof ISeq)
|
rlm@10
|
560 return ((ISeq) x).next();
|
rlm@10
|
561 ISeq seq = seq(x);
|
rlm@10
|
562 if(seq == null)
|
rlm@10
|
563 return null;
|
rlm@10
|
564 return seq.next();
|
rlm@10
|
565 }
|
rlm@10
|
566
|
rlm@10
|
567 static public ISeq more(Object x){
|
rlm@10
|
568 if(x instanceof ISeq)
|
rlm@10
|
569 return ((ISeq) x).more();
|
rlm@10
|
570 ISeq seq = seq(x);
|
rlm@10
|
571 if(seq == null)
|
rlm@10
|
572 return PersistentList.EMPTY;
|
rlm@10
|
573 return seq.more();
|
rlm@10
|
574 }
|
rlm@10
|
575
|
rlm@10
|
576 //static public Seqable more(Object x){
|
rlm@10
|
577 // Seqable ret = null;
|
rlm@10
|
578 // if(x instanceof ISeq)
|
rlm@10
|
579 // ret = ((ISeq) x).more();
|
rlm@10
|
580 // else
|
rlm@10
|
581 // {
|
rlm@10
|
582 // ISeq seq = seq(x);
|
rlm@10
|
583 // if(seq == null)
|
rlm@10
|
584 // ret = PersistentList.EMPTY;
|
rlm@10
|
585 // else
|
rlm@10
|
586 // ret = seq.more();
|
rlm@10
|
587 // }
|
rlm@10
|
588 // if(ret == null)
|
rlm@10
|
589 // ret = PersistentList.EMPTY;
|
rlm@10
|
590 // return ret;
|
rlm@10
|
591 //}
|
rlm@10
|
592
|
rlm@10
|
593 static public Object peek(Object x){
|
rlm@10
|
594 if(x == null)
|
rlm@10
|
595 return null;
|
rlm@10
|
596 return ((IPersistentStack) x).peek();
|
rlm@10
|
597 }
|
rlm@10
|
598
|
rlm@10
|
599 static public Object pop(Object x){
|
rlm@10
|
600 if(x == null)
|
rlm@10
|
601 return null;
|
rlm@10
|
602 return ((IPersistentStack) x).pop();
|
rlm@10
|
603 }
|
rlm@10
|
604
|
rlm@10
|
605 static public Object get(Object coll, Object key){
|
rlm@10
|
606 if(coll instanceof ILookup)
|
rlm@10
|
607 return ((ILookup) coll).valAt(key);
|
rlm@10
|
608 return getFrom(coll, key);
|
rlm@10
|
609 }
|
rlm@10
|
610
|
rlm@10
|
611 static Object getFrom(Object coll, Object key){
|
rlm@10
|
612 if(coll == null)
|
rlm@10
|
613 return null;
|
rlm@10
|
614 else if(coll instanceof Map) {
|
rlm@10
|
615 Map m = (Map) coll;
|
rlm@10
|
616 return m.get(key);
|
rlm@10
|
617 }
|
rlm@10
|
618 else if(coll instanceof IPersistentSet) {
|
rlm@10
|
619 IPersistentSet set = (IPersistentSet) coll;
|
rlm@10
|
620 return set.get(key);
|
rlm@10
|
621 }
|
rlm@10
|
622 else if(key instanceof Number && (coll instanceof String || coll.getClass().isArray())) {
|
rlm@10
|
623 int n = ((Number) key).intValue();
|
rlm@10
|
624 if(n >= 0 && n < count(coll))
|
rlm@10
|
625 return nth(coll, n);
|
rlm@10
|
626 return null;
|
rlm@10
|
627 }
|
rlm@10
|
628
|
rlm@10
|
629 return null;
|
rlm@10
|
630 }
|
rlm@10
|
631
|
rlm@10
|
632 static public Object get(Object coll, Object key, Object notFound){
|
rlm@10
|
633 if(coll instanceof ILookup)
|
rlm@10
|
634 return ((ILookup) coll).valAt(key, notFound);
|
rlm@10
|
635 return getFrom(coll, key, notFound);
|
rlm@10
|
636 }
|
rlm@10
|
637
|
rlm@10
|
638 static Object getFrom(Object coll, Object key, Object notFound){
|
rlm@10
|
639 if(coll == null)
|
rlm@10
|
640 return notFound;
|
rlm@10
|
641 else if(coll instanceof Map) {
|
rlm@10
|
642 Map m = (Map) coll;
|
rlm@10
|
643 if(m.containsKey(key))
|
rlm@10
|
644 return m.get(key);
|
rlm@10
|
645 return notFound;
|
rlm@10
|
646 }
|
rlm@10
|
647 else if(coll instanceof IPersistentSet) {
|
rlm@10
|
648 IPersistentSet set = (IPersistentSet) coll;
|
rlm@10
|
649 if(set.contains(key))
|
rlm@10
|
650 return set.get(key);
|
rlm@10
|
651 return notFound;
|
rlm@10
|
652 }
|
rlm@10
|
653 else if(key instanceof Number && (coll instanceof String || coll.getClass().isArray())) {
|
rlm@10
|
654 int n = ((Number) key).intValue();
|
rlm@10
|
655 return n >= 0 && n < count(coll) ? nth(coll, n) : notFound;
|
rlm@10
|
656 }
|
rlm@10
|
657 return notFound;
|
rlm@10
|
658
|
rlm@10
|
659 }
|
rlm@10
|
660
|
rlm@10
|
661 static public Associative assoc(Object coll, Object key, Object val){
|
rlm@10
|
662 if(coll == null)
|
rlm@10
|
663 return new PersistentArrayMap(new Object[]{key, val});
|
rlm@10
|
664 return ((Associative) coll).assoc(key, val);
|
rlm@10
|
665 }
|
rlm@10
|
666
|
rlm@10
|
667 static public Object contains(Object coll, Object key){
|
rlm@10
|
668 if(coll == null)
|
rlm@10
|
669 return F;
|
rlm@10
|
670 else if(coll instanceof Associative)
|
rlm@10
|
671 return ((Associative) coll).containsKey(key) ? T : F;
|
rlm@10
|
672 else if(coll instanceof IPersistentSet)
|
rlm@10
|
673 return ((IPersistentSet) coll).contains(key) ? T : F;
|
rlm@10
|
674 else if(coll instanceof Map) {
|
rlm@10
|
675 Map m = (Map) coll;
|
rlm@10
|
676 return m.containsKey(key) ? T : F;
|
rlm@10
|
677 }
|
rlm@10
|
678 else if(key instanceof Number && (coll instanceof String || coll.getClass().isArray())) {
|
rlm@10
|
679 int n = ((Number) key).intValue();
|
rlm@10
|
680 return n >= 0 && n < count(coll);
|
rlm@10
|
681 }
|
rlm@10
|
682 return F;
|
rlm@10
|
683 }
|
rlm@10
|
684
|
rlm@10
|
685 static public Object find(Object coll, Object key){
|
rlm@10
|
686 if(coll == null)
|
rlm@10
|
687 return null;
|
rlm@10
|
688 else if(coll instanceof Associative)
|
rlm@10
|
689 return ((Associative) coll).entryAt(key);
|
rlm@10
|
690 else {
|
rlm@10
|
691 Map m = (Map) coll;
|
rlm@10
|
692 if(m.containsKey(key))
|
rlm@10
|
693 return new MapEntry(key, m.get(key));
|
rlm@10
|
694 return null;
|
rlm@10
|
695 }
|
rlm@10
|
696 }
|
rlm@10
|
697
|
rlm@10
|
698 //takes a seq of key,val,key,val
|
rlm@10
|
699
|
rlm@10
|
700 //returns tail starting at val of matching key if found, else null
|
rlm@10
|
701 static public ISeq findKey(Keyword key, ISeq keyvals) throws Exception{
|
rlm@10
|
702 while(keyvals != null) {
|
rlm@10
|
703 ISeq r = keyvals.next();
|
rlm@10
|
704 if(r == null)
|
rlm@10
|
705 throw new Exception("Malformed keyword argslist");
|
rlm@10
|
706 if(keyvals.first() == key)
|
rlm@10
|
707 return r;
|
rlm@10
|
708 keyvals = r.next();
|
rlm@10
|
709 }
|
rlm@10
|
710 return null;
|
rlm@10
|
711 }
|
rlm@10
|
712
|
rlm@10
|
713 static public Object dissoc(Object coll, Object key) throws Exception{
|
rlm@10
|
714 if(coll == null)
|
rlm@10
|
715 return null;
|
rlm@10
|
716 return ((IPersistentMap) coll).without(key);
|
rlm@10
|
717 }
|
rlm@10
|
718
|
rlm@10
|
719 static public Object nth(Object coll, int n){
|
rlm@10
|
720 if(coll instanceof Indexed)
|
rlm@10
|
721 return ((Indexed) coll).nth(n);
|
rlm@10
|
722 return nthFrom(Util.ret1(coll, coll = null), n);
|
rlm@10
|
723 }
|
rlm@10
|
724
|
rlm@10
|
725 static Object nthFrom(Object coll, int n){
|
rlm@10
|
726 if(coll == null)
|
rlm@10
|
727 return null;
|
rlm@10
|
728 else if(coll instanceof CharSequence)
|
rlm@10
|
729 return Character.valueOf(((CharSequence) coll).charAt(n));
|
rlm@10
|
730 else if(coll.getClass().isArray())
|
rlm@10
|
731 return Reflector.prepRet(Array.get(coll, n));
|
rlm@10
|
732 else if(coll instanceof RandomAccess)
|
rlm@10
|
733 return ((List) coll).get(n);
|
rlm@10
|
734 else if(coll instanceof Matcher)
|
rlm@10
|
735 return ((Matcher) coll).group(n);
|
rlm@10
|
736
|
rlm@10
|
737 else if(coll instanceof Map.Entry) {
|
rlm@10
|
738 Map.Entry e = (Map.Entry) coll;
|
rlm@10
|
739 if(n == 0)
|
rlm@10
|
740 return e.getKey();
|
rlm@10
|
741 else if(n == 1)
|
rlm@10
|
742 return e.getValue();
|
rlm@10
|
743 throw new IndexOutOfBoundsException();
|
rlm@10
|
744 }
|
rlm@10
|
745
|
rlm@10
|
746 else if(coll instanceof Sequential) {
|
rlm@10
|
747 ISeq seq = RT.seq(coll);
|
rlm@10
|
748 coll = null;
|
rlm@10
|
749 for(int i = 0; i <= n && seq != null; ++i, seq = seq.next()) {
|
rlm@10
|
750 if(i == n)
|
rlm@10
|
751 return seq.first();
|
rlm@10
|
752 }
|
rlm@10
|
753 throw new IndexOutOfBoundsException();
|
rlm@10
|
754 }
|
rlm@10
|
755 else
|
rlm@10
|
756 throw new UnsupportedOperationException(
|
rlm@10
|
757 "nth not supported on this type: " + coll.getClass().getSimpleName());
|
rlm@10
|
758 }
|
rlm@10
|
759
|
rlm@10
|
760 static public Object nth(Object coll, int n, Object notFound){
|
rlm@10
|
761 if(coll instanceof Indexed) {
|
rlm@10
|
762 Indexed v = (Indexed) coll;
|
rlm@10
|
763 return v.nth(n, notFound);
|
rlm@10
|
764 }
|
rlm@10
|
765 return nthFrom(coll, n, notFound);
|
rlm@10
|
766 }
|
rlm@10
|
767
|
rlm@10
|
768 static Object nthFrom(Object coll, int n, Object notFound){
|
rlm@10
|
769 if(coll == null)
|
rlm@10
|
770 return notFound;
|
rlm@10
|
771 else if(n < 0)
|
rlm@10
|
772 return notFound;
|
rlm@10
|
773
|
rlm@10
|
774 else if(coll instanceof CharSequence) {
|
rlm@10
|
775 CharSequence s = (CharSequence) coll;
|
rlm@10
|
776 if(n < s.length())
|
rlm@10
|
777 return Character.valueOf(s.charAt(n));
|
rlm@10
|
778 return notFound;
|
rlm@10
|
779 }
|
rlm@10
|
780 else if(coll.getClass().isArray()) {
|
rlm@10
|
781 if(n < Array.getLength(coll))
|
rlm@10
|
782 return Reflector.prepRet(Array.get(coll, n));
|
rlm@10
|
783 return notFound;
|
rlm@10
|
784 }
|
rlm@10
|
785 else if(coll instanceof RandomAccess) {
|
rlm@10
|
786 List list = (List) coll;
|
rlm@10
|
787 if(n < list.size())
|
rlm@10
|
788 return list.get(n);
|
rlm@10
|
789 return notFound;
|
rlm@10
|
790 }
|
rlm@10
|
791 else if(coll instanceof Matcher) {
|
rlm@10
|
792 Matcher m = (Matcher) coll;
|
rlm@10
|
793 if(n < m.groupCount())
|
rlm@10
|
794 return m.group(n);
|
rlm@10
|
795 return notFound;
|
rlm@10
|
796 }
|
rlm@10
|
797 else if(coll instanceof Map.Entry) {
|
rlm@10
|
798 Map.Entry e = (Map.Entry) coll;
|
rlm@10
|
799 if(n == 0)
|
rlm@10
|
800 return e.getKey();
|
rlm@10
|
801 else if(n == 1)
|
rlm@10
|
802 return e.getValue();
|
rlm@10
|
803 return notFound;
|
rlm@10
|
804 }
|
rlm@10
|
805 else if(coll instanceof Sequential) {
|
rlm@10
|
806 ISeq seq = RT.seq(coll);
|
rlm@10
|
807 coll = null;
|
rlm@10
|
808 for(int i = 0; i <= n && seq != null; ++i, seq = seq.next()) {
|
rlm@10
|
809 if(i == n)
|
rlm@10
|
810 return seq.first();
|
rlm@10
|
811 }
|
rlm@10
|
812 return notFound;
|
rlm@10
|
813 }
|
rlm@10
|
814 else
|
rlm@10
|
815 throw new UnsupportedOperationException(
|
rlm@10
|
816 "nth not supported on this type: " + coll.getClass().getSimpleName());
|
rlm@10
|
817 }
|
rlm@10
|
818
|
rlm@10
|
819 static public Object assocN(int n, Object val, Object coll){
|
rlm@10
|
820 if(coll == null)
|
rlm@10
|
821 return null;
|
rlm@10
|
822 else if(coll instanceof IPersistentVector)
|
rlm@10
|
823 return ((IPersistentVector) coll).assocN(n, val);
|
rlm@10
|
824 else if(coll instanceof Object[]) {
|
rlm@10
|
825 //hmm... this is not persistent
|
rlm@10
|
826 Object[] array = ((Object[]) coll);
|
rlm@10
|
827 array[n] = val;
|
rlm@10
|
828 return array;
|
rlm@10
|
829 }
|
rlm@10
|
830 else
|
rlm@10
|
831 return null;
|
rlm@10
|
832 }
|
rlm@10
|
833
|
rlm@10
|
834 static boolean hasTag(Object o, Object tag){
|
rlm@10
|
835 return Util.equals(tag, RT.get(RT.meta(o), TAG_KEY));
|
rlm@10
|
836 }
|
rlm@10
|
837
|
rlm@10
|
838 /**
|
rlm@10
|
839 * ********************* Boxing/casts ******************************
|
rlm@10
|
840 */
|
rlm@10
|
841 static public Object box(Object x){
|
rlm@10
|
842 return x;
|
rlm@10
|
843 }
|
rlm@10
|
844
|
rlm@10
|
845 static public Character box(char x){
|
rlm@10
|
846 return Character.valueOf(x);
|
rlm@10
|
847 }
|
rlm@10
|
848
|
rlm@10
|
849 static public Object box(boolean x){
|
rlm@10
|
850 return x ? T : F;
|
rlm@10
|
851 }
|
rlm@10
|
852
|
rlm@10
|
853 static public Object box(Boolean x){
|
rlm@10
|
854 return x;// ? T : null;
|
rlm@10
|
855 }
|
rlm@10
|
856
|
rlm@10
|
857 static public Number box(byte x){
|
rlm@10
|
858 return x;//Num.from(x);
|
rlm@10
|
859 }
|
rlm@10
|
860
|
rlm@10
|
861 static public Number box(short x){
|
rlm@10
|
862 return x;//Num.from(x);
|
rlm@10
|
863 }
|
rlm@10
|
864
|
rlm@10
|
865 static public Number box(int x){
|
rlm@10
|
866 return x;//Num.from(x);
|
rlm@10
|
867 }
|
rlm@10
|
868
|
rlm@10
|
869 static public Number box(long x){
|
rlm@10
|
870 return x;//Num.from(x);
|
rlm@10
|
871 }
|
rlm@10
|
872
|
rlm@10
|
873 static public Number box(float x){
|
rlm@10
|
874 return x;//Num.from(x);
|
rlm@10
|
875 }
|
rlm@10
|
876
|
rlm@10
|
877 static public Number box(double x){
|
rlm@10
|
878 return x;//Num.from(x);
|
rlm@10
|
879 }
|
rlm@10
|
880
|
rlm@10
|
881 static public char charCast(Object x){
|
rlm@10
|
882 if(x instanceof Character)
|
rlm@10
|
883 return ((Character) x).charValue();
|
rlm@10
|
884
|
rlm@10
|
885 long n = ((Number) x).longValue();
|
rlm@10
|
886 if(n < Character.MIN_VALUE || n > Character.MAX_VALUE)
|
rlm@10
|
887 throw new IllegalArgumentException("Value out of range for char: " + x);
|
rlm@10
|
888
|
rlm@10
|
889 return (char) n;
|
rlm@10
|
890 }
|
rlm@10
|
891
|
rlm@10
|
892 static public boolean booleanCast(Object x){
|
rlm@10
|
893 if(x instanceof Boolean)
|
rlm@10
|
894 return ((Boolean) x).booleanValue();
|
rlm@10
|
895 return x != null;
|
rlm@10
|
896 }
|
rlm@10
|
897
|
rlm@10
|
898 static public boolean booleanCast(boolean x){
|
rlm@10
|
899 return x;
|
rlm@10
|
900 }
|
rlm@10
|
901
|
rlm@10
|
902 static public byte byteCast(Object x){
|
rlm@10
|
903 long n = ((Number) x).longValue();
|
rlm@10
|
904 if(n < Byte.MIN_VALUE || n > Byte.MAX_VALUE)
|
rlm@10
|
905 throw new IllegalArgumentException("Value out of range for byte: " + x);
|
rlm@10
|
906
|
rlm@10
|
907 return (byte) n;
|
rlm@10
|
908 }
|
rlm@10
|
909
|
rlm@10
|
910 static public short shortCast(Object x){
|
rlm@10
|
911 long n = ((Number) x).longValue();
|
rlm@10
|
912 if(n < Short.MIN_VALUE || n > Short.MAX_VALUE)
|
rlm@10
|
913 throw new IllegalArgumentException("Value out of range for short: " + x);
|
rlm@10
|
914
|
rlm@10
|
915 return (short) n;
|
rlm@10
|
916 }
|
rlm@10
|
917
|
rlm@10
|
918 static public int intCast(Object x){
|
rlm@10
|
919 if(x instanceof Integer)
|
rlm@10
|
920 return ((Integer)x).intValue();
|
rlm@10
|
921 if(x instanceof Number)
|
rlm@10
|
922 return intCast(((Number) x).longValue());
|
rlm@10
|
923 return ((Character) x).charValue();
|
rlm@10
|
924 }
|
rlm@10
|
925
|
rlm@10
|
926 static public int intCast(char x){
|
rlm@10
|
927 return x;
|
rlm@10
|
928 }
|
rlm@10
|
929
|
rlm@10
|
930 static public int intCast(byte x){
|
rlm@10
|
931 return x;
|
rlm@10
|
932 }
|
rlm@10
|
933
|
rlm@10
|
934 static public int intCast(short x){
|
rlm@10
|
935 return x;
|
rlm@10
|
936 }
|
rlm@10
|
937
|
rlm@10
|
938 static public int intCast(int x){
|
rlm@10
|
939 return x;
|
rlm@10
|
940 }
|
rlm@10
|
941
|
rlm@10
|
942 static public int intCast(float x){
|
rlm@10
|
943 if(x < Integer.MIN_VALUE || x > Integer.MAX_VALUE)
|
rlm@10
|
944 throw new IllegalArgumentException("Value out of range for int: " + x);
|
rlm@10
|
945 return (int) x;
|
rlm@10
|
946 }
|
rlm@10
|
947
|
rlm@10
|
948 static public int intCast(long x){
|
rlm@10
|
949 if(x < Integer.MIN_VALUE || x > Integer.MAX_VALUE)
|
rlm@10
|
950 throw new IllegalArgumentException("Value out of range for int: " + x);
|
rlm@10
|
951 return (int) x;
|
rlm@10
|
952 }
|
rlm@10
|
953
|
rlm@10
|
954 static public int intCast(double x){
|
rlm@10
|
955 if(x < Integer.MIN_VALUE || x > Integer.MAX_VALUE)
|
rlm@10
|
956 throw new IllegalArgumentException("Value out of range for int: " + x);
|
rlm@10
|
957 return (int) x;
|
rlm@10
|
958 }
|
rlm@10
|
959
|
rlm@10
|
960 static public long longCast(Object x){
|
rlm@10
|
961 return ((Number) x).longValue();
|
rlm@10
|
962 }
|
rlm@10
|
963
|
rlm@10
|
964 static public long longCast(int x){
|
rlm@10
|
965 return x;
|
rlm@10
|
966 }
|
rlm@10
|
967
|
rlm@10
|
968 static public long longCast(float x){
|
rlm@10
|
969 if(x < Long.MIN_VALUE || x > Long.MAX_VALUE)
|
rlm@10
|
970 throw new IllegalArgumentException("Value out of range for long: " + x);
|
rlm@10
|
971 return (long) x;
|
rlm@10
|
972 }
|
rlm@10
|
973
|
rlm@10
|
974 static public long longCast(long x){
|
rlm@10
|
975 return x;
|
rlm@10
|
976 }
|
rlm@10
|
977
|
rlm@10
|
978 static public long longCast(double x){
|
rlm@10
|
979 if(x < Long.MIN_VALUE || x > Long.MAX_VALUE)
|
rlm@10
|
980 throw new IllegalArgumentException("Value out of range for long: " + x);
|
rlm@10
|
981 return (long) x;
|
rlm@10
|
982 }
|
rlm@10
|
983
|
rlm@10
|
984 static public float floatCast(Object x){
|
rlm@10
|
985 if(x instanceof Float)
|
rlm@10
|
986 return ((Float) x).floatValue();
|
rlm@10
|
987
|
rlm@10
|
988 double n = ((Number) x).doubleValue();
|
rlm@10
|
989 if(n < -Float.MAX_VALUE || n > Float.MAX_VALUE)
|
rlm@10
|
990 throw new IllegalArgumentException("Value out of range for float: " + x);
|
rlm@10
|
991
|
rlm@10
|
992 return (float) n;
|
rlm@10
|
993
|
rlm@10
|
994 }
|
rlm@10
|
995
|
rlm@10
|
996 static public float floatCast(int x){
|
rlm@10
|
997 return x;
|
rlm@10
|
998 }
|
rlm@10
|
999
|
rlm@10
|
1000 static public float floatCast(float x){
|
rlm@10
|
1001 return x;
|
rlm@10
|
1002 }
|
rlm@10
|
1003
|
rlm@10
|
1004 static public float floatCast(long x){
|
rlm@10
|
1005 return x;
|
rlm@10
|
1006 }
|
rlm@10
|
1007
|
rlm@10
|
1008 static public float floatCast(double x){
|
rlm@10
|
1009 if(x < -Float.MAX_VALUE || x > Float.MAX_VALUE)
|
rlm@10
|
1010 throw new IllegalArgumentException("Value out of range for float: " + x);
|
rlm@10
|
1011
|
rlm@10
|
1012 return (float) x;
|
rlm@10
|
1013 }
|
rlm@10
|
1014
|
rlm@10
|
1015 static public double doubleCast(Object x){
|
rlm@10
|
1016 return ((Number) x).doubleValue();
|
rlm@10
|
1017 }
|
rlm@10
|
1018
|
rlm@10
|
1019 static public double doubleCast(int x){
|
rlm@10
|
1020 return x;
|
rlm@10
|
1021 }
|
rlm@10
|
1022
|
rlm@10
|
1023 static public double doubleCast(float x){
|
rlm@10
|
1024 return x;
|
rlm@10
|
1025 }
|
rlm@10
|
1026
|
rlm@10
|
1027 static public double doubleCast(long x){
|
rlm@10
|
1028 return x;
|
rlm@10
|
1029 }
|
rlm@10
|
1030
|
rlm@10
|
1031 static public double doubleCast(double x){
|
rlm@10
|
1032 return x;
|
rlm@10
|
1033 }
|
rlm@10
|
1034
|
rlm@10
|
1035 static public IPersistentMap map(Object... init){
|
rlm@10
|
1036 if(init == null)
|
rlm@10
|
1037 return PersistentArrayMap.EMPTY;
|
rlm@10
|
1038 else if(init.length <= PersistentArrayMap.HASHTABLE_THRESHOLD)
|
rlm@10
|
1039 return PersistentArrayMap.createWithCheck(init);
|
rlm@10
|
1040 return PersistentHashMap.createWithCheck(init);
|
rlm@10
|
1041 }
|
rlm@10
|
1042
|
rlm@10
|
1043 static public IPersistentSet set(Object... init){
|
rlm@10
|
1044 return PersistentHashSet.createWithCheck(init);
|
rlm@10
|
1045 }
|
rlm@10
|
1046
|
rlm@10
|
1047 static public IPersistentVector vector(Object... init){
|
rlm@10
|
1048 return LazilyPersistentVector.createOwning(init);
|
rlm@10
|
1049 }
|
rlm@10
|
1050
|
rlm@10
|
1051 static public IPersistentVector subvec(IPersistentVector v, int start, int end){
|
rlm@10
|
1052 if(end < start || start < 0 || end > v.count())
|
rlm@10
|
1053 throw new IndexOutOfBoundsException();
|
rlm@10
|
1054 if(start == end)
|
rlm@10
|
1055 return PersistentVector.EMPTY;
|
rlm@10
|
1056 return new APersistentVector.SubVector(null, v, start, end);
|
rlm@10
|
1057 }
|
rlm@10
|
1058
|
rlm@10
|
1059 /**
|
rlm@10
|
1060 * **************************************** list support *******************************
|
rlm@10
|
1061 */
|
rlm@10
|
1062
|
rlm@10
|
1063
|
rlm@10
|
1064 static public ISeq list(){
|
rlm@10
|
1065 return null;
|
rlm@10
|
1066 }
|
rlm@10
|
1067
|
rlm@10
|
1068 static public ISeq list(Object arg1){
|
rlm@10
|
1069 return new PersistentList(arg1);
|
rlm@10
|
1070 }
|
rlm@10
|
1071
|
rlm@10
|
1072 static public ISeq list(Object arg1, Object arg2){
|
rlm@10
|
1073 return listStar(arg1, arg2, null);
|
rlm@10
|
1074 }
|
rlm@10
|
1075
|
rlm@10
|
1076 static public ISeq list(Object arg1, Object arg2, Object arg3){
|
rlm@10
|
1077 return listStar(arg1, arg2, arg3, null);
|
rlm@10
|
1078 }
|
rlm@10
|
1079
|
rlm@10
|
1080 static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4){
|
rlm@10
|
1081 return listStar(arg1, arg2, arg3, arg4, null);
|
rlm@10
|
1082 }
|
rlm@10
|
1083
|
rlm@10
|
1084 static public ISeq list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5){
|
rlm@10
|
1085 return listStar(arg1, arg2, arg3, arg4, arg5, null);
|
rlm@10
|
1086 }
|
rlm@10
|
1087
|
rlm@10
|
1088 static public ISeq listStar(Object arg1, ISeq rest){
|
rlm@10
|
1089 return (ISeq) cons(arg1, rest);
|
rlm@10
|
1090 }
|
rlm@10
|
1091
|
rlm@10
|
1092 static public ISeq listStar(Object arg1, Object arg2, ISeq rest){
|
rlm@10
|
1093 return (ISeq) cons(arg1, cons(arg2, rest));
|
rlm@10
|
1094 }
|
rlm@10
|
1095
|
rlm@10
|
1096 static public ISeq listStar(Object arg1, Object arg2, Object arg3, ISeq rest){
|
rlm@10
|
1097 return (ISeq) cons(arg1, cons(arg2, cons(arg3, rest)));
|
rlm@10
|
1098 }
|
rlm@10
|
1099
|
rlm@10
|
1100 static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, ISeq rest){
|
rlm@10
|
1101 return (ISeq) cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest))));
|
rlm@10
|
1102 }
|
rlm@10
|
1103
|
rlm@10
|
1104 static public ISeq listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, ISeq rest){
|
rlm@10
|
1105 return (ISeq) cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest)))));
|
rlm@10
|
1106 }
|
rlm@10
|
1107
|
rlm@10
|
1108 static public ISeq arrayToList(Object[] a) throws Exception{
|
rlm@10
|
1109 ISeq ret = null;
|
rlm@10
|
1110 for(int i = a.length - 1; i >= 0; --i)
|
rlm@10
|
1111 ret = (ISeq) cons(a[i], ret);
|
rlm@10
|
1112 return ret;
|
rlm@10
|
1113 }
|
rlm@10
|
1114
|
rlm@10
|
1115 static public Object[] object_array(Object sizeOrSeq){
|
rlm@10
|
1116 if(sizeOrSeq instanceof Number)
|
rlm@10
|
1117 return new Object[((Number) sizeOrSeq).intValue()];
|
rlm@10
|
1118 else
|
rlm@10
|
1119 {
|
rlm@10
|
1120 ISeq s = RT.seq(sizeOrSeq);
|
rlm@10
|
1121 int size = RT.count(s);
|
rlm@10
|
1122 Object[] ret = new Object[size];
|
rlm@10
|
1123 for(int i = 0; i < size && s != null; i++, s = s.next())
|
rlm@10
|
1124 ret[i] = s.first();
|
rlm@10
|
1125 return ret;
|
rlm@10
|
1126 }
|
rlm@10
|
1127 }
|
rlm@10
|
1128
|
rlm@10
|
1129 static public Object[] toArray(Object coll) throws Exception{
|
rlm@10
|
1130 if(coll == null)
|
rlm@10
|
1131 return EMPTY_ARRAY;
|
rlm@10
|
1132 else if(coll instanceof Object[])
|
rlm@10
|
1133 return (Object[]) coll;
|
rlm@10
|
1134 else if(coll instanceof Collection)
|
rlm@10
|
1135 return ((Collection) coll).toArray();
|
rlm@10
|
1136 else if(coll instanceof Map)
|
rlm@10
|
1137 return ((Map) coll).entrySet().toArray();
|
rlm@10
|
1138 else if(coll instanceof String) {
|
rlm@10
|
1139 char[] chars = ((String) coll).toCharArray();
|
rlm@10
|
1140 Object[] ret = new Object[chars.length];
|
rlm@10
|
1141 for(int i = 0; i < chars.length; i++)
|
rlm@10
|
1142 ret[i] = chars[i];
|
rlm@10
|
1143 return ret;
|
rlm@10
|
1144 }
|
rlm@10
|
1145 else if(coll.getClass().isArray()) {
|
rlm@10
|
1146 ISeq s = (seq(coll));
|
rlm@10
|
1147 Object[] ret = new Object[count(s)];
|
rlm@10
|
1148 for(int i = 0; i < ret.length; i++, s = s.next())
|
rlm@10
|
1149 ret[i] = s.first();
|
rlm@10
|
1150 return ret;
|
rlm@10
|
1151 }
|
rlm@10
|
1152 else
|
rlm@10
|
1153 throw new Exception("Unable to convert: " + coll.getClass() + " to Object[]");
|
rlm@10
|
1154 }
|
rlm@10
|
1155
|
rlm@10
|
1156 static public Object[] seqToArray(ISeq seq){
|
rlm@10
|
1157 int len = length(seq);
|
rlm@10
|
1158 Object[] ret = new Object[len];
|
rlm@10
|
1159 for(int i = 0; seq != null; ++i, seq = seq.next())
|
rlm@10
|
1160 ret[i] = seq.first();
|
rlm@10
|
1161 return ret;
|
rlm@10
|
1162 }
|
rlm@10
|
1163
|
rlm@10
|
1164 static public Object seqToTypedArray(ISeq seq) throws Exception{
|
rlm@10
|
1165 Class type = (seq != null) ? seq.first().getClass() : Object.class;
|
rlm@10
|
1166 return seqToTypedArray(type, seq);
|
rlm@10
|
1167 }
|
rlm@10
|
1168
|
rlm@10
|
1169 static public Object seqToTypedArray(Class type, ISeq seq) throws Exception{
|
rlm@10
|
1170 Object ret = Array.newInstance(type, length(seq));
|
rlm@10
|
1171 for(int i = 0; seq != null; ++i, seq = seq.next())
|
rlm@10
|
1172 Array.set(ret, i, seq.first());
|
rlm@10
|
1173 return ret;
|
rlm@10
|
1174 }
|
rlm@10
|
1175
|
rlm@10
|
1176 static public int length(ISeq list){
|
rlm@10
|
1177 int i = 0;
|
rlm@10
|
1178 for(ISeq c = list; c != null; c = c.next()) {
|
rlm@10
|
1179 i++;
|
rlm@10
|
1180 }
|
rlm@10
|
1181 return i;
|
rlm@10
|
1182 }
|
rlm@10
|
1183
|
rlm@10
|
1184 static public int boundedLength(ISeq list, int limit) throws Exception{
|
rlm@10
|
1185 int i = 0;
|
rlm@10
|
1186 for(ISeq c = list; c != null && i <= limit; c = c.next()) {
|
rlm@10
|
1187 i++;
|
rlm@10
|
1188 }
|
rlm@10
|
1189 return i;
|
rlm@10
|
1190 }
|
rlm@10
|
1191
|
rlm@10
|
1192 ///////////////////////////////// reader support ////////////////////////////////
|
rlm@10
|
1193
|
rlm@10
|
1194 static Character readRet(int ret){
|
rlm@10
|
1195 if(ret == -1)
|
rlm@10
|
1196 return null;
|
rlm@10
|
1197 return box((char) ret);
|
rlm@10
|
1198 }
|
rlm@10
|
1199
|
rlm@10
|
1200 static public Character readChar(Reader r) throws Exception{
|
rlm@10
|
1201 int ret = r.read();
|
rlm@10
|
1202 return readRet(ret);
|
rlm@10
|
1203 }
|
rlm@10
|
1204
|
rlm@10
|
1205 static public Character peekChar(Reader r) throws Exception{
|
rlm@10
|
1206 int ret;
|
rlm@10
|
1207 if(r instanceof PushbackReader) {
|
rlm@10
|
1208 ret = r.read();
|
rlm@10
|
1209 ((PushbackReader) r).unread(ret);
|
rlm@10
|
1210 }
|
rlm@10
|
1211 else {
|
rlm@10
|
1212 r.mark(1);
|
rlm@10
|
1213 ret = r.read();
|
rlm@10
|
1214 r.reset();
|
rlm@10
|
1215 }
|
rlm@10
|
1216
|
rlm@10
|
1217 return readRet(ret);
|
rlm@10
|
1218 }
|
rlm@10
|
1219
|
rlm@10
|
1220 static public int getLineNumber(Reader r){
|
rlm@10
|
1221 if(r instanceof LineNumberingPushbackReader)
|
rlm@10
|
1222 return ((LineNumberingPushbackReader) r).getLineNumber();
|
rlm@10
|
1223 return 0;
|
rlm@10
|
1224 }
|
rlm@10
|
1225
|
rlm@10
|
1226 static public LineNumberingPushbackReader getLineNumberingReader(Reader r){
|
rlm@10
|
1227 if(isLineNumberingReader(r))
|
rlm@10
|
1228 return (LineNumberingPushbackReader) r;
|
rlm@10
|
1229 return new LineNumberingPushbackReader(r);
|
rlm@10
|
1230 }
|
rlm@10
|
1231
|
rlm@10
|
1232 static public boolean isLineNumberingReader(Reader r){
|
rlm@10
|
1233 return r instanceof LineNumberingPushbackReader;
|
rlm@10
|
1234 }
|
rlm@10
|
1235
|
rlm@10
|
1236 static public String resolveClassNameInContext(String className){
|
rlm@10
|
1237 //todo - look up in context var
|
rlm@10
|
1238 return className;
|
rlm@10
|
1239 }
|
rlm@10
|
1240
|
rlm@10
|
1241 static public boolean suppressRead(){
|
rlm@10
|
1242 //todo - look up in suppress-read var
|
rlm@10
|
1243 return false;
|
rlm@10
|
1244 }
|
rlm@10
|
1245
|
rlm@10
|
1246 static public String printString(Object x){
|
rlm@10
|
1247 try {
|
rlm@10
|
1248 StringWriter sw = new StringWriter();
|
rlm@10
|
1249 print(x, sw);
|
rlm@10
|
1250 return sw.toString();
|
rlm@10
|
1251 }
|
rlm@10
|
1252 catch(Exception e) {
|
rlm@10
|
1253 throw new RuntimeException(e);
|
rlm@10
|
1254 }
|
rlm@10
|
1255 }
|
rlm@10
|
1256
|
rlm@10
|
1257 static public Object readString(String s){
|
rlm@10
|
1258 PushbackReader r = new PushbackReader(new StringReader(s));
|
rlm@10
|
1259 try {
|
rlm@10
|
1260 return LispReader.read(r, true, null, false);
|
rlm@10
|
1261 }
|
rlm@10
|
1262 catch(Exception e) {
|
rlm@10
|
1263 throw new RuntimeException(e);
|
rlm@10
|
1264 }
|
rlm@10
|
1265 }
|
rlm@10
|
1266
|
rlm@10
|
1267 static public void print(Object x, Writer w) throws Exception{
|
rlm@10
|
1268 //call multimethod
|
rlm@10
|
1269 if(PRINT_INITIALIZED.isBound() && RT.booleanCast(PRINT_INITIALIZED.deref()))
|
rlm@10
|
1270 PR_ON.invoke(x, w);
|
rlm@10
|
1271 //*
|
rlm@10
|
1272 else {
|
rlm@10
|
1273 boolean readably = booleanCast(PRINT_READABLY.deref());
|
rlm@10
|
1274 if(x instanceof Obj) {
|
rlm@10
|
1275 Obj o = (Obj) x;
|
rlm@10
|
1276 if(RT.count(o.meta()) > 0 &&
|
rlm@10
|
1277 ((readably && booleanCast(PRINT_META.deref()))
|
rlm@10
|
1278 || booleanCast(PRINT_DUP.deref()))) {
|
rlm@10
|
1279 IPersistentMap meta = o.meta();
|
rlm@10
|
1280 w.write("#^");
|
rlm@10
|
1281 if(meta.count() == 1 && meta.containsKey(TAG_KEY))
|
rlm@10
|
1282 print(meta.valAt(TAG_KEY), w);
|
rlm@10
|
1283 else
|
rlm@10
|
1284 print(meta, w);
|
rlm@10
|
1285 w.write(' ');
|
rlm@10
|
1286 }
|
rlm@10
|
1287 }
|
rlm@10
|
1288 if(x == null)
|
rlm@10
|
1289 w.write("nil");
|
rlm@10
|
1290 else if(x instanceof ISeq || x instanceof IPersistentList) {
|
rlm@10
|
1291 w.write('(');
|
rlm@10
|
1292 printInnerSeq(seq(x), w);
|
rlm@10
|
1293 w.write(')');
|
rlm@10
|
1294 }
|
rlm@10
|
1295 else if(x instanceof String) {
|
rlm@10
|
1296 String s = (String) x;
|
rlm@10
|
1297 if(!readably)
|
rlm@10
|
1298 w.write(s);
|
rlm@10
|
1299 else {
|
rlm@10
|
1300 w.write('"');
|
rlm@10
|
1301 //w.write(x.toString());
|
rlm@10
|
1302 for(int i = 0; i < s.length(); i++) {
|
rlm@10
|
1303 char c = s.charAt(i);
|
rlm@10
|
1304 switch(c) {
|
rlm@10
|
1305 case '\n':
|
rlm@10
|
1306 w.write("\\n");
|
rlm@10
|
1307 break;
|
rlm@10
|
1308 case '\t':
|
rlm@10
|
1309 w.write("\\t");
|
rlm@10
|
1310 break;
|
rlm@10
|
1311 case '\r':
|
rlm@10
|
1312 w.write("\\r");
|
rlm@10
|
1313 break;
|
rlm@10
|
1314 case '"':
|
rlm@10
|
1315 w.write("\\\"");
|
rlm@10
|
1316 break;
|
rlm@10
|
1317 case '\\':
|
rlm@10
|
1318 w.write("\\\\");
|
rlm@10
|
1319 break;
|
rlm@10
|
1320 case '\f':
|
rlm@10
|
1321 w.write("\\f");
|
rlm@10
|
1322 break;
|
rlm@10
|
1323 case '\b':
|
rlm@10
|
1324 w.write("\\b");
|
rlm@10
|
1325 break;
|
rlm@10
|
1326 default:
|
rlm@10
|
1327 w.write(c);
|
rlm@10
|
1328 }
|
rlm@10
|
1329 }
|
rlm@10
|
1330 w.write('"');
|
rlm@10
|
1331 }
|
rlm@10
|
1332 }
|
rlm@10
|
1333 else if(x instanceof IPersistentMap) {
|
rlm@10
|
1334 w.write('{');
|
rlm@10
|
1335 for(ISeq s = seq(x); s != null; s = s.next()) {
|
rlm@10
|
1336 IMapEntry e = (IMapEntry) s.first();
|
rlm@10
|
1337 print(e.key(), w);
|
rlm@10
|
1338 w.write(' ');
|
rlm@10
|
1339 print(e.val(), w);
|
rlm@10
|
1340 if(s.next() != null)
|
rlm@10
|
1341 w.write(", ");
|
rlm@10
|
1342 }
|
rlm@10
|
1343 w.write('}');
|
rlm@10
|
1344 }
|
rlm@10
|
1345 else if(x instanceof IPersistentVector) {
|
rlm@10
|
1346 IPersistentVector a = (IPersistentVector) x;
|
rlm@10
|
1347 w.write('[');
|
rlm@10
|
1348 for(int i = 0; i < a.count(); i++) {
|
rlm@10
|
1349 print(a.nth(i), w);
|
rlm@10
|
1350 if(i < a.count() - 1)
|
rlm@10
|
1351 w.write(' ');
|
rlm@10
|
1352 }
|
rlm@10
|
1353 w.write(']');
|
rlm@10
|
1354 }
|
rlm@10
|
1355 else if(x instanceof IPersistentSet) {
|
rlm@10
|
1356 w.write("#{");
|
rlm@10
|
1357 for(ISeq s = seq(x); s != null; s = s.next()) {
|
rlm@10
|
1358 print(s.first(), w);
|
rlm@10
|
1359 if(s.next() != null)
|
rlm@10
|
1360 w.write(" ");
|
rlm@10
|
1361 }
|
rlm@10
|
1362 w.write('}');
|
rlm@10
|
1363 }
|
rlm@10
|
1364 else if(x instanceof Character) {
|
rlm@10
|
1365 char c = ((Character) x).charValue();
|
rlm@10
|
1366 if(!readably)
|
rlm@10
|
1367 w.write(c);
|
rlm@10
|
1368 else {
|
rlm@10
|
1369 w.write('\\');
|
rlm@10
|
1370 switch(c) {
|
rlm@10
|
1371 case '\n':
|
rlm@10
|
1372 w.write("newline");
|
rlm@10
|
1373 break;
|
rlm@10
|
1374 case '\t':
|
rlm@10
|
1375 w.write("tab");
|
rlm@10
|
1376 break;
|
rlm@10
|
1377 case ' ':
|
rlm@10
|
1378 w.write("space");
|
rlm@10
|
1379 break;
|
rlm@10
|
1380 case '\b':
|
rlm@10
|
1381 w.write("backspace");
|
rlm@10
|
1382 break;
|
rlm@10
|
1383 case '\f':
|
rlm@10
|
1384 w.write("formfeed");
|
rlm@10
|
1385 break;
|
rlm@10
|
1386 case '\r':
|
rlm@10
|
1387 w.write("return");
|
rlm@10
|
1388 break;
|
rlm@10
|
1389 default:
|
rlm@10
|
1390 w.write(c);
|
rlm@10
|
1391 }
|
rlm@10
|
1392 }
|
rlm@10
|
1393 }
|
rlm@10
|
1394 else if(x instanceof Class) {
|
rlm@10
|
1395 w.write("#=");
|
rlm@10
|
1396 w.write(((Class) x).getName());
|
rlm@10
|
1397 }
|
rlm@10
|
1398 else if(x instanceof BigDecimal && readably) {
|
rlm@10
|
1399 w.write(x.toString());
|
rlm@10
|
1400 w.write('M');
|
rlm@10
|
1401 }
|
rlm@10
|
1402 else if(x instanceof Var) {
|
rlm@10
|
1403 Var v = (Var) x;
|
rlm@10
|
1404 w.write("#=(var " + v.ns.name + "/" + v.sym + ")");
|
rlm@10
|
1405 }
|
rlm@10
|
1406 else if(x instanceof Pattern) {
|
rlm@10
|
1407 Pattern p = (Pattern) x;
|
rlm@10
|
1408 w.write("#\"" + p.pattern() + "\"");
|
rlm@10
|
1409 }
|
rlm@10
|
1410 else w.write(x.toString());
|
rlm@10
|
1411 }
|
rlm@10
|
1412 //*/
|
rlm@10
|
1413 }
|
rlm@10
|
1414
|
rlm@10
|
1415 private static void printInnerSeq(ISeq x, Writer w) throws Exception{
|
rlm@10
|
1416 for(ISeq s = x; s != null; s = s.next()) {
|
rlm@10
|
1417 print(s.first(), w);
|
rlm@10
|
1418 if(s.next() != null)
|
rlm@10
|
1419 w.write(' ');
|
rlm@10
|
1420 }
|
rlm@10
|
1421 }
|
rlm@10
|
1422
|
rlm@10
|
1423 static public void formatAesthetic(Writer w, Object obj) throws IOException{
|
rlm@10
|
1424 if(obj == null)
|
rlm@10
|
1425 w.write("null");
|
rlm@10
|
1426 else
|
rlm@10
|
1427 w.write(obj.toString());
|
rlm@10
|
1428 }
|
rlm@10
|
1429
|
rlm@10
|
1430 static public void formatStandard(Writer w, Object obj) throws IOException{
|
rlm@10
|
1431 if(obj == null)
|
rlm@10
|
1432 w.write("null");
|
rlm@10
|
1433 else if(obj instanceof String) {
|
rlm@10
|
1434 w.write('"');
|
rlm@10
|
1435 w.write((String) obj);
|
rlm@10
|
1436 w.write('"');
|
rlm@10
|
1437 }
|
rlm@10
|
1438 else if(obj instanceof Character) {
|
rlm@10
|
1439 w.write('\\');
|
rlm@10
|
1440 char c = ((Character) obj).charValue();
|
rlm@10
|
1441 switch(c) {
|
rlm@10
|
1442 case '\n':
|
rlm@10
|
1443 w.write("newline");
|
rlm@10
|
1444 break;
|
rlm@10
|
1445 case '\t':
|
rlm@10
|
1446 w.write("tab");
|
rlm@10
|
1447 break;
|
rlm@10
|
1448 case ' ':
|
rlm@10
|
1449 w.write("space");
|
rlm@10
|
1450 break;
|
rlm@10
|
1451 case '\b':
|
rlm@10
|
1452 w.write("backspace");
|
rlm@10
|
1453 break;
|
rlm@10
|
1454 case '\f':
|
rlm@10
|
1455 w.write("formfeed");
|
rlm@10
|
1456 break;
|
rlm@10
|
1457 default:
|
rlm@10
|
1458 w.write(c);
|
rlm@10
|
1459 }
|
rlm@10
|
1460 }
|
rlm@10
|
1461 else
|
rlm@10
|
1462 w.write(obj.toString());
|
rlm@10
|
1463 }
|
rlm@10
|
1464
|
rlm@10
|
1465 static public Object format(Object o, String s, Object... args) throws Exception{
|
rlm@10
|
1466 Writer w;
|
rlm@10
|
1467 if(o == null)
|
rlm@10
|
1468 w = new StringWriter();
|
rlm@10
|
1469 else if(Util.equals(o, T))
|
rlm@10
|
1470 w = (Writer) OUT.deref();
|
rlm@10
|
1471 else
|
rlm@10
|
1472 w = (Writer) o;
|
rlm@10
|
1473 doFormat(w, s, ArraySeq.create(args));
|
rlm@10
|
1474 if(o == null)
|
rlm@10
|
1475 return w.toString();
|
rlm@10
|
1476 return null;
|
rlm@10
|
1477 }
|
rlm@10
|
1478
|
rlm@10
|
1479 static public ISeq doFormat(Writer w, String s, ISeq args) throws Exception{
|
rlm@10
|
1480 for(int i = 0; i < s.length();) {
|
rlm@10
|
1481 char c = s.charAt(i++);
|
rlm@10
|
1482 switch(Character.toLowerCase(c)) {
|
rlm@10
|
1483 case '~':
|
rlm@10
|
1484 char d = s.charAt(i++);
|
rlm@10
|
1485 switch(Character.toLowerCase(d)) {
|
rlm@10
|
1486 case '%':
|
rlm@10
|
1487 w.write('\n');
|
rlm@10
|
1488 break;
|
rlm@10
|
1489 case 't':
|
rlm@10
|
1490 w.write('\t');
|
rlm@10
|
1491 break;
|
rlm@10
|
1492 case 'a':
|
rlm@10
|
1493 if(args == null)
|
rlm@10
|
1494 throw new IllegalArgumentException("Missing argument");
|
rlm@10
|
1495 RT.formatAesthetic(w, RT.first(args));
|
rlm@10
|
1496 args = RT.next(args);
|
rlm@10
|
1497 break;
|
rlm@10
|
1498 case 's':
|
rlm@10
|
1499 if(args == null)
|
rlm@10
|
1500 throw new IllegalArgumentException("Missing argument");
|
rlm@10
|
1501 RT.formatStandard(w, RT.first(args));
|
rlm@10
|
1502 args = RT.next(args);
|
rlm@10
|
1503 break;
|
rlm@10
|
1504 case '{':
|
rlm@10
|
1505 int j = s.indexOf("~}", i); //note - does not nest
|
rlm@10
|
1506 if(j == -1)
|
rlm@10
|
1507 throw new IllegalArgumentException("Missing ~}");
|
rlm@10
|
1508 String subs = s.substring(i, j);
|
rlm@10
|
1509 for(ISeq sargs = RT.seq(RT.first(args)); sargs != null;)
|
rlm@10
|
1510 sargs = doFormat(w, subs, sargs);
|
rlm@10
|
1511 args = RT.next(args);
|
rlm@10
|
1512 i = j + 2; //skip ~}
|
rlm@10
|
1513 break;
|
rlm@10
|
1514 case '^':
|
rlm@10
|
1515 if(args == null)
|
rlm@10
|
1516 return null;
|
rlm@10
|
1517 break;
|
rlm@10
|
1518 case '~':
|
rlm@10
|
1519 w.write('~');
|
rlm@10
|
1520 break;
|
rlm@10
|
1521 default:
|
rlm@10
|
1522 throw new IllegalArgumentException("Unsupported ~ directive: " + d);
|
rlm@10
|
1523 }
|
rlm@10
|
1524 break;
|
rlm@10
|
1525 default:
|
rlm@10
|
1526 w.write(c);
|
rlm@10
|
1527 }
|
rlm@10
|
1528 }
|
rlm@10
|
1529 return args;
|
rlm@10
|
1530 }
|
rlm@10
|
1531 ///////////////////////////////// values //////////////////////////
|
rlm@10
|
1532
|
rlm@10
|
1533 static public Object[] setValues(Object... vals){
|
rlm@10
|
1534 //ThreadLocalData.setValues(vals);
|
rlm@10
|
1535 if(vals.length > 0)
|
rlm@10
|
1536 return vals;//[0];
|
rlm@10
|
1537 return null;
|
rlm@10
|
1538 }
|
rlm@10
|
1539
|
rlm@10
|
1540
|
rlm@10
|
1541 static public ClassLoader makeClassLoader(){
|
rlm@10
|
1542 return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction(){
|
rlm@10
|
1543 public Object run(){
|
rlm@10
|
1544 try{
|
rlm@10
|
1545 Var.pushThreadBindings(RT.map(USE_CONTEXT_CLASSLOADER, RT.T));
|
rlm@10
|
1546 // getRootClassLoader();
|
rlm@10
|
1547 return new DynamicClassLoader(baseLoader());
|
rlm@10
|
1548 }
|
rlm@10
|
1549 finally{
|
rlm@10
|
1550 Var.popThreadBindings();
|
rlm@10
|
1551 }
|
rlm@10
|
1552 }
|
rlm@10
|
1553 });
|
rlm@10
|
1554 }
|
rlm@10
|
1555
|
rlm@10
|
1556 static public ClassLoader baseLoader(){
|
rlm@10
|
1557 if(Compiler.LOADER.isBound())
|
rlm@10
|
1558 return (ClassLoader) Compiler.LOADER.deref();
|
rlm@10
|
1559 else if(booleanCast(USE_CONTEXT_CLASSLOADER.deref()))
|
rlm@10
|
1560 return Thread.currentThread().getContextClassLoader();
|
rlm@10
|
1561 return Compiler.class.getClassLoader();
|
rlm@10
|
1562 }
|
rlm@10
|
1563
|
rlm@10
|
1564 static public Class classForName(String name) throws ClassNotFoundException{
|
rlm@10
|
1565
|
rlm@10
|
1566 return Class.forName(name, true, baseLoader());
|
rlm@10
|
1567 }
|
rlm@10
|
1568
|
rlm@10
|
1569 static public Class loadClassForName(String name) throws ClassNotFoundException{
|
rlm@10
|
1570 try
|
rlm@10
|
1571 {
|
rlm@10
|
1572 Class.forName(name, false, baseLoader());
|
rlm@10
|
1573 }
|
rlm@10
|
1574 catch(ClassNotFoundException e)
|
rlm@10
|
1575 {
|
rlm@10
|
1576 return null;
|
rlm@10
|
1577 }
|
rlm@10
|
1578 return Class.forName(name, true, baseLoader());
|
rlm@10
|
1579 }
|
rlm@10
|
1580
|
rlm@10
|
1581 static public float aget(float[] xs, int i){
|
rlm@10
|
1582 return xs[i];
|
rlm@10
|
1583 }
|
rlm@10
|
1584
|
rlm@10
|
1585 static public float aset(float[] xs, int i, float v){
|
rlm@10
|
1586 xs[i] = v;
|
rlm@10
|
1587 return v;
|
rlm@10
|
1588 }
|
rlm@10
|
1589
|
rlm@10
|
1590 static public int alength(float[] xs){
|
rlm@10
|
1591 return xs.length;
|
rlm@10
|
1592 }
|
rlm@10
|
1593
|
rlm@10
|
1594 static public float[] aclone(float[] xs){
|
rlm@10
|
1595 return xs.clone();
|
rlm@10
|
1596 }
|
rlm@10
|
1597
|
rlm@10
|
1598 static public double aget(double[] xs, int i){
|
rlm@10
|
1599 return xs[i];
|
rlm@10
|
1600 }
|
rlm@10
|
1601
|
rlm@10
|
1602 static public double aset(double[] xs, int i, double v){
|
rlm@10
|
1603 xs[i] = v;
|
rlm@10
|
1604 return v;
|
rlm@10
|
1605 }
|
rlm@10
|
1606
|
rlm@10
|
1607 static public int alength(double[] xs){
|
rlm@10
|
1608 return xs.length;
|
rlm@10
|
1609 }
|
rlm@10
|
1610
|
rlm@10
|
1611 static public double[] aclone(double[] xs){
|
rlm@10
|
1612 return xs.clone();
|
rlm@10
|
1613 }
|
rlm@10
|
1614
|
rlm@10
|
1615 static public int aget(int[] xs, int i){
|
rlm@10
|
1616 return xs[i];
|
rlm@10
|
1617 }
|
rlm@10
|
1618
|
rlm@10
|
1619 static public int aset(int[] xs, int i, int v){
|
rlm@10
|
1620 xs[i] = v;
|
rlm@10
|
1621 return v;
|
rlm@10
|
1622 }
|
rlm@10
|
1623
|
rlm@10
|
1624 static public int alength(int[] xs){
|
rlm@10
|
1625 return xs.length;
|
rlm@10
|
1626 }
|
rlm@10
|
1627
|
rlm@10
|
1628 static public int[] aclone(int[] xs){
|
rlm@10
|
1629 return xs.clone();
|
rlm@10
|
1630 }
|
rlm@10
|
1631
|
rlm@10
|
1632 static public long aget(long[] xs, int i){
|
rlm@10
|
1633 return xs[i];
|
rlm@10
|
1634 }
|
rlm@10
|
1635
|
rlm@10
|
1636 static public long aset(long[] xs, int i, long v){
|
rlm@10
|
1637 xs[i] = v;
|
rlm@10
|
1638 return v;
|
rlm@10
|
1639 }
|
rlm@10
|
1640
|
rlm@10
|
1641 static public int alength(long[] xs){
|
rlm@10
|
1642 return xs.length;
|
rlm@10
|
1643 }
|
rlm@10
|
1644
|
rlm@10
|
1645 static public long[] aclone(long[] xs){
|
rlm@10
|
1646 return xs.clone();
|
rlm@10
|
1647 }
|
rlm@10
|
1648
|
rlm@10
|
1649 static public char aget(char[] xs, int i){
|
rlm@10
|
1650 return xs[i];
|
rlm@10
|
1651 }
|
rlm@10
|
1652
|
rlm@10
|
1653 static public char aset(char[] xs, int i, char v){
|
rlm@10
|
1654 xs[i] = v;
|
rlm@10
|
1655 return v;
|
rlm@10
|
1656 }
|
rlm@10
|
1657
|
rlm@10
|
1658 static public int alength(char[] xs){
|
rlm@10
|
1659 return xs.length;
|
rlm@10
|
1660 }
|
rlm@10
|
1661
|
rlm@10
|
1662 static public char[] aclone(char[] xs){
|
rlm@10
|
1663 return xs.clone();
|
rlm@10
|
1664 }
|
rlm@10
|
1665
|
rlm@10
|
1666 static public byte aget(byte[] xs, int i){
|
rlm@10
|
1667 return xs[i];
|
rlm@10
|
1668 }
|
rlm@10
|
1669
|
rlm@10
|
1670 static public byte aset(byte[] xs, int i, byte v){
|
rlm@10
|
1671 xs[i] = v;
|
rlm@10
|
1672 return v;
|
rlm@10
|
1673 }
|
rlm@10
|
1674
|
rlm@10
|
1675 static public int alength(byte[] xs){
|
rlm@10
|
1676 return xs.length;
|
rlm@10
|
1677 }
|
rlm@10
|
1678
|
rlm@10
|
1679 static public byte[] aclone(byte[] xs){
|
rlm@10
|
1680 return xs.clone();
|
rlm@10
|
1681 }
|
rlm@10
|
1682
|
rlm@10
|
1683 static public short aget(short[] xs, int i){
|
rlm@10
|
1684 return xs[i];
|
rlm@10
|
1685 }
|
rlm@10
|
1686
|
rlm@10
|
1687 static public short aset(short[] xs, int i, short v){
|
rlm@10
|
1688 xs[i] = v;
|
rlm@10
|
1689 return v;
|
rlm@10
|
1690 }
|
rlm@10
|
1691
|
rlm@10
|
1692 static public int alength(short[] xs){
|
rlm@10
|
1693 return xs.length;
|
rlm@10
|
1694 }
|
rlm@10
|
1695
|
rlm@10
|
1696 static public short[] aclone(short[] xs){
|
rlm@10
|
1697 return xs.clone();
|
rlm@10
|
1698 }
|
rlm@10
|
1699
|
rlm@10
|
1700 static public boolean aget(boolean[] xs, int i){
|
rlm@10
|
1701 return xs[i];
|
rlm@10
|
1702 }
|
rlm@10
|
1703
|
rlm@10
|
1704 static public boolean aset(boolean[] xs, int i, boolean v){
|
rlm@10
|
1705 xs[i] = v;
|
rlm@10
|
1706 return v;
|
rlm@10
|
1707 }
|
rlm@10
|
1708
|
rlm@10
|
1709 static public int alength(boolean[] xs){
|
rlm@10
|
1710 return xs.length;
|
rlm@10
|
1711 }
|
rlm@10
|
1712
|
rlm@10
|
1713 static public boolean[] aclone(boolean[] xs){
|
rlm@10
|
1714 return xs.clone();
|
rlm@10
|
1715 }
|
rlm@10
|
1716
|
rlm@10
|
1717 static public Object aget(Object[] xs, int i){
|
rlm@10
|
1718 return xs[i];
|
rlm@10
|
1719 }
|
rlm@10
|
1720
|
rlm@10
|
1721 static public Object aset(Object[] xs, int i, Object v){
|
rlm@10
|
1722 xs[i] = v;
|
rlm@10
|
1723 return v;
|
rlm@10
|
1724 }
|
rlm@10
|
1725
|
rlm@10
|
1726 static public int alength(Object[] xs){
|
rlm@10
|
1727 return xs.length;
|
rlm@10
|
1728 }
|
rlm@10
|
1729
|
rlm@10
|
1730 static public Object[] aclone(Object[] xs){
|
rlm@10
|
1731 return xs.clone();
|
rlm@10
|
1732 }
|
rlm@10
|
1733
|
rlm@10
|
1734
|
rlm@10
|
1735 }
|