//public static final byte DECLARE = -6;
/** push a reference to the current scope onto the stack */
- // FIXME: Document this
public static final byte GLOBALSCOPE = -7;
/** if given a null literal pop two elements off the stack; push stack[-1].get(stack[top])
/** finish a finally block and carry out whatever instruction initiated the finally block */
public static final byte MAKE_GRAMMAR = -25;
- // FIXME: Document these and NEWSCOPE/OLDSCOPE/TOPSCOPE changes
+ // FEATURE: Document these and NEWSCOPE/OLDSCOPE/TOPSCOPE changes
public static final byte SCOPEGET = -26;
public static final byte SCOPEPUT = -27;
}
boolean match(CharIndexed input, REMatch mymatch) {
- // charAt(index-n) may be unknown on a Reader/InputStream. FIXME
+ // charAt(index-n) may be unknown on a Reader/InputStream.
// Match after a newline if in multiline mode
if (newline != null) {
TrapMarker tm = (TrapMarker) o;
JS key = tm.t.key();
JS target = tm.t.target();
- if(tm.t.isWriteTrap() != write) throw new JSExn("tried to do a " + (write?"write":"read") + " cascade in a " + (write?"read":"write") + " trap");
+ if(tm.t.isWriteTrap() != write)
+ throw new JSExn("tried to do a "+(write?"write":"read") + " cascade in a " + (write?"read":"write") + " trap");
JS.Trap t = write ? tm.t.nextWrite() : tm.t.nextRead();
- // FIXME: Doesn't handle multiple levels of clone's (probably can just make this a while loop)
- if(t == null && target instanceof JS.Clone) {
+ while (t == null && target instanceof JS.Clone) {
target = ((JS.Clone)target).clonee;
t = target.getTrap(key);
if(t != null) t = write ? t.write() : t.read();
}
case CALL: case CALLMETHOD: {
- // FIXME: can a lot of simple cases in Parser be
- // reduced so creating a new JS[] is not necessary?
JS[] jsargs;
if (arg instanceof JSNumber.I) {
+ // FIXME: we should be able to recycle JS[]'s here
jsargs = new JS[((JSNumber.I)arg).toInt()];
for (int i=0; i < jsargs.length; i++) jsargs[i] = (JS)stack.pop();
} else jsargs = (JS[])arg;
case THROW:
throw new JSExn((JS)stack.pop(), this);
- /* FIXME GRAMMAR
- case MAKE_GRAMMAR: {
- final Grammar r = (Grammar)arg;
- final JSScope final_scope = scope;
- Grammar r2 = new Grammar() {
- public int match(String s, int start, Map v, JSScope scope) throws JSExn {
- return r.match(s, start, v, final_scope);
- }
- public int matchAndWrite(String s, int start, Map v, JSScope scope, String key) throws JSExn {
- return r.matchAndWrite(s, start, v, final_scope, key);
- }
- public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
- Map v = new Map();
- r.matchAndWrite((String)a0, 0, v, final_scope, "foo");
- return v.get("foo");
- }
- };
- Object obj = stack.pop();
- if (obj != null && obj instanceof Grammar) r2 = new Grammar.Alternative((Grammar)obj, r2);
- stack.push(r2);
- break;
- }
- */
case ADD_TRAP: case DEL_TRAP: {
JS val = (JS)stack.pop();
JS key = (JS)stack.pop();
JS js = (JS)stack.peek();
// A trap addition/removal
- if(!(val instanceof JSFunction)) throw new JSExn("tried to add/remove a non-function trap"); // FIXME
+ if(!(val instanceof JSFunction)) throw new JSExn("tried to add/remove a non-function trap");
if(op == ADD_TRAP) js.addTrap(key, val);
else js.delTrap(key, val);
break;
void setupTrap(JS.Trap t, JS val, CallMarker cm) throws JSExn {
stack.push(cm);
stack.push(new TrapArgs(t, val));
- f = (JSFunction)t.function(); // FIXME
+ f = (JSFunction)t.function();
scope = f.parentScope;
pc = 0;
}
public void delTrap(JS key, JS function) throws JSExn;
public Trap getTrap(JS key) throws JSExn;
- // FIXME: consider renaming/removing these
+ // FEATURE: consider renaming/removing these
public JS unclone();
public String coerceToString() throws JSExn;
public String[] getFormalArgs() { return emptystr; }
public String coerceToString() throws JSExn { throw new JSExn("cannot coerce a "+getClass().getName()+" to a string"); }
- public JS putAndTriggerTraps(JS key, JS val) throws JSExn { throw new JSExn(
- "'" + key + "' is trap read only on class ["+ getClass().getName() +"]"); }
- public JS getAndTriggerTraps(JS key) throws JSExn { return null; } // FIXME throw errors?
+ public JS putAndTriggerTraps(JS key, JS val) throws JSExn {
+ throw new JSExn("'" + key + "' is trap read only on class ["+ getClass().getName() +"]"); }
+ public JS getAndTriggerTraps(JS key) throws JSExn { return null; }
public JS justTriggerTraps(JS key, JS value) throws JSExn { return null; }
public void addTrap(JS key, JS function) throws JSExn {
Log.warn(this, "'" + JSU.str(key) + "' is not trappable on class ["+ getClass().getName() +"]"); }
public Trap next();
public Trap nextRead();
public Trap nextWrite();
-
- public Trap read(); // FIXME reconsider these function names
+ public Trap read(); // FEATURE reconsider these function names
public Trap write();
}
}
public String[] getFormalArgs() { return empty; }
- public String coerceToString() { return "array"; } // FIXME
+ public String coerceToString() throws JSExn { throw new JSExn("cannot coerce a "+getClass().getName()+" to a string"); }
public JS call(JS method, JS[] args) throws JSExn {
//#switch(JSU.str(method))
public void delTrap(JS k, JS f) throws JSExn { throw new JSExn("arrays do not support traps"); }
public JS.Trap getTrap(JS k) throws JSExn { throw new JSExn("arrays do not support traps"); }
- /** FIXME: move to specialised ArrayStore superclass. */
+ /** FEATURE: move to specialised ArrayStore superclass. */
public void addAll(JS[] entries) { for (int i=0; i < entries.length; i++) add(entries[i]); }
public void setSize(int newSize) {
if(start > length) start = length;
if(end > length) end = length;
JSArray a = new JSArray(end-start);
- for(int i=0;i<end-start;i++) // FIXME: with ArrayStore do System.arraycopy()
+ for(int i=0;i<end-start;i++) // FEATURE: with ArrayStore do System.arraycopy()
a.set(i, get(start+i));
return a;
}
int newLength = oldLength - deleteCount + newCount;
int lengthChange = newLength - oldLength;
JSArray ret = new JSArray(deleteCount);
- for(int i=0;i<deleteCount;i++) // FIXME: ArrayStore System.arraycopy()
+ for(int i=0;i<deleteCount;i++) // FEATURE: ArrayStore System.arraycopy()
ret.set(i, get(start+i));
if(lengthChange > 0) {
setSize(newLength);
// Public //////////////////////////////////////////////////////////////////////////////
- // FIXME: what needs to be syncrhonized (if anything)?
private Interpreter runner = null;
public Object run(Object o) throws JSExn {
if (runner == null) runner = new Interpreter(this, true, emptyArgs);
if (o instanceof Number) return JSU.N((Number)o);
if (o instanceof JS) return (JS)o;
if (o instanceof Object[]) {
- // FIXME: get element type here
+ throw new JSExn("Reflection onto Object[] not supported yet");
}
throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
}
public JS get(JS key) throws JSExn { return wrap(arr[JSU.toInt(key)]); }
}
- // FIXME public static class Hash { }
- // FIXME public Enumeration keys() throws JSExn { }
+ public Enumeration keys() throws JSExn { throw new JSExn("JSReflection.keys() not supported yet"); }
public JS get(JS key) throws JSExn {
String k = JSU.toString(key);
public static final JS[] emptyArgs = new JS[] { };
- // FIXME
- public static InputStream getInputStream(JS j) { return null; }
+ public static InputStream getInputStream(JS j) throws IOException {
+ while(j != null && j instanceof JS.Cloneable) 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 JS fromReader(String sourceName, int firstLine, Reader source) throws IOException {
return Parser.fromReader(sourceName, firstLine, source); }
- // FIXME
public static JS cloneWithNewGlobalScope(JS js, JS s) {
- if(js instanceof JSFunction)
- return ((JSFunction)js)._cloneWithNewParentScope(new JSScope.Top(s));
- else
- return js;
- }
+ 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); }