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 )
54 return "<number>" + QString::number( m_value ) +
"</number>";
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
151 return QLatin1String(
"addition" );
153 return QLatin1String(
"subtraction" );
155 return QLatin1String(
"multiplication" );
157 return QLatin1String(
"division" );
159 return QLatin1String(
"modulo" );
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
318 return QLatin1String(
"relationGT" );
320 return QLatin1String(
"relationGE" );
322 return QLatin1String(
"relationLT" );
324 return QLatin1String(
"relationLE" );
326 return QLatin1String(
"relationEQ" );
328 return QLatin1String(
"relationNE" );
342 bool LogicalOp::shortCircuitOn()
const
356 QString LogicalOp::opName()
const
359 return QLatin1String(
"conjunction" );
361 return QLatin1String(
"disjunction" );
364 Value LogicalOp::doEvaluate()
const
370 bool lhsBool = lhs.toBoolean();
371 if ( lhsBool == shortCircuitOn() ) {
372 return Value( lhsBool );
380 return QLatin1String(
"union");
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
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()