package org.dynjs.parser.ast;
import org.dynjs.parser.CodeVisitor;
import org.dynjs.runtime.ExecutionContext;
import org.dynjs.runtime.Types;
import org.dynjs.runtime.linker.DynJSBootstrapper;
import java.lang.invoke.CallSite;
public class BitwiseExpression extends AbstractBinaryExpression {
public BitwiseExpression(Expression lhs, Expression rhs, String op) {
super(lhs, rhs, op);
}
@Override
public Object accept(Object context, CodeVisitor visitor, boolean strict) {
return visitor.visit( context, this, strict );
}
@Override
public Object interpret(ExecutionContext context, boolean debug) {
Object lhs = getValue(this.lhsGet, context, getLhs().interpret(context, debug));
Long lhsNum = null;
if (getOp().equals(">>>")) {
lhsNum = Types.toUint32(context, lhs);
} else {
lhsNum = Types.toInt32(context, lhs);
}
Object value = getRhs().interpret(context, debug);
if (getOp().equals("<<")) {
// 11.7.1
Long rhsNum = Types.toUint32(context, getValue(this.rhsGet, context, value));
int shiftCount = rhsNum.intValue() & 0x1F;
return((int) (lhsNum.longValue() << shiftCount));
} else if (getOp().equals(">>")) {
// 11.7.2
Long rhsNum = Types.toUint32(context, getValue(this.rhsGet, context, value));
int shiftCount = rhsNum.intValue() & 0x1F;
return((int) (lhsNum.longValue() >> shiftCount));
} else if (getOp().equals(">>>")) {
// 11.7.3
Long rhsNum = Types.toUint32(context, getValue(this.rhsGet, context, value));
int shiftCount = rhsNum.intValue() & 0x1F;
return(lhsNum.longValue() >>> shiftCount);
} else if (getOp().equals("&")) {
Long rhsNum = Types.toInt32(context, getValue(this.rhsGet, context, value));
return(lhsNum.longValue() & rhsNum.longValue());
} else if (getOp().equals("|")) {
Long rhsNum = Types.toInt32(context, getValue(this.rhsGet, context, value));
return(lhsNum.longValue() | rhsNum.longValue());
} else if (getOp().equals("^")) {
Long rhsNum = Types.toInt32(context, getValue(this.rhsGet, context, value));
return(lhsNum.longValue() ^ rhsNum.longValue());
}
return null; // not reached
}
}