diff --git a/mozilla/js/js2/java/AssignmentNode.java b/mozilla/js/js2/java/AssignmentNode.java index e65f66f2287..4b653602836 100644 --- a/mozilla/js/js2/java/AssignmentNode.java +++ b/mozilla/js/js2/java/AssignmentNode.java @@ -13,9 +13,8 @@ class AssignmentNode extends BinaryNode { JSValue rValue = theEnv.theStack.pop(); JSValue lValue = theEnv.theStack.pop(); - theEnv.theGlobals.put(lValue.toString(), rValue); - - + theEnv.theStack.push(rValue); + lValue.putProp(theEnv); } } \ No newline at end of file diff --git a/mozilla/js/js2/java/BinaryNode.java b/mozilla/js/js2/java/BinaryNode.java index 429f1225948..9a8acbf4bd2 100644 --- a/mozilla/js/js2/java/BinaryNode.java +++ b/mozilla/js/js2/java/BinaryNode.java @@ -7,10 +7,29 @@ class BinaryNode extends ExpressionNode { op = aOp; } + void evalLHS(Environment theEnv) + { + left.evalLHS(theEnv); + JSValue lV = theEnv.theStack.pop(); + right.eval(theEnv); + + if (op == ".") + lV.getProp(theEnv); + else + super.evalLHS(theEnv); + } + void eval(Environment theEnv) { left.eval(theEnv); + JSValue lV = theEnv.theStack.pop(); right.eval(theEnv); + + if (op == ".") + lV.getProp(theEnv); + else + System.out.println("missing binary op " + op); + } String print(String indent) diff --git a/mozilla/js/js2/java/ControlNodeGroup.java b/mozilla/js/js2/java/ControlNodeGroup.java index 5e55474bc5a..4a7f028a547 100644 --- a/mozilla/js/js2/java/ControlNodeGroup.java +++ b/mozilla/js/js2/java/ControlNodeGroup.java @@ -55,15 +55,22 @@ class ControlNodeGroup { tails.removeAllElements(); } - void fixContinues(ControlNode butt) + void fixContinues(ControlNode butt, String label) { int count = continueTails.size(); - for (int i = 0; i < count; i++) - { - ControlNode aNode = (ControlNode)(continueTails.elementAt(i)); - aNode.setNext(butt); + int i = 0; + while (i < count) { + ControlNode c = (ControlNode)(continueTails.elementAt(i)); + ExpressionNode e = c.getExpression(); + String tgt = (e == null) ? null : ((JSIdentifier)e).s; + if ((tgt == null) || tgt.equals(label)) { + c.setNext(butt); + continueTails.removeElementAt(i); + count--; + } + else + i++; } - continueTails.removeAllElements(); } void setHead(ControlNode aHead) @@ -123,18 +130,19 @@ class ControlNodeGroup { void shiftBreakTails(String label) { int count = breakTails.size(); - for (int i = 0; i < count; i++) - { + int i = 0; + while (i < count) { ControlNode c = (ControlNode)(breakTails.elementAt(i)); ExpressionNode e = c.getExpression(); - String tgt = (e == null) ? null : ((JSObject)e).value; + String tgt = (e == null) ? null : ((JSIdentifier)e).s; if ((tgt == null) || tgt.equals(label)) { tails.addElement(c); breakTails.removeElementAt(i); - i--; count--; } - } + else + i++; + } } ControlNode head; diff --git a/mozilla/js/js2/java/Environment.java b/mozilla/js/js2/java/Environment.java index a1e02b274f9..f96ce5b4ba6 100644 --- a/mozilla/js/js2/java/Environment.java +++ b/mozilla/js/js2/java/Environment.java @@ -3,13 +3,13 @@ import java.util.Hashtable; class Environment { - JSStack theStack = new JSStack(); - Hashtable theGlobals = new Hashtable(); + JSStack theStack = new JSStack(); + JSObject scope = new JSObject("globals"); String print() { StringBuffer result = new StringBuffer("Globals contents :\n"); - result.append(theGlobals.toString()); + result.append(scope.toString()); result.append("\nStack Top = " + theStack.size()); return result.toString(); } diff --git a/mozilla/js/js2/java/JSBoolean.java b/mozilla/js/js2/java/JSBoolean.java index e1acc2981c9..16580ff37a7 100644 --- a/mozilla/js/js2/java/JSBoolean.java +++ b/mozilla/js/js2/java/JSBoolean.java @@ -23,6 +23,14 @@ class JSBoolean extends JSValue { return !b; } + void bang(Environment theEnv) { + theEnv.theStack.push((b) ? JSFalse : JSTrue); + } + + void typeof(Environment theEnv) { + theEnv.theStack.push(new JSString("boolean")); + } + JSBoolean toJSBoolean() { return this; } diff --git a/mozilla/js/js2/java/JSDouble.java b/mozilla/js/js2/java/JSDouble.java index 4fbd7878179..49c3293c20f 100644 --- a/mozilla/js/js2/java/JSDouble.java +++ b/mozilla/js/js2/java/JSDouble.java @@ -20,6 +20,13 @@ class JSDouble extends JSNumber { theEnv.theStack.push(this); } + void plus(Environment theEnv) { + theEnv.theStack.push(this); + } + + void minus(Environment theEnv) { + theEnv.theStack.push(new JSDouble(-d)); + } void add(Environment theEnv) { JSValue vR = theEnv.theStack.peek(); diff --git a/mozilla/js/js2/java/JSGrammar.g b/mozilla/js/js2/java/JSGrammar.g index e8ea70fb9eb..747e24bc55e 100644 --- a/mozilla/js/js2/java/JSGrammar.g +++ b/mozilla/js/js2/java/JSGrammar.g @@ -45,7 +45,7 @@ options { // ********* Identifiers ********** identifier returns [ExpressionNode e] { e = null; } - : opI:IDENT { e = new JSObject(opI.getText()); } + : opI:IDENT { e = new JSIdentifier(opI.getText()); } | "version" { e = new JSObject("version"); } | "override" { e = new JSObject("override"); } | "method" { e = new JSObject("method"); } @@ -454,7 +454,7 @@ statements[int scope, ControlNodeGroup container] // ********* Labeled Statements ********** labeled_statement[boolean non_empty, ControlNodeGroup container] { ExpressionNode e = null; } - : e = identifier ":" code_statement[non_empty, container, ((JSObject)e).value] + : e = identifier ":" code_statement[non_empty, container, ((JSIdentifier)e).s] ; if_statement[boolean non_empty, ControlNodeGroup container] diff --git a/mozilla/js/js2/java/JSInteger.java b/mozilla/js/js2/java/JSInteger.java index 7efd5c66069..39280f95a1a 100644 --- a/mozilla/js/js2/java/JSInteger.java +++ b/mozilla/js/js2/java/JSInteger.java @@ -35,6 +35,10 @@ class JSInteger extends JSNumber { return new JSString(Integer.toString(i)); } + void twiddle(Environment theEnv) { + theEnv.theStack.push(new JSInteger(~i)); + } + void and(Environment theEnv) { JSValue vR = theEnv.theStack.pop(); theEnv.theStack.push(new JSInteger(i & vR.toJSInteger().i)); diff --git a/mozilla/js/js2/java/JSNumber.java b/mozilla/js/js2/java/JSNumber.java index d8d7b7b216d..bd89e31499d 100644 --- a/mozilla/js/js2/java/JSNumber.java +++ b/mozilla/js/js2/java/JSNumber.java @@ -1,3 +1,8 @@ abstract class JSNumber extends JSValue { + + void typeof(Environment theEnv) { + theEnv.theStack.push(new JSString("number")); + } + } \ No newline at end of file diff --git a/mozilla/js/js2/java/JSObject.java b/mozilla/js/js2/java/JSObject.java index 11355211c49..f50ac93b1bf 100644 --- a/mozilla/js/js2/java/JSObject.java +++ b/mozilla/js/js2/java/JSObject.java @@ -1,3 +1,6 @@ + +import java.util.Hashtable; + class JSObject extends JSValue { static JSObject JSUndefined = new JSObject("undefined"); @@ -12,20 +15,16 @@ class JSObject extends JSValue { return indent + "JSObject : " + value + "\n"; } - void evalLHS(Environment theEnv) + void eval(Environment theEnv) { theEnv.theStack.push(this); } - - void eval(Environment theEnv) - { - JSValue v = (JSValue)(theEnv.theGlobals.get(value)); - if (v == null) { - System.out.println("Accessed undefined : " + value); - theEnv.theStack.push(JSUndefined); - } + + void typeof(Environment theEnv) { + if (this == JSUndefined) + theEnv.theStack.push(new JSString("undefined")); else - theEnv.theStack.push(v); + theEnv.theStack.push(new JSString("object")); } JSValue defaultValue(String hint) { @@ -48,107 +47,25 @@ class JSObject extends JSValue { return toPrimitive("Number").toJSDouble(); } - void gt(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.gt(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().gt(theEnv); - } - } - - void ge(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.ge(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().ge(theEnv); - } - } - - void lt(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.lt(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().lt(theEnv); - } - } - - void le(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.le(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().le(theEnv); - } - } - - void eq(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.eq(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().eq(theEnv); - } - } - - void ne(Environment theEnv) { - JSValue lV = toPrimitive("Number"); - JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.ne(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().ne(theEnv); - } - } - - void add(Environment theEnv) { - JSValue lV = toPrimitive(""); - JSValue rV = theEnv.theStack.pop().toPrimitive(""); - if ((lV instanceof JSString) || (rV instanceof JSString)) { - theEnv.theStack.push(rV); - lV.ne(theEnv); - } - else { - theEnv.theStack.push(rV.toJSDouble()); - lV.toJSDouble().add(theEnv); - } - } - - void subtract(Environment theEnv) { - theEnv.theStack.push(theEnv.theStack.pop().toJSDouble()); - toJSDouble().subtract(theEnv); - } - - public String toString() { - return value; + return value + contents.toString(); } + void getProp(Environment theEnv) { + JSString id = theEnv.theStack.pop().toJSString(); + JSValue v = (JSValue)(contents.get(id.s)); + theEnv.theStack.push(v); + } + + void putProp(Environment theEnv) { + JSValue v = theEnv.theStack.pop(); + JSString id = theEnv.theStack.pop().toJSString(); + contents.put(id.s, v); + } + + + Hashtable contents = new Hashtable(); + String value; } \ No newline at end of file diff --git a/mozilla/js/js2/java/JSString.java b/mozilla/js/js2/java/JSString.java index 82acbf11eda..e21e35f55c9 100644 --- a/mozilla/js/js2/java/JSString.java +++ b/mozilla/js/js2/java/JSString.java @@ -10,6 +10,10 @@ class JSString extends JSValue { theEnv.theStack.push(this); } + void typeof(Environment theEnv) { + theEnv.theStack.push(new JSString("string")); + } + void add(Environment theEnv) { JSString vR = theEnv.theStack.pop().toJSString(); @@ -88,6 +92,6 @@ class JSString extends JSValue { return this; } - String s; + protected String s; } \ No newline at end of file diff --git a/mozilla/js/js2/java/JSValue.java b/mozilla/js/js2/java/JSValue.java index e7dedd883ca..ec0d1de8d3e 100644 --- a/mozilla/js/js2/java/JSValue.java +++ b/mozilla/js/js2/java/JSValue.java @@ -20,25 +20,176 @@ class JSValue extends ExpressionNode { throw new RuntimeException("unimplemented " + op + " called"); } - void add(Environment theEnv) { unimplemented("add"); } - void subtract(Environment theEnv) { unimplemented("subtract"); } - void multiply(Environment theEnv) { unimplemented("multiply"); } - void divide(Environment theEnv) { unimplemented("divide"); } - void remainder(Environment theEnv) { unimplemented("remainder"); } + void gt(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.gt(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().gt(theEnv); + } + } - void and(Environment theEnv) { unimplemented("and"); } - void or(Environment theEnv) { unimplemented("or"); } - void xor(Environment theEnv) { unimplemented("xor"); } - void shl(Environment theEnv) { unimplemented("shl"); } - void shr(Environment theEnv) { unimplemented("shr"); } - void ushl(Environment theEnv) { unimplemented("ushl"); } + void ge(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.ge(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().ge(theEnv); + } + } - void gt(Environment theEnv) { unimplemented("gt"); } - void ge(Environment theEnv) { unimplemented("ge"); } - void lt(Environment theEnv) { unimplemented("lt"); } - void le(Environment theEnv) { unimplemented("le"); } - void eq(Environment theEnv) { unimplemented("eq"); } - void ne(Environment theEnv) { unimplemented("ne"); } + void lt(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.lt(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().lt(theEnv); + } + } + + void le(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.le(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().le(theEnv); + } + } + + void eq(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.eq(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().eq(theEnv); + } + } + + void ne(Environment theEnv) { + JSValue lV = toPrimitive("Number"); + JSValue rV = theEnv.theStack.pop().toPrimitive("Number"); + if ((lV instanceof JSString) && (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.ne(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().ne(theEnv); + } + } + + void plus(Environment theEnv) { + toJSDouble().plus(theEnv); + } + + void minus(Environment theEnv) { + toJSDouble().minus(theEnv); + } + + void twiddle(Environment theEnv) { + toJSInteger().twiddle(theEnv); + } + + void bang(Environment theEnv) { + toJSBoolean().bang(theEnv); + } + + void typeof(Environment theEnv) { + unimplemented("typeof"); + } + + void add(Environment theEnv) { + JSValue lV = toPrimitive(""); + JSValue rV = theEnv.theStack.pop().toPrimitive(""); + if ((lV instanceof JSString) || (rV instanceof JSString)) { + theEnv.theStack.push(rV); + lV.ne(theEnv); + } + else { + theEnv.theStack.push(rV.toJSDouble()); + lV.toJSDouble().add(theEnv); + } + } + + void subtract(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSDouble()); + toJSDouble().subtract(theEnv); + } + + void multiply(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSDouble()); + toJSDouble().multiply(theEnv); + } + + void divide(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSDouble()); + toJSDouble().divide(theEnv); + } + + void remainder(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSDouble()); + toJSDouble().remainder(theEnv); + } + + void and(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().and(theEnv); + } + + void or(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().or(theEnv); + } + + void xor(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().xor(theEnv); + } + + void shl(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().shl(theEnv); + } + + void shr(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().shr(theEnv); + } + + void ushl(Environment theEnv) { + theEnv.theStack.push(theEnv.theStack.pop().toJSInteger()); + toJSInteger().ushl(theEnv); + } + + void getProp(Environment theEnv) { + unimplemented("getProp"); + } + + void putProp(Environment theEnv) { + unimplemented("putProp"); + } + + JSDouble toJSDouble() { unimplemented("toJSDouble"); return null; } JSInteger toJSInteger() { unimplemented("toJSInteger"); return null; } diff --git a/mozilla/js/js2/java/TryNode.java b/mozilla/js/js2/java/TryNode.java index a696451d6b6..bf7304bd518 100644 --- a/mozilla/js/js2/java/TryNode.java +++ b/mozilla/js/js2/java/TryNode.java @@ -33,7 +33,7 @@ class TryNode extends ControlNode { ExpressionNode e = (ExpressionNode)(catchExpr.elementAt(i)); String id = ((JSObject)e).value; theEnv.theStack.setStack(stackHeight); - theEnv.theGlobals.put(id, x.getValue()); + theEnv.scope.contents.put(id, x.getValue()); // XXX YAARGH !!! return (ControlNode)(catchCode.elementAt(i)); } } diff --git a/mozilla/js/js2/java/UnaryNode.java b/mozilla/js/js2/java/UnaryNode.java index 102c8b8f1d6..0ec16a89b39 100644 --- a/mozilla/js/js2/java/UnaryNode.java +++ b/mozilla/js/js2/java/UnaryNode.java @@ -22,6 +22,29 @@ class UnaryNode extends ExpressionNode { return result.toString(); } + void eval(Environment theEnv) + { + child.eval(theEnv); + JSValue cV = theEnv.theStack.pop(); + + if (op == "+") + cV.plus(theEnv); + else + if (op == "-") + cV.minus(theEnv); + else + if (op == "~") + cV.twiddle(theEnv); + else + if (op == "!") + cV.bang(theEnv); + else + if (op == "typeof") + cV.typeof(theEnv); + else + System.out.println("missing unary op " + op); + } + String getOperator() { return op;