package org.dynjs.parser.ast; import org.dynjs.exception.ThrowException; import org.dynjs.parser.CodeVisitor; import org.dynjs.runtime.ExecutionContext; import org.dynjs.runtime.Reference; import org.dynjs.runtime.Types; import org.dynjs.runtime.linker.DynJSBootstrapper; import java.lang.invoke.CallSite; public class AdditiveExpression extends AbstractBinaryExpression { public AdditiveExpression(final Expression lhs, final Expression rhs, final String op) { super(lhs, rhs, op); } public Object accept(Object context, CodeVisitor visitor, boolean strict) { return visitor.visit( context, this, strict); } @Override public Object interpret(ExecutionContext context, boolean debug) { if ( this.getOp().equals( "+" ) ) { Object lhs = Types.toPrimitive(context, getValue(this.lhsGet, context, getLhs().interpret(context, debug))); Object rhs = Types.toPrimitive(context, getValue(this.rhsGet, context, getRhs().interpret(context, debug))); if (lhs instanceof String || rhs instanceof String) { return(Types.toString(context, lhs) + Types.toString(context, rhs)); } Number lhsNum = Types.toNumber(context, lhs); Number rhsNum = Types.toNumber(context, rhs); if (Double.isNaN(lhsNum.doubleValue()) || Double.isNaN(rhsNum.doubleValue())) { return(Double.NaN); } if (lhsNum instanceof Double || rhsNum instanceof Double) { if (lhsNum.doubleValue() == 0.0 && rhsNum.doubleValue() == 0.0) { if (Double.compare(lhsNum.doubleValue(), 0.0) < 0 && Double.compare(rhsNum.doubleValue(), 0.0) < 0) { return(-0.0); } else { return(0.0); } } return(lhsNum.doubleValue() + rhsNum.doubleValue()); } return(lhsNum.longValue() + rhsNum.longValue()); } else { Number lhs = Types.toNumber(context, getValue(this.lhsGet, context, getLhs().interpret(context, debug))); Number rhs = Types.toNumber(context, getValue(this.rhsGet, context, getRhs().interpret(context, debug))); if (Double.isNaN(lhs.doubleValue()) || Double.isNaN(rhs.doubleValue())) { return(Double.NaN); } if (lhs instanceof Double || rhs instanceof Double) { if (lhs.doubleValue() == 0.0 && rhs.doubleValue() == 0.0) { if (Double.compare(lhs.doubleValue(), 0.0) < 0 && Double.compare(rhs.doubleValue(), 0.0) < 0) { return(+0.0); } } return(lhs.doubleValue() - rhs.doubleValue()); } return(lhs.longValue() - rhs.longValue()); } } }