Moved from stack to inline execution.

This commit is contained in:
rogerl%netscape.com 1999-05-28 19:00:48 +00:00
parent e4fa0248e5
commit 8801e117eb
23 changed files with 279 additions and 396 deletions

View File

@ -5,28 +5,29 @@ class ArithmeticNode extends BinaryNode {
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.eval(theEnv);
JSValue lV = theEnv.theStack.pop();
right.eval(theEnv);
JSValue lV = left.eval(theEnv);
JSValue rV = right.eval(theEnv);
if (op == "+")
lV.add(theEnv);
return lV.add(theEnv, rV);
else
if (op == "-")
lV.subtract(theEnv);
return lV.subtract(theEnv, rV);
else
if (op == "*")
lV.multiply(theEnv);
return lV.multiply(theEnv, rV);
else
if (op == "/")
lV.divide(theEnv);
return lV.divide(theEnv, rV);
else
if (op == "%")
lV.remainder(theEnv);
else
return lV.remainder(theEnv, rV);
else {
System.out.println("missing arithmetic op " + op);
return null;
}
}
}

View File

@ -5,16 +5,12 @@ class AssignmentNode extends BinaryNode {
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.evalLHS(theEnv);
right.eval(theEnv);
JSReference lV = left.evalLHS(theEnv);
JSValue rV = right.eval(theEnv);
JSValue rValue = theEnv.theStack.pop();
JSValue lValue = theEnv.theStack.pop();
theEnv.theStack.push(rValue);
lValue.putProp(theEnv);
return lV.base.putProp(theEnv, lV.id, rV);
}
}

View File

@ -7,31 +7,32 @@ class BinaryNode extends ExpressionNode {
op = aOp;
}
void evalLHS(Environment theEnv)
JSReference evalLHS(Environment theEnv)
{
if (op == ".") {
left.eval(theEnv);
JSValue lV = theEnv.theStack.pop();
JSValue lV = left.eval(theEnv);
JSString id;
if (right instanceof JSIdentifier)
theEnv.theStack.push((JSValue)right);
id = (JSString)right;
else
right.eval(theEnv);
theEnv.theStack.push(lV);
id = right.eval(theEnv).toJSString(theEnv);
return new JSReference(lV, id);
}
else
throw new RuntimeException("bad lValue operator " + op);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.eval(theEnv);
JSValue lV = theEnv.theStack.pop();
right.eval(theEnv);
JSValue lV = left.eval(theEnv);
JSValue rV = right.eval(theEnv);
if (op == ".")
lV.getProp(theEnv);
else
return lV.getProp(theEnv, rV.toJSString(theEnv));
else {
System.out.println("missing binary op " + op);
return null;
}
}

View File

@ -5,31 +5,32 @@ class BitwiseNode extends BinaryNode {
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.eval(theEnv);
JSInteger lV = theEnv.theStack.pop().toJSInteger(theEnv);
right.eval(theEnv);
JSInteger lV = left.eval(theEnv).toJSInteger(theEnv);
JSValue rV = right.eval(theEnv);
if (op == "&")
lV.and(theEnv);
return lV.and(theEnv, rV);
else
if (op == "|")
lV.or(theEnv);
return lV.or(theEnv, rV);
else
if (op == "^")
lV.xor(theEnv);
return lV.xor(theEnv, rV);
else
if (op == "<<")
lV.shr(theEnv);
return lV.shr(theEnv, rV);
else
if (op == ">>")
lV.shl(theEnv);
return lV.shl(theEnv, rV);
else
if (op == ">>>")
lV.ushl(theEnv);
else
return lV.ushl(theEnv, rV);
else {
System.out.println("missing bitwise op " + op);
return null;
}
}
}

View File

