annotate src/clojure/lang/RT.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
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 }