package org.ibex.js; import java.io.Reader; import java.io.IOException; import java.io.InputStream; import org.ibex.util.*; public class JSU { public static final JS[] emptyArgs = new JS[] { }; public static InputStream getInputStream(JS j) throws IOException { while(j != null && j instanceof JS.Clone) j = j.unclone(); if (j != null && j instanceof Fountain) return ((Fountain)j).getInputStream(); return null; } /** returns a Pausable which will restart the context; * expects a value to be pushed onto the stack when unpaused. */ public static Pausable pause() throws Pausable.NotPausableException { Interpreter i = Interpreter.current(); i.pause(); return i; } /** Coerce a JS object into a boolean. */ public static boolean toBoolean(JS o) { if(o == null) return false; if(o instanceof JSNumber) return ((JSNumber)o).toBoolean(); if(o instanceof JSString) return ((JSString)o).s.length() != 0; return true; } //#repeat long/int/double/float toLong/toInt/toDouble/toFloat Long/Integer/Double/Float parseLong/parseInt/parseDouble/parseFloat /** Coerce a JS object to a long. */ public static long toLong(JS o) throws JSExn { if(o == null) return 0; if(o instanceof JSNumber) return ((JSNumber)o).toLong(); if(o instanceof JSString) return Long.parseLong(o.coerceToString()); throw new JSExn("can't coerce a " + o.getClass().getName() + " to a number"); } //#end /** Coerce a JS object to a String. */ public static String toString(JS o) throws JSExn { if(o == null) return "null"; return o.coerceToString(); } public static boolean isInt(JS o) { if(o == null) return true; if(o instanceof JSNumber.I) return true; if(o instanceof JSNumber.B) return false; if(o instanceof JSNumber) { JSNumber n = (JSNumber) o; return n.toInt() == n.toDouble(); } if(o instanceof JSString) { String s = ((JSString)o).s; for(int i=0;i '9') return false; return true; } return false; } public static boolean isString(JS o) { if(o instanceof JSString) return true; return false; } // Instance Methods //////////////////////////////////////////////////////////////////// public final static JS NaN = new JSNumber.D(Double.NaN); public final static JS ZERO = new JSNumber.I(0); public final static JS ONE = new JSNumber.I(1); public final static JS MATH = new JSMath(); public static final JS T = new JSNumber.B(true); public static final JS F = new JSNumber.B(false); public static final JS B(boolean b) { return b ? T : F; } public static final JS B(int i) { return i==0 ? F : T; } private static final int CACHE_SIZE = 65536 / 4; // must be a power of two private static final JSString[] stringCache = new JSString[CACHE_SIZE]; public static final JS S(String s) { if(s == null) return null; int slot = s.hashCode()&(CACHE_SIZE-1); JSString ret = stringCache[slot]; if(ret == null || !ret.s.equals(s)) stringCache[slot] = ret = new JSString(s); return ret; } public static final JS S(String s, boolean intern) { return intern ? JSString.intern(s) : S(s); } public static final JS N(double d) { return new JSNumber.D(d); } public static final JS N(long l) { return new JSNumber.L(l); } public static final JS N(Number n) { if(n instanceof Integer) return N(n.intValue()); if(n instanceof Long) return N(n.longValue()); return N(n.doubleValue()); } private static final JSNumber.I negone = new JSNumber.I(-1); private static final JSNumber.I[] icache = new JSNumber.I[128]; static { for (int i=0; i < icache.length; i++) icache[i] = new JSNumber.I(i); } public static final JS N(int i) { return i == -1 ? negone : i >= 0 && i < icache.length ? icache[i] : new JSNumber.I(i); } /** Internal method for coercing to String without throwing a JSExn. */ public static String str(JS o) { try { return toString(o); } catch(JSExn e) { return o.toString(); } } // Static Interpreter Control Methods /////////////////////////////////////////////////////////////// public static JS fromReader(String sourceName, int firstLine, Reader source) throws IOException { return Parser.fromReader(sourceName, firstLine, source); } public static JS cloneWithNewGlobalScope(JS js, JS s) { return js instanceof JSFunction ? ((JSFunction)js)._cloneWithNewParentScope(new JSScope.Top(s)) : js; } /** log a message with the current JavaScript sourceName/line */ public static void log(Object message) { info(message); } public static void debug(Object message) { Log.debug(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); } public static void info(Object message) { Log.info(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); } public static void warn(Object message) { Log.warn(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); } public static void error(Object message) { Log.error(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); } }