@ -26,12 +26,11 @@ class ConditionalNode extends ControlNode {
ControlNode eval(Environment theEnv)
{
ControlNode n = super.eval(theEnv);
JSBoolean b = theEnv.theStack.pop().toJSBoolean(theEnv);
JSBoolean b = expr.eval(theEnv).toJSBoolean(theEnv);
if (b.isTrue())
return trueCode;
else
return n;
return next;
}
String print()

View File

@ -3,14 +3,12 @@ import java.util.Hashtable;
class Environment {
JSStack theStack = new JSStack();
JSObject scope = new JSObject("globals");
String print()
{
StringBuffer result = new StringBuffer("Globals contents :\n");
result.append(scope.toString());
result.append("\nStack Top = " + theStack.size());
return result.toString();
}

View File

@ -9,14 +9,16 @@ class ExpressionNode {
return indent + "ExpressionNode(" + getClass().toString() + ")\n";
}
void evalLHS(Environment theEnv)
JSReference evalLHS(Environment theEnv)
{
System.out.println("Unimplemented evalLHS for " + print(""));
return null;
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
System.out.println("Unimplemented eval for " + print(""));
return null;
}
}

View File

@ -8,9 +8,9 @@ class JSBoolean extends JSValue {
b = p;
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
return this;
}
boolean isTrue()
@ -23,12 +23,12 @@ class JSBoolean extends JSValue {
return !b;
}
void bang(Environment theEnv) {
theEnv.theStack.push((b) ? JSFalse : JSTrue);
JSValue bang(Environment theEnv) {
return (b) ? JSFalse : JSTrue;
}
void typeof(Environment theEnv) {
theEnv.theStack.push(new JSString("boolean"));
JSValue typeof(Environment theEnv) {
return new JSString("boolean");
}
JSBoolean toJSBoolean(Environment theEnv) {

View File

@ -20,77 +20,64 @@ class JSDouble extends JSNumber {
return Double.toString(d);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
return this;
}
void plus(Environment theEnv) {
theEnv.theStack.push(this);
JSValue plus(Environment theEnv) {
return this;
}
void minus(Environment theEnv) {
theEnv.theStack.push(new JSDouble(-d));
JSValue minus(Environment theEnv) {
return new JSDouble(-d);
}
void add(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString)
toJSString(theEnv).add(theEnv);
else {
theEnv.theStack.pop();
theEnv.theStack.push(new JSDouble(d + vR.toJSDouble(theEnv).d));
}
JSValue add(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return toJSString(theEnv).add(theEnv, rV);
else
return new JSDouble(d + rV.toJSDouble(theEnv).d);
}
void subtract(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSDouble(d - vR.toJSDouble(theEnv).d));
JSValue subtract(Environment theEnv, JSValue rV) {
return new JSDouble(d - rV.toJSDouble(theEnv).d);
}
void multiply(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSDouble(d * vR.toJSDouble(theEnv).d));
JSValue multiply(Environment theEnv, JSValue rV) {
return new JSDouble(d * rV.toJSDouble(theEnv).d);
}
void divide(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSDouble(d / vR.toJSDouble(theEnv).d));
JSValue divide(Environment theEnv, JSValue rV) {
return new JSDouble(d / rV.toJSDouble(theEnv).d);
}
void remainder(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSDouble(d % vR.toJSDouble(theEnv).d));
JSValue remainder(Environment theEnv, JSValue rV) {
return new JSDouble(d % rV.toJSDouble(theEnv).d);
}
void gt(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d > vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue gt(Environment theEnv, JSValue rV) {
return (d > rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
void ge(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d >= vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue ge(Environment theEnv, JSValue rV) {
return (d >= rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
void lt(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d < vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue lt(Environment theEnv, JSValue rV) {
return (d < rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
void le(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d <= vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue le(Environment theEnv, JSValue rV) {
return (d <= rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
void eq(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d == vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue eq(Environment theEnv, JSValue rV) {
return (d == rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
void ne(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push((d != vR.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
JSValue ne(Environment theEnv, JSValue rV) {
return (d != rV.toJSDouble(theEnv).d) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
}
JSDouble toJSDouble(Environment theEnv) {

View File

@ -10,16 +10,14 @@ class JSIdentifier extends JSString {
return indent + "JSIdentifier : " + s + "\n";
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
theEnv.scope.getProp(theEnv);
return theEnv.scope.getProp(theEnv, this);
}
void evalLHS(Environment theEnv)
JSReference evalLHS(Environment theEnv)
{
theEnv.theStack.push(this);
theEnv.theStack.push(theEnv.scope);
return new JSReference(theEnv.scope, this);
}
}

View File

@ -10,9 +10,9 @@ class JSInteger extends JSNumber {
i = p;
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
return this;
}
JSBoolean toJSBoolean(Environment theEnv) {
@ -35,38 +35,32 @@ class JSInteger extends JSNumber {
return new JSString(Integer.toString(i));
}
void twiddle(Environment theEnv) {
theEnv.theStack.push(new JSInteger(~i));
JSValue twiddle(Environment theEnv) {
return new JSInteger(~i);
}
void and(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i & vR.toJSInteger(theEnv).i));
JSValue and(Environment theEnv, JSValue rV) {
return new JSInteger(i & rV.toJSInteger(theEnv).i);
}
void or(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i | vR.toJSInteger(theEnv).i));
JSValue or(Environment theEnv, JSValue rV) {
return new JSInteger(i | rV.toJSInteger(theEnv).i);
}
void xor(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i ^ vR.toJSInteger(theEnv).i));
JSValue xor(Environment theEnv, JSValue rV) {
return new JSInteger(i ^ rV.toJSInteger(theEnv).i);
}
void shl(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i >> vR.toJSInteger(theEnv).i));
JSValue shl(Environment theEnv, JSValue rV) {
return new JSInteger(i >> rV.toJSInteger(theEnv).i);
}
void shr(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i << vR.toJSInteger(theEnv).i));
JSValue shr(Environment theEnv, JSValue rV) {
return new JSInteger(i << rV.toJSInteger(theEnv).i);
}
void ushl(Environment theEnv) {
JSValue vR = theEnv.theStack.pop();
theEnv.theStack.push(new JSInteger(i >>> vR.toJSInteger(theEnv).i));
JSValue ushl(Environment theEnv, JSValue rV) {
return new JSInteger(i >>> rV.toJSInteger(theEnv).i);
}
int i;

View File

@ -1,7 +1,7 @@
abstract class JSNumber extends JSValue {
void typeof(Environment theEnv) {
theEnv.theStack.push(new JSString("number"));
JSValue typeof(Environment theEnv) {
return new JSString("number");
}

View File

@ -19,16 +19,16 @@ class JSObject extends JSValue {
return value + contents.toString();
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
return this;
}
void typeof(Environment theEnv) {
JSValue typeof(Environment theEnv) {
if (this == JSUndefined)
theEnv.theStack.push(new JSString("undefined"));
return new JSString("undefined");
else
theEnv.theStack.push(new JSString("object"));
return new JSString("object");
}
JSBoolean toJSBoolean(Environment theEnv) {
@ -39,16 +39,13 @@ class JSObject extends JSValue {
return toPrimitive(theEnv, "Number").toJSDouble(theEnv);
}
void getProp(Environment theEnv) {
JSString id = theEnv.theStack.pop().toJSString(theEnv);
JSValue v = (JSValue)(contents.get(id.s));
theEnv.theStack.push(v);
JSValue getProp(Environment theEnv, JSString id) {
return (JSValue)(contents.get(id.s));
}
void putProp(Environment theEnv) {
JSValue v = theEnv.theStack.pop();
JSString id = theEnv.theStack.pop().toJSString(theEnv);
contents.put(id.s, v);
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
contents.put(id.s, rV);
return rV;
}

View File

@ -0,0 +1,12 @@
class JSReference {
JSReference(JSValue aBase, JSString aID)
{
base = aBase;
id = aID;
}
JSValue base;
JSString id;
}

View File

@ -1,38 +0,0 @@
import java.util.Stack;
class JSStack {
Stack stack = new Stack();
void push(JSValue v)
{
stack.push(v);
}
boolean isEmpty()
{
return stack.isEmpty();
}
JSValue pop()
{
return (JSValue)stack.pop();
}
JSValue peek()
{
return (JSValue)stack.peek();
}
int size()
{
return stack.size();
}
void setStack(int top)
{
stack.setSize(top);
}
}

View File

@ -5,79 +5,60 @@ class JSString extends JSValue {
s = p;
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
theEnv.theStack.push(this);
return this;
}
void typeof(Environment theEnv) {
theEnv.theStack.push(new JSString("string"));
JSValue typeof(Environment theEnv) {
return new JSString("string");
}
void add(Environment theEnv)
JSValue add(Environment theEnv, JSValue rV)
{
JSString vR = theEnv.theStack.pop().toJSString(theEnv);
theEnv.theStack.push(new JSString(s + vR.s));
return new JSString(s + rV.toJSString(theEnv).s);
}
void gt(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) == 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue gt(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) == 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).gt(theEnv);
return toJSDouble(theEnv).gt(theEnv, rV);
}
void ge(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) != -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue ge(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) != -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).ge(theEnv);
return toJSDouble(theEnv).ge(theEnv, rV);
}
void lt(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) == -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue lt(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) == -1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).lt(theEnv);
return toJSDouble(theEnv).lt(theEnv, rV);
}
void le(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) != 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue le(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) != 1) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).le(theEnv);
return toJSDouble(theEnv).le(theEnv, rV);
}
void eq(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) == 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue eq(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) == 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).eq(theEnv);
return toJSDouble(theEnv).eq(theEnv, rV);
}
void ne(Environment theEnv) {
JSValue vR = theEnv.theStack.peek();
if (vR instanceof JSString) {
theEnv.theStack.pop();
theEnv.theStack.push((s.compareTo(vR.toJSString(theEnv).s) != 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse);
}
JSValue ne(Environment theEnv, JSValue rV) {
if (rV instanceof JSString)
return (s.compareTo(rV.toJSString(theEnv).s) != 0) ? JSBoolean.JSTrue : JSBoolean.JSFalse;
else
toJSDouble(theEnv).ne(theEnv);
return toJSDouble(theEnv).ne(theEnv, rV);
}
JSDouble toJSDouble(Environment theEnv) {

View File

@ -5,188 +5,150 @@ class JSValue extends ExpressionNode {
return indent + "JSValue\n";
}
void evalLHS(Environment theEnv)
JSReference evalLHS(Environment theEnv)
{
throw new RuntimeException("EvalLHS on non-lvalue");
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
throw new RuntimeException("Eval on JSValue");
}
void unimplemented(String op)
JSValue unimplemented(String op)
{
throw new RuntimeException("unimplemented " + op + " called");
}
void gt(Environment theEnv) {
JSValue gt(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.gt(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).gt(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.gt(theEnv, rV);
else
return lV.toJSDouble(theEnv).gt(theEnv, rV.toJSDouble(theEnv));
}
void ge(Environment theEnv) {
JSValue ge(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.ge(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).ge(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.ge(theEnv, rV);
else
return lV.toJSDouble(theEnv).ge(theEnv, rV.toJSDouble(theEnv));
}
void lt(Environment theEnv) {
JSValue lt(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.lt(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).lt(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.lt(theEnv, rV);
else
return lV.toJSDouble(theEnv).lt(theEnv, rV.toJSDouble(theEnv));
}
void le(Environment theEnv) {
JSValue le(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.le(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).le(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.le(theEnv, rV);
else
return lV.toJSDouble(theEnv).le(theEnv, rV.toJSDouble(theEnv));
}
void eq(Environment theEnv) {
JSValue eq(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.eq(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).eq(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.eq(theEnv, rV);
else
return lV.toJSDouble(theEnv).eq(theEnv, rV.toJSDouble(theEnv));
}
void ne(Environment theEnv) {
JSValue ne(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "Number");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.ne(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).ne(theEnv);
}
rV = rV.toPrimitive(theEnv, "Number");
if ((lV instanceof JSString) && (rV instanceof JSString))
return lV.ne(theEnv, rV);
else
return lV.toJSDouble(theEnv).ne(theEnv, rV.toJSDouble(theEnv));
}
void plus(Environment theEnv) {
toJSDouble(theEnv).plus(theEnv);
JSValue plus(Environment theEnv) {
return toJSDouble(theEnv).plus(theEnv);
}
void minus(Environment theEnv) {
toJSDouble(theEnv).minus(theEnv);
JSValue minus(Environment theEnv) {
return toJSDouble(theEnv).minus(theEnv);
}
void twiddle(Environment theEnv) {
toJSInteger(theEnv).twiddle(theEnv);
JSValue twiddle(Environment theEnv) {
return toJSInteger(theEnv).twiddle(theEnv);
}
void bang(Environment theEnv) {
toJSBoolean(theEnv).bang(theEnv);
JSValue bang(Environment theEnv) {
return toJSBoolean(theEnv).bang(theEnv);
}
void typeof(Environment theEnv) {
unimplemented("typeof");
JSValue typeof(Environment theEnv) {
return unimplemented("typeof");
}
void add(Environment theEnv) {
JSValue add(Environment theEnv, JSValue rV) {
JSValue lV = toPrimitive(theEnv, "");
JSValue rV = theEnv.theStack.pop().toPrimitive(theEnv, "");
if ((lV instanceof JSString) || (rV instanceof JSString)) {
theEnv.theStack.push(rV);
lV.ne(theEnv);
}
else {
theEnv.theStack.push(rV.toJSDouble(theEnv));
lV.toJSDouble(theEnv).add(theEnv);
}
rV = rV.toPrimitive(theEnv, "");
if ((lV instanceof JSString) || (rV instanceof JSString))
return lV.add(theEnv, rV);
else
return lV.toJSDouble(theEnv).add(theEnv, rV);
}
void subtract(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSDouble(theEnv));
toJSDouble(theEnv).subtract(theEnv);
JSValue subtract(Environment theEnv, JSValue rV) {
return toJSDouble(theEnv).subtract(theEnv, rV.toJSDouble(theEnv));
}
void multiply(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSDouble(theEnv));
toJSDouble(theEnv).multiply(theEnv);
JSValue multiply(Environment theEnv, JSValue rV) {
return toJSDouble(theEnv).multiply(theEnv, rV.toJSDouble(theEnv));
}
void divide(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSDouble(theEnv));
toJSDouble(theEnv).divide(theEnv);
JSValue divide(Environment theEnv, JSValue rV) {
return toJSDouble(theEnv).divide(theEnv, rV.toJSDouble(theEnv));
}
void remainder(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSDouble(theEnv));
toJSDouble(theEnv).remainder(theEnv);
JSValue remainder(Environment theEnv, JSValue rV) {
return toJSDouble(theEnv).remainder(theEnv, rV.toJSDouble(theEnv));
}
void and(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).and(theEnv);
JSValue and(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).and(theEnv, rV.toJSInteger(theEnv));
}
void or(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).or(theEnv);
JSValue or(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).or(theEnv, rV.toJSInteger(theEnv));
}
void xor(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).xor(theEnv);
JSValue xor(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).xor(theEnv, rV.toJSInteger(theEnv));
}
void shl(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).shl(theEnv);
JSValue shl(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).shl(theEnv, rV.toJSInteger(theEnv));
}
void shr(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).shr(theEnv);
JSValue shr(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).shr(theEnv, rV.toJSInteger(theEnv));
}
void ushl(Environment theEnv) {
theEnv.theStack.push(theEnv.theStack.pop().toJSInteger(theEnv));
toJSInteger(theEnv).ushl(theEnv);
JSValue ushl(Environment theEnv, JSValue rV) {
return toJSInteger(theEnv).ushl(theEnv, rV.toJSInteger(theEnv));
}
void getProp(Environment theEnv) {
toJSObject(theEnv).getProp(theEnv);
JSValue getProp(Environment theEnv, JSString id) {
return toJSObject(theEnv).getProp(theEnv, id);
}
void putProp(Environment theEnv) {
toJSObject(theEnv).putProp(theEnv);
JSValue putProp(Environment theEnv, JSString id, JSValue rV) {
return toJSObject(theEnv).putProp(theEnv, id, rV);
}
JSValue defaultValue(Environment theEnv, String hint) {
@ -204,16 +166,12 @@ When the [[DefaultValue]] method of O is called with hint String, the following
*/
JSValue v = null;
if (hint.equals("String")) {
theEnv.theStack.push(new JSString("toString"));
getProp(theEnv);
v = theEnv.theStack.pop();
v = getProp(theEnv, new JSString("toString"));
if (v instanceof JSObject) {
// invoke 'v.Call' with 'this' as the JS this
}
else {
theEnv.theStack.push(new JSString("valueOf"));
getProp(theEnv);
v = theEnv.theStack.pop();
v = getProp(theEnv, new JSString("valueOf"));
if (v instanceof JSObject) {
}
else

View File

@ -5,36 +5,35 @@ class LogicalNode extends BinaryNode {
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.eval(theEnv);
JSBoolean b = theEnv.theStack.pop().toJSBoolean(theEnv);
JSBoolean b = left.eval(theEnv).toJSBoolean(theEnv);
if (op == "&&") {
if (b.isFalse())
theEnv.theStack.push(b);
return b;
else {
right.eval(theEnv);
b = theEnv.theStack.pop().toJSBoolean(theEnv);
b = right.eval(theEnv).toJSBoolean(theEnv);
if (b.isFalse())
theEnv.theStack.push(b);
return b;
else
theEnv.theStack.push(JSBoolean.JSTrue);
return JSBoolean.JSTrue;
}
}
if (op == "||") {
if (b.isTrue())
theEnv.theStack.push(b);
return b;
else {
right.eval(theEnv);
b = theEnv.theStack.pop().toJSBoolean(theEnv);
b = right.eval(theEnv).toJSBoolean(theEnv);
if (b.isTrue())
theEnv.theStack.push(b);
return b;
else
theEnv.theStack.push(JSBoolean.JSFalse);
return JSBoolean.JSFalse;
}
}
else
else {
System.out.println("missing logical op " + op);
return null;
}
}
}

View File

@ -5,30 +5,31 @@ class RelationalNode extends BinaryNode {
super(aOp, aLeft, aRight);
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
left.eval(theEnv);
JSValue lV = theEnv.theStack.pop();
right.eval(theEnv);
JSValue lV = left.eval(theEnv);
JSValue rV = right.eval(theEnv);
if (op == ">")
lV.gt(theEnv);
return lV.gt(theEnv, rV);
else
if (op == ">=")
lV.ge(theEnv);
return lV.ge(theEnv, rV);
else
if (op == "<")
lV.lt(theEnv);
return lV.lt(theEnv, rV);
else
if (op == "<=")
lV.le(theEnv);
return lV.le(theEnv, rV);
else
if (op == "==")
lV.eq(theEnv);
return lV.eq(theEnv, rV);
else
if (op == "!=")
lV.ne(theEnv);
else
return lV.ne(theEnv, rV);
else {
System.out.println("missing relational op");
return null;
}
}
}

View File

@ -21,20 +21,18 @@ class SwitchNode extends ControlNode {
ControlNode eval(Environment theEnv)
{
ControlNode n = super.eval(theEnv);
JSValue v = theEnv.theStack.pop();
JSValue v = expr.eval(theEnv);
int count = caseExpr.size();
for (int i = 0; i < count; i++) {
ExpressionNode e = (ExpressionNode)(caseExpr.elementAt(i));
e.eval(theEnv);
v.eq(theEnv);
if (theEnv.theStack.pop().toJSBoolean(theEnv).isTrue())
JSBoolean b = v.eq(theEnv, e.eval(theEnv)).toJSBoolean(theEnv);
if (b.isTrue())
return (ControlNode)(caseCode.elementAt(i));
}
if (defaultCode != null)
return defaultCode;
else
return n;
return next;
}
Vector caseExpr = new Vector();

View File

@ -7,8 +7,7 @@ class ThrowNode extends ControlNode {
ControlNode eval(Environment theEnv)
{
ControlNode n = super.eval(theEnv);
throw new JSException(theEnv.theStack.pop());
throw new JSException(expr.eval(theEnv));
}
}

View File

@ -22,7 +22,6 @@ class TryNode extends ControlNode {
ControlNode eval(Environment theEnv)
{
int stackHeight = theEnv.theStack.size();
try {
ControlNode c = tryBody;
while (c != null) c = c.eval(theEnv);
@ -32,7 +31,6 @@ class TryNode extends ControlNode {
for (int i = 0; i < count; i++) {
ExpressionNode e = (ExpressionNode)(catchExpr.elementAt(i));
String id = ((JSObject)e).value;
theEnv.theStack.setStack(stackHeight);
theEnv.scope.contents.put(id, x.getValue()); // XXX YAARGH !!!
return (ControlNode)(catchCode.elementAt(i));
}

View File

@ -22,27 +22,28 @@ class UnaryNode extends ExpressionNode {
return result.toString();
}
void eval(Environment theEnv)
JSValue eval(Environment theEnv)
{
child.eval(theEnv);
JSValue cV = theEnv.theStack.pop();
JSValue cV = child.eval(theEnv);
if (op == "+")
cV.plus(theEnv);
return cV.plus(theEnv);
else
if (op == "-")
cV.minus(theEnv);
return cV.minus(theEnv);
else
if (op == "~")
cV.twiddle(theEnv);
return cV.twiddle(theEnv);
else
if (op == "!")
cV.bang(theEnv);
return cV.bang(theEnv);
else
if (op == "typeof")
cV.typeof(theEnv);
else
return cV.typeof(theEnv);
else {
System.out.println("missing unary op " + op);
return null;
}
}
String getOperator()