/** create a new instance; literal is a reference to the corresponding ForthBlock */
public static final byte NEWFUNCTION = -5;
- /** pop a string off the stack and declare it in the current scope */
+ /** if given a non-null argument declare its argument in the current scope and push
+ it to the stack, else, declares the element on the top of the stack and leaves it
+ there */
public static final byte DECLARE = -6;
/** push a reference to the current scope onto the stack */
public static final byte TOPSCOPE = -7;
- /** pop two elements off the stack; push stack[-1].get(stack[top]) */
+ /** if given a null literal pop two elements off the stack; push stack[-1].get(stack[top])
+ else pop one element off the stack, push stack[top].get(literal) */
public static final byte GET = -8;
/** push stack[-1].get(stack[top]) */
// Adding and Altering Bytecodes ///////////////////////////////////////////////////
int get(int pos) { return op[pos]; }
+ Object getArg(int pos) { return arg[pos]; }
void set(int pos, int op_, Object arg_) { op[pos] = op_; arg[pos] = arg_; }
void set(int pos, Object arg_) { arg[pos] = arg_; }
+ int pop() { size--; arg[size] = null; return op[size]; }
void paste(CompiledFunctionImpl other) { for(int i=0; i<other.size; i++) add(other.line[i], other.op[i], other.arg[i]); }
CompiledFunctionImpl add(int line, int op_) { return add(line, op_, null); }
CompiledFunctionImpl add(int line, int op_, Object arg_) {
case LITERAL: t.push(arg[pc]); break;
case OBJECT: t.push(new JS.Obj()); break;
case ARRAY: t.push(new JS.Array(JS.toNumber(arg[pc]).intValue())); break;
- case DECLARE: s.declare((String)t.pop()); break;
+ case DECLARE: s.declare((String)(arg[pc]==null ? t.peek() : arg[pc])); if(arg[pc] != null) t.push(arg[pc]); break;
case TOPSCOPE: t.push(s); break;
case JT: if (JS.toBoolean(t.pop())) pc += JS.toNumber(arg[pc]).intValue() - 1; break;
case JF: if (!JS.toBoolean(t.pop())) pc += JS.toNumber(arg[pc]).intValue() - 1; break;
case GET_PRESERVE: {
Object o, v;
if (op[pc] == GET) {
- v = t.pop();
+ v = arg[pc] == null ? t.pop() : arg[pc];
o = t.pop();
} else {
v = t.pop();