31 #include "xml/dom_nodeimpl.h" 
   32 #include "xml/dom_nodelistimpl.h" 
   33 #include "kjs/operations.h" 
   34 #include "kjs/value.h" 
   39 using namespace khtml;
 
   40 using namespace khtml::XPath;
 
   42 Number::Number( 
double value )
 
   57 Value Number::doEvaluate()
 const 
   59     return Value( m_value );
 
   74     return "<string>" + m_value.
string() + 
"</string>";
 
   77 Value String::doEvaluate()
 const 
   79     return Value( m_value );
 
   82 Value Negative::doEvaluate()
 const 
   85     return Value( -p.toNumber() );
 
   90     return "<negative>" + 
subExpr( 0 )->
dump() + 
"</number>";
 
   96     s += 
"<operand>" + 
subExpr( 0 )->
dump() + 
"</operand>";
 
   97     s += 
"<operand>" + 
subExpr( 1 )->
dump() + 
"</operand>";
 
   98     s += 
"</" + 
opName() + 
">";
 
  109 Value NumericOp::doEvaluate()
 const 
  113     double leftVal = lhs.toNumber(), rightVal = rhs.toNumber();
 
  117             return Value( leftVal + rightVal );
 
  119             return Value( leftVal - rightVal );
 
  121             return Value( leftVal * rightVal );
 
  123             if ( rightVal == 0.0 || rightVal == -0.0 ) {
 
  124                 if ( leftVal == 0.0 || leftVal == -0.0) {
 
  128                     if (signbit(leftVal) == signbit(rightVal))
 
  129                         return Value( KJS::Inf );
 
  131                         return Value( -KJS::Inf );
 
  134                 return Value( leftVal / rightVal );
 
  137             if ( rightVal == 0.0 || rightVal == -0.0 )
 
  140                 return Value( remainder( leftVal, rightVal ) );
 
  147 QString NumericOp::opName()
 const 
  181         for (
unsigned long i = 0; i < set->length(); ++i) {
 
  183             out->append(stringVal);
 
  196         for (
unsigned long i = 0; i < set->length(); ++i) {
 
  198             out->append(
Value(stringVal).toNumber());
 
  203 Value RelationOp::doEvaluate()
 const 
  208     if (lhs.isNodeset() || rhs.isNodeset())
 
  212         if ((lhs.isNodeset() && rhs.isNodeset()) ||
 
  213             (lhs.isString()  || rhs.isString())) {
 
  215             WTF::Vector<DOM::DOMString> leftStrings;
 
  216             WTF::Vector<DOM::DOMString> rightStrings;
 
  221             for (
unsigned pl = 0; pl < leftStrings.size(); ++pl) {
 
  222                 for (
unsigned pr = 0; pr < rightStrings.size(); ++pr) {
 
  223                     if (compareStrings(leftStrings[pl], rightStrings[pr]))
 
  231         if (lhs.isNumber() || rhs.isNumber()) {
 
  232             WTF::Vector<double> leftNums;
 
  233             WTF::Vector<double> rightNums;
 
  238             for (
unsigned pl = 0; pl < leftNums.size(); ++pl) {
 
  239                 for (
unsigned pr = 0; pr < rightNums.size(); ++pr) {
 
  240                     if (compareNumbers(leftNums[pl], rightNums[pr]))
 
  249         assert(lhs.isBoolean() || rhs.isBoolean());
 
  252             lhs = 
Value(lhs.toBoolean());
 
  254             rhs = 
Value(rhs.toBoolean());
 
  260         if ( lhs.isBoolean() || rhs.isBoolean() ) {
 
  261             equal = ( lhs.toBoolean() == rhs.toBoolean() );
 
  262         } 
else if ( lhs.isNumber() || rhs.isNumber() ) {
 
  263             equal = ( lhs.toNumber() == rhs.toNumber() );
 
  265             equal = ( lhs.toString() == rhs.toString() );
 
  268         if ( opCode == 
OP_EQ )
 
  269             return Value( equal );
 
  271             return Value( !equal );
 
  276     double leftVal = lhs.toNumber(), rightVal = rhs.toNumber();
 
  277     return Value(compareNumbers(leftVal, rightVal));
 
  281 bool RelationOp::compareNumbers(
double leftVal, 
double rightVal)
 const 
  285             return leftVal > rightVal;
 
  287             return leftVal >= rightVal;
 
  289             return leftVal < rightVal;
 
  291             return leftVal <= rightVal;
 
  293             return leftVal == rightVal;
 
  295             return leftVal != rightVal;
 
  311     return compareNumbers(
Value(l).toNumber(), 
Value(r).toNumber());
 
  314 QString RelationOp::opName()
 const 
  342 bool LogicalOp::shortCircuitOn()
 const 
  356 QString LogicalOp::opName()
 const 
  364 Value LogicalOp::doEvaluate()
 const 
  370     bool lhsBool = lhs.toBoolean();
 
  371     if ( lhsBool == shortCircuitOn() ) {
 
  372         return Value( lhsBool );
 
  383 Value Union::doEvaluate()
 const 
  388         kWarning(6011) << 
"Union operator '|' works only with nodesets.";
 
  390         return Value( 
new StaticNodeListImpl );
 
  397     for ( 
unsigned long n = 0; n < lhsNodes->length(); ++n )
 
  398         result->append( lhsNodes->item( n ) );
 
  400     for ( 
unsigned long n = 0; n < rhsNodes->length(); ++n )
 
  401         result->append( rhsNodes->item( n ) );
 
  403     return Value( result );
 
  418     Q_ASSERT( m_expr != 0 );
 
  423     if ( result.isNumber() ) {
 
  427     return result.toBoolean();
 
  437     return QString() + 
"<predicate>" + m_expr->
dump() + 
"</predicate>";
 
DOM::DOMString toString() const 
void addSubExpression(Expression *expr)
String(const DOM::DOMString &value)
virtual bool isConstant() const 
SharedPtr< DOM::StaticNodeListImpl > DomNodeList
virtual QString dump() const 
virtual QString dump() const =0
QString number(int n, int base)
static void numify(const Value &val, WTF::Vector< double > *out)
virtual QString opName() const =0
static EvaluationContext & evaluationContext()
RelationOp(int opCode, Expression *lhs, Expression *rhs)
static void reportInvalidExpressionErr()
DOMString stringValue(NodeImpl *node)
This class implements the basic string we use in the DOM. 
LogicalOp(int opCode, Expression *lhs, Expression *rhs)
virtual Value evaluate() const 
virtual QString dump() const 
Predicate(Expression *expr)
virtual bool isConstant() const 
NumericOp(int opCode, Expression *lhs, Expression *rhs)
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Expression * subExpr(unsigned int i)
static void stringify(const Value &val, WTF::Vector< DOMString > *out)
virtual QString dump() const 
virtual QString dump() const 
DomNodeList & toNodeset()