lib Library API Documentation

koscript_eval.cc

00001 /* This file is part of the KDE project 00002 Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "koscript_eval.h" 00021 #include "koscript_value.h" 00022 #include "koscript_context.h" 00023 #include "koscript_func.h" 00024 #include "koscript_struct.h" 00025 #include "koscript.h" 00026 #include "koscript_parsenode.h" 00027 #include "koscript_util.h" 00028 #include "koscript_property.h" 00029 #include "koscript_method.h" 00030 #include <kdebug.h> 00031 #include <stdio.h> 00032 #include <math.h> 00033 00034 #include <kregexp.h> 00035 00036 #include <qfileinfo.h> 00037 #include <klocale.h> 00038 00039 // Get a left and right operand for arithmetic 00040 // operations like add, mul, div etc. If leftexpr 00041 // is true, then the left value must be assignable. 00042 #define EVAL_OPS( ctx, l, r, leftexpr ) \ 00043 KSParseNode *left = node->branch1(); \ 00044 KSParseNode *right = node->branch2(); \ 00045 if ( !left || !right ) \ 00046 return false; \ 00047 \ 00048 KSContext l( ctx, leftexpr ); \ 00049 KSContext r( ctx ); \ 00050 if ( !left->eval( l ) ) \ 00051 { \ 00052 ctx.setException( l ); \ 00053 return false; \ 00054 } \ 00055 if ( !right->eval( r ) ) \ 00056 { \ 00057 ctx.setException( r ); \ 00058 return false; \ 00059 } 00060 00061 #define EVAL_LEFT_OP( ctx, l ) \ 00062 KSParseNode *left = node->branch1(); \ 00063 if ( !left ) \ 00064 return false; \ 00065 \ 00066 KSContext l( ctx ); \ 00067 if ( !left->eval( l ) ) \ 00068 { \ 00069 ctx.setException( l ); \ 00070 return false; \ 00071 } \ 00072 00073 #define EVAL_RIGHT_OP( ctx, r ) \ 00074 KSParseNode *right = node->branch2(); \ 00075 if ( !right ) \ 00076 return false; \ 00077 \ 00078 KSContext r( ctx ); \ 00079 if ( !right->eval( r ) ) \ 00080 { \ 00081 ctx.setException( r ); \ 00082 return false; \ 00083 } \ 00084 00085 // Try to reuse one of the KSValue objects l or r 00086 // and assign it to ctx. This is faster than the default 00087 // behaviour of creating a new KSValue object all the time. 00088 #define FILL_VALUE( ctx, l, r ) \ 00089 if ( l.value()->mode() == KSValue::Temp ) \ 00090 ctx.setValue( l.shareValue() ); \ 00091 else if ( r.value()->mode() == KSValue::Temp ) \ 00092 ctx.setValue( r.shareValue() ); \ 00093 else \ 00094 ctx.setValue( new KSValue ); 00095 00096 bool KSEval_definitions( KSParseNode* node, KSContext& context ) 00097 { 00098 if ( node->branch1() ) 00099 { 00100 if ( node->branch1()->getType() == func_dcl ) 00101 { 00102 Q_ASSERT( context.scope() ); 00103 context.scope()->addObject( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) ); 00104 } 00105 else if ( !node->branch1()->eval( context ) ) 00106 return false; 00107 } 00108 if ( node->branch2() ) 00109 { 00110 if ( node->branch2()->getType() == func_dcl ) 00111 { 00112 Q_ASSERT( context.scope() ); 00113 context.scope()->addObject( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) ); 00114 } 00115 else if ( !node->branch2()->eval( context ) ) 00116 return false; 00117 } 00118 00119 return true; 00120 } 00121 00122 bool KSEval_exports( KSParseNode* node, KSContext& context ) 00123 { 00124 Q_ASSERT( context.value() ); 00125 00126 if ( context.value()->type() == KSValue::StructClassType ) 00127 { 00128 if ( node->branch1() ) 00129 { 00130 if ( node->branch1()->getType() == func_dcl ) 00131 context.value()->structClassValue()->nameSpace()->insert( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) ); 00132 else if ( !node->branch1()->eval( context ) ) 00133 return false; 00134 } 00135 if ( node->branch2() ) 00136 { 00137 if ( node->branch2()->getType() == func_dcl ) 00138 context.value()->structClassValue()->nameSpace()->insert( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) ); 00139 else if ( !node->branch2()->eval( context ) ) 00140 return false; 00141 } 00142 } 00143 else 00144 Q_ASSERT( 0 ); 00145 00146 return true; 00147 } 00148 00149 bool KSEval_t_vertical_line( KSParseNode* node, KSContext& context ) 00150 { 00151 EVAL_OPS( context, l, r, false ); 00152 00153 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) || 00154 !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00155 { 00156 context.exception()->addLine( node->getLineNo() ); 00157 return false; 00158 } 00159 00160 context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() | r.value()->intValue() ) ) ); 00161 00162 return true; 00163 } 00164 00165 bool KSEval_t_circumflex( KSParseNode* node, KSContext& context ) 00166 { 00167 EVAL_OPS( context, l, r, false ); 00168 00169 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) || 00170 !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00171 { 00172 context.exception()->addLine( node->getLineNo() ); 00173 return false; 00174 } 00175 00176 context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() ^ r.value()->intValue() ) ) ); 00177 00178 return true; 00179 } 00180 00181 bool KSEval_t_ampersand( KSParseNode* node, KSContext& context ) 00182 { 00183 EVAL_OPS( context, l, r, false ); 00184 00185 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) || 00186 !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00187 { 00188 context.exception()->addLine( node->getLineNo() ); 00189 return false; 00190 } 00191 00192 context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() & r.value()->intValue() ) ) ); 00193 00194 return true; 00195 } 00196 00197 bool KSEval_t_shiftright( KSParseNode* node, KSContext& context ) 00198 { 00199 EVAL_OPS( context, l, r, false ); 00200 00201 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) || 00202 !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00203 { 00204 context.exception()->addLine( node->getLineNo() ); 00205 return false; 00206 } 00207 00208 context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() >> r.value()->intValue() ) ) ); 00209 00210 return true; 00211 } 00212 00213 bool KSEval_t_shiftleft( KSParseNode* node, KSContext& context ) 00214 { 00215 EVAL_OPS( context, l, r, false ); 00216 00217 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) || 00218 !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00219 { 00220 context.exception()->addLine( node->getLineNo() ); 00221 return false; 00222 } 00223 00224 context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() << r.value()->intValue() ) ) ); 00225 00226 return true; 00227 } 00228 00229 bool KSEval_t_plus_sign( KSParseNode* node, KSContext& context ) 00230 { 00231 // Unary ? 00232 if ( node->branch1() && !node->branch2() ) 00233 { 00234 if ( !node->branch1()->eval( context ) ) 00235 return false; 00236 00237 /* this operator is valid on numeric types so if it casts to a double it's ok. 00238 I'm not sure if there is possible data loss converting from int to double 00239 so avoid casting to double in that case just to be safe. 00240 */ 00241 if ( context.value()->type() == KSValue::IntType || 00242 context.value()->cast( KSValue::DoubleType) ) 00243 { 00244 return true; 00245 } 00246 00247 QString tmp( i18n("Unary Operator + not defined for type %1") ); 00248 context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) ); 00249 return false; 00250 } 00251 00252 // Binary operator 00253 EVAL_OPS( context, l, r, false ); 00254 00255 00256 //allows 5+date or 5+time 00257 //before you can just make time+5 and date +5 00258 if ( r.value()->type() == KSValue::TimeType ) 00259 { 00260 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ) 00261 return false; 00262 QTime t = r.value()->timeValue(); 00263 t = t.addSecs( l.value()->intValue() ); 00264 FILL_VALUE( context, l, r ); 00265 context.value()->setValue( t ); 00266 return TRUE; 00267 } 00268 else if ( r.value()->type() == KSValue::DateType ) 00269 { 00270 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ) 00271 return false; 00272 QDate d = r.value()->dateValue(); 00273 d = d.addDays( l.value()->intValue() ); 00274 FILL_VALUE( context, l, r ); 00275 context.value()->setValue( d ); 00276 return TRUE; 00277 } 00278 00279 // allows addition of boolean value, such as True+False 00280 if ( r.value()->type() == KSValue::BoolType ) 00281 { 00282 r.value()->cast( KSValue::IntType ); 00283 } 00284 00285 if ( l.value()->type() == KSValue::TimeType ) 00286 { 00287 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00288 return false; 00289 QTime t = l.value()->timeValue(); 00290 t = t.addSecs( r.value()->intValue() ); 00291 FILL_VALUE( context, l, r ); 00292 context.value()->setValue( t ); 00293 return TRUE; 00294 } 00295 else if ( l.value()->type() == KSValue::DateType ) 00296 { 00297 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00298 return false; 00299 QDate d = l.value()->dateValue(); 00300 d = d.addDays( r.value()->intValue() ); 00301 FILL_VALUE( context, l, r ); 00302 context.value()->setValue( d ); 00303 return TRUE; 00304 } 00305 00306 // allows addition of boolean value, such as True+False 00307 if ( l.value()->type() == KSValue::BoolType ) 00308 { 00309 l.value()->cast( KSValue::IntType ); 00310 } 00311 00312 // If we have double and int, then always convert to double 00313 else if ( l.value()->type() == KSValue::DoubleType ) 00314 { 00315 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00316 return false; 00317 } 00318 else 00319 { 00320 if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 00321 return false; 00322 l.value()->cast( r.value()->type()); 00323 } 00324 00325 switch( l.value()->type() ) 00326 { 00327 case KSValue::IntType: 00328 { 00329 KScript::Long result = r.value()->intValue() + l.value()->intValue(); 00330 FILL_VALUE( context, l, r ); 00331 context.value()->setValue( result ); 00332 return true; 00333 } 00334 break; 00335 case KSValue::DoubleType: 00336 { 00337 KScript::Double result = l.value()->doubleValue() + r.value()->doubleValue(); 00338 FILL_VALUE( context, l, r ); 00339 context.value()->setValue( result ); 00340 return true; 00341 } 00342 case KSValue::StringType: 00343 { 00344 QString result = l.value()->stringValue() + r.value()->stringValue(); 00345 FILL_VALUE( context, l, r ); 00346 context.value()->setValue( result ); 00347 return true; 00348 } 00349 break; 00350 case KSValue::ListType: 00351 { 00352 QValueList<KSValue::Ptr> result = l.value()->listValue() + r.value()->listValue(); 00353 FILL_VALUE( context, l, r ); 00354 context.value()->setValue( result ); 00355 return true; 00356 } 00357 break; 00358 case KSValue::MapType: 00359 { 00360 QMap<QString,KSValue::Ptr> result = l.value()->mapValue(); 00361 QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin(); 00362 QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end(); 00363 for( ; it != end; ++it ) 00364 result.insert( it.key(), it.data() ); 00365 FILL_VALUE( context, l, r ); 00366 context.value()->setValue( result ); 00367 return true; 00368 } 00369 break; 00370 case KSValue::DateType: 00371 case KSValue::TimeType: 00372 // Handled above 00373 return true; 00374 default: 00375 QString tmp( i18n("Operator + not defined for type %1") ); 00376 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00377 return false; 00378 } 00379 00380 // Never reached 00381 return false; 00382 } 00383 00384 bool KSEval_t_minus_sign( KSParseNode* node, KSContext& context ) 00385 { 00386 // Unary ? 00387 if ( node->branch1() && !node->branch2() ) 00388 { 00389 if ( !node->branch1()->eval( context ) ) 00390 return false; 00391 if ( context.value()->type() == KSValue::IntType ) 00392 { 00393 context.setValue( new KSValue( -( context.value()->intValue() ) ) ); 00394 return true; 00395 } 00396 if ( context.value()->type() == KSValue::DoubleType ) 00397 { 00398 context.setValue( new KSValue( -( context.value()->doubleValue() ) ) ); 00399 return true; 00400 } 00401 00402 QString tmp( i18n("Unary Operator - not defined for type %1") ); 00403 context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) ); 00404 return false; 00405 } 00406 00407 EVAL_OPS( context, l, r, false ); 00408 00409 //allows 5-date and 5-time 00410 if ( r.value()->type() == KSValue::TimeType ) 00411 { 00412 if ( KSUtil::checkType( context, l.value(), KSValue::TimeType, false ) ) 00413 { 00414 QTime d = r.value()->timeValue(); 00415 int diff = d.secsTo( l.value()->timeValue() ); 00416 FILL_VALUE( context, l, r ); 00417 QTime _time(0,0,0); 00418 _time=_time.addSecs(diff); 00419 context.value()->setValue( /*(KScript::Long) diff*/_time ); 00420 return TRUE; 00421 } 00422 00423 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ) 00424 return false; 00425 QTime t = r.value()->timeValue(); 00426 t = t.addSecs( -l.value()->intValue() ); 00427 FILL_VALUE( context, l, r ); 00428 context.value()->setValue( t ); 00429 return TRUE; 00430 } 00431 else if ( r.value()->type() == KSValue::DateType ) 00432 { 00433 if ( KSUtil::checkType( context, l.value(), KSValue::DateType, false ) ) 00434 { 00435 QDate d = r.value()->dateValue(); 00436 int diff = d.daysTo( l.value()->dateValue() ); 00437 FILL_VALUE( context, l, r ); 00438 context.value()->setValue( (KScript::Long)diff ); 00439 return TRUE; 00440 } 00441 00442 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ) 00443 return false; 00444 QDate d = r.value()->dateValue(); 00445 d = d.addDays( -l.value()->intValue() ); 00446 FILL_VALUE( context, l, r ); 00447 context.value()->setValue( d ); 00448 return TRUE; 00449 } 00450 00451 00452 00453 if ( l.value()->type() == KSValue::TimeType ) 00454 { 00455 if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) ) 00456 { 00457 QTime d = r.value()->timeValue(); 00458 int diff = d.secsTo( l.value()->timeValue() ); 00459 FILL_VALUE( context, l, r ); 00460 context.value()->setValue( (KScript::Long) diff ); 00461 return TRUE; 00462 } 00463 00464 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00465 return false; 00466 QTime t = l.value()->timeValue(); 00467 t = t.addSecs( -r.value()->intValue() ); 00468 FILL_VALUE( context, l, r ); 00469 context.value()->setValue( t ); 00470 return TRUE; 00471 } 00472 else if ( l.value()->type() == KSValue::DateType ) 00473 { 00474 if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) ) 00475 { 00476 QDate d = r.value()->dateValue(); 00477 int diff = d.daysTo( l.value()->dateValue() ); 00478 FILL_VALUE( context, l, r ); 00479 context.value()->setValue( (KScript::Long)diff ); 00480 return TRUE; 00481 } 00482 00483 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00484 return false; 00485 QDate d = l.value()->dateValue(); 00486 d = d.addDays( -r.value()->intValue() ); 00487 FILL_VALUE( context, l, r ); 00488 context.value()->setValue( d ); 00489 return TRUE; 00490 } 00491 // If we have double and int, then always convert to double 00492 else if ( l.value()->type() == KSValue::DoubleType ) 00493 { 00494 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00495 return false; 00496 } 00497 else 00498 { 00499 if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 00500 return false; 00501 l.value()->cast( r.value()->type()); 00502 } 00503 00504 switch( l.value()->type() ) 00505 { 00506 case KSValue::IntType: 00507 { 00508 KScript::Long result = l.value()->intValue() - r.value()->intValue(); 00509 FILL_VALUE( context, l, r ); 00510 context.value()->setValue( result ); 00511 return true; 00512 } 00513 case KSValue::DoubleType: 00514 { 00515 KScript::Double result = l.value()->doubleValue() - r.value()->doubleValue(); 00516 FILL_VALUE( context, l, r ); 00517 context.value()->setValue( result ); 00518 return true; 00519 } 00520 default: 00521 QString tmp( i18n("Operator - not defined for type %1") ); 00522 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00523 return false; 00524 } 00525 00526 // Never reached 00527 return false; 00528 } 00529 00530 bool KSEval_t_asterik( KSParseNode* node, KSContext& context ) 00531 { 00532 EVAL_OPS( context, l, r, false ); 00533 00534 // If we have double and int, then always convert to double 00535 if ( l.value()->type() == KSValue::DoubleType ) 00536 { 00537 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00538 return false; 00539 } 00540 else 00541 { 00542 if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 00543 return false; 00544 l.value()->cast( r.value()->type()); 00545 } 00546 00547 switch( l.value()->type() ) 00548 { 00549 case KSValue::IntType: 00550 { 00551 // promote to double multiplication( fix bug #42499 ) 00552 // hold it in long integer only if it is small enough 00553 KScript::Double v = r.value()->doubleValue() * l.value()->doubleValue(); 00554 FILL_VALUE( context, l, r ); 00555 if( fabs( v ) < 1e9 ) 00556 context.value()->setValue( (long) v ); 00557 else 00558 context.value()->setValue( v ); 00559 return true; 00560 } 00561 case KSValue::DoubleType: 00562 { 00563 KScript::Double result = r.value()->doubleValue() * l.value()->doubleValue(); 00564 FILL_VALUE( context, l, r ); 00565 context.value()->setValue( result ); 00566 return true; 00567 } 00568 default: 00569 QString tmp( i18n("Operator * not defined for type %1") ); 00570 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00571 return false; 00572 } 00573 00574 // Never reached 00575 return false; 00576 } 00577 00578 bool KSEval_t_solidus( KSParseNode* node, KSContext& context ) 00579 { 00580 EVAL_OPS( context, l, r, false ); 00581 00582 // If we have double and int, then always convert to double 00583 if ( l.value()->type() == KSValue::DoubleType ) 00584 { 00585 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00586 return false; 00587 } 00588 else 00589 { 00590 if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 00591 return false; 00592 l.value()->cast( r.value()->type()); 00593 } 00594 00595 switch( l.value()->type() ) 00596 { 00597 case KSValue::IntType: 00598 { 00599 // If the devision has a "rest" then we have to convert to doubles 00600 if ( r.value()->intValue()!=0 && ( l.value()->intValue() % r.value()->intValue() ) == 0 ) 00601 { 00602 KScript::Long result = l.value()->intValue() / r.value()->intValue(); 00603 FILL_VALUE( context, l, r ); 00604 context.value()->setValue( result ); 00605 } 00606 else 00607 { 00608 KScript::Double result = (double)l.value()->intValue() / (double)r.value()->intValue(); 00609 FILL_VALUE( context, l, r ); 00610 context.value()->setValue( result ); 00611 } 00612 return true; 00613 } 00614 case KSValue::DoubleType: 00615 { 00616 KScript::Double result = l.value()->doubleValue() / r.value()->doubleValue(); 00617 FILL_VALUE( context, l, r ); 00618 context.value()->setValue( result ); 00619 return true; 00620 } 00621 default: 00622 QString tmp( i18n("Operator / not defined for type %1") ); 00623 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00624 return false; 00625 } 00626 00627 // Never reached 00628 return false; 00629 } 00630 00631 bool KSEval_t_percent_sign( KSParseNode* node, KSContext& context ) 00632 { 00633 EVAL_OPS( context, l, r, false ); 00634 00635 if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ) 00636 return false; 00637 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 00638 return false; 00639 00640 if(r.value()->intValue()!=0) 00641 { 00642 KScript::Long result = l.value()->intValue() % r.value()->intValue(); 00643 FILL_VALUE( context, l, r ); 00644 context.value()->setValue( result ); 00645 } 00646 else 00647 { 00648 KScript::Double result = (double)l.value()->intValue() / (double)r.value()->intValue(); 00649 FILL_VALUE( context, l, r ); 00650 context.value()->setValue( result ); 00651 } 00652 return true; 00653 } 00654 00655 bool KSEval_t_tilde( KSParseNode* , KSContext& ) { return false; } 00656 00657 bool KSEval_t_integer_literal( KSParseNode* node, KSContext& context ) 00658 { 00659 context.setValue( new KSValue( node->getIntegerLiteral() ) ); 00660 return true; 00661 } 00662 00663 bool KSEval_t_string_literal( KSParseNode* node, KSContext& context ) 00664 { 00665 context.setValue( new KSValue( node->getStringLiteral() ) ); 00666 return true; 00667 } 00668 00669 bool KSEval_t_character_literal( KSParseNode* node, KSContext& context ) 00670 { 00671 context.setValue( new KSValue( node->getCharacterLiteral() ) ); 00672 return true; 00673 } 00674 00675 bool KSEval_t_floating_pt_literal( KSParseNode* node, KSContext& context ) 00676 { 00677 context.setValue( new KSValue( node->getFloatingPtLiteral() ) ); 00678 return true; 00679 } 00680 00681 bool KSEval_t_boolean_literal( KSParseNode* node, KSContext& context ) 00682 { 00683 context.setValue( new KSValue( node->getBooleanLiteral() ) ); 00684 return true; 00685 } 00686 00687 bool KSEval_scoped_name( KSParseNode* node, KSContext& context ) 00688 { 00689 KSValue* v = context.object( node->getIdent() ); 00690 if ( !v ) 00691 { 00692 context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) ); 00693 return false; 00694 } 00695 00696 v->ref(); 00697 context.setValue( v ); 00698 00699 return true; 00700 } 00701 00702 00703 bool KSEval_const_dcl( KSParseNode* node, KSContext& context ) 00704 { 00705 Q_ASSERT( node->branch1() ); 00706 00707 KSContext( l ); 00708 if ( !node->branch1()->eval( l ) ) 00709 { 00710 context.setException( l ); 00711 return false; 00712 } 00713 00714 if ( !context.value() ) 00715 context.scope()->addObject( node->getIdent(), l.shareValue() ); 00716 else if ( context.value()->type() == KSValue::StructClassType ) 00717 context.value()->structClassValue()->nameSpace()->insert( node->getIdent(), l.shareValue() ); 00718 else 00719 Q_ASSERT( 0 ); 00720 00721 return true; 00722 } 00723 00724 bool KSEval_func_dcl( KSParseNode* node, KSContext& context ) 00725 { 00726 // We want an additional namespace in the scope 00727 KSNamespace nspace; 00728 KSSubScope scope( &nspace ); 00729 context.scope()->pushLocalScope( &scope ); 00730 00731 // Fill parameters in our namespace 00732 if ( node->branch1() ) 00733 if ( !node->branch1()->eval( context ) ) 00734 { 00735 context.scope()->popLocalScope(); 00736 return false; 00737 } 00738 00739 // Are parameters left ? 00740 if ( !context.value()->listValue().isEmpty() ) 00741 { 00742 const QString tmp( i18n("1 argument is not needed", "%n arguments are not needed", context.value()->listValue().count() ) ); 00743 context.setException( new KSException( "TooManyArguments", tmp, node->getLineNo() ) ); 00744 context.scope()->popLocalScope(); 00745 return false; 00746 } 00747 00748 bool res = true; 00749 // Call the function 00750 if ( node->branch2() ) 00751 res = node->branch2()->eval( context ); 00752 00753 // Finish stack unwinding 00754 context.clearReturnFlag(); 00755 00756 // Remove the local scope 00757 context.scope()->popLocalScope(); 00758 00759 return res; 00760 } 00761 00762 bool KSEval_func_lines( KSParseNode* node, KSContext& context ) 00763 { 00764 if ( node->branch1() ) 00765 { 00766 context.interpreter()->context().setException( 0 ); // ### reset -- HACK (Simon) 00767 if ( !node->branch1()->eval( context ) ) 00768 return false; 00769 if ( context.returnFlag() ) 00770 return true; 00771 // if ( node->branch1()->getType() == t_return ) 00772 // return true; 00773 } 00774 00775 // We are not interested in the value of the evaluation 00776 // since it is not a return value. 00777 context.setValue( 0 ); 00778 00779 // Did some destructor cause a exception ? 00780 if ( context.interpreter()->context().exception() ) 00781 { 00782 context.setException( context.interpreter()->context().exception() ); 00783 return false; 00784 } 00785 00786 // The second branch can only hold a "func_lines" parsenode. 00787 if ( node->branch2() ) 00788 if ( !node->branch2()->eval( context ) ) 00789 return false; 00790 00791 return true; 00792 } 00793 00794 bool KSEval_assign_expr( KSParseNode* node, KSContext& context ) 00795 { 00796 EVAL_OPS( context, l, r, true ); 00797 00798 if ( l.value()->mode() != KSValue::LeftExpr ) 00799 { 00800 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) ); 00801 return false; 00802 } 00803 00804 // Special handling for strings 00805 if ( l.value()->type() == KSValue::CharRefType ) 00806 { 00807 if ( !r.value()->cast( KSValue::CharType ) ) 00808 { 00809 QString tmp( i18n("From %1 to Char") ); 00810 context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) ); 00811 return false; 00812 } 00813 l.value()->charRefValue() = r.value()->charValue(); 00814 00815 // Dont return the CharRef, so create a new value 00816 context.setValue( new KSValue( r.value()->charValue() ) ); 00817 return true; 00818 } 00819 00820 // Special handling for properties 00821 if ( l.value()->type() == KSValue::PropertyType ) 00822 { 00823 if ( ! l.value()->propertyValue()->set( context, r.shareValue() ) ) 00824 return false; 00825 // Return the value we just assigned 00826 context.setValue( r.shareValue() ); 00827 } 00828 else 00829 { 00830 l.value()->suck( r.value() ); 00831 // Return the value we just assigned 00832 context.setValue( l.shareValue() ); 00833 } 00834 // Now it is a rightexpr. Dont allow to change it -> constant 00835 // context.value()->setMode( KSValue::Constant ); 00836 00837 return true; 00838 } 00839 00840 bool KSEval_t_equal( KSParseNode* node, KSContext& context ) 00841 { 00842 EVAL_OPS( context, l, r, false ); 00843 00844 KScript::Boolean result; 00845 if ( !r.value()->cast( l.value()->type() ) ) 00846 { 00847 /* If we can't cast the values to match, then they definitely aren't 00848 equal. Don't return a parse error here -- our users aren't expected 00849 to have detailed understanding of the syntax. 00850 */ 00851 result = false; 00852 } 00853 else 00854 { 00855 00856 result = ( r.value()->cmp( *l.value() ) ); 00857 } 00858 00859 FILL_VALUE( context, l, r ); 00860 context.value()->setValue( result ); 00861 return true; 00862 } 00863 00864 bool KSEval_t_notequal( KSParseNode* node, KSContext& context ) 00865 { 00866 EVAL_OPS( context, l, r, false ); 00867 00868 if ( !r.value()->cast( l.value()->type() ) ) 00869 { 00870 QString tmp( i18n("From %1 to %2") ); 00871 context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ).arg( l.value()->typeName() ), node->getLineNo() ) ); 00872 return false; 00873 } 00874 00875 KScript::Boolean result = !( r.value()->cmp( *l.value() ) ); 00876 FILL_VALUE( context, l, r ); 00877 context.value()->setValue( result ); 00878 return true; 00879 } 00880 00881 bool KSEval_t_less_or_equal( KSParseNode* node, KSContext& context ) 00882 { 00883 EVAL_OPS( context, l, r, false ); 00884 00885 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00886 return false; 00887 00888 switch( l.value()->type() ) 00889 { 00890 case KSValue::IntType: 00891 { 00892 KScript::Boolean result = l.value()->intValue() <= r.value()->intValue(); 00893 FILL_VALUE( context, l, r ); 00894 context.value()->setValue( result ); 00895 return true; 00896 } 00897 case KSValue::DoubleType: 00898 { 00899 KScript::Boolean result = l.value()->doubleValue() <= r.value()->doubleValue(); 00900 FILL_VALUE( context, l, r ); 00901 context.value()->setValue( result ); 00902 return true; 00903 } 00904 case KSValue::CharType: 00905 { 00906 KScript::Boolean result = l.value()->charValue() <= r.value()->charValue(); 00907 FILL_VALUE( context, l, r ); 00908 context.value()->setValue( result ); 00909 return true; 00910 } 00911 case KSValue::StringType: 00912 { 00913 KScript::Boolean result = l.value()->stringValue() <= r.value()->stringValue(); 00914 FILL_VALUE( context, l, r ); 00915 context.value()->setValue( result ); 00916 return true; 00917 } 00918 case KSValue::DateType: 00919 { 00920 KScript::Boolean result = l.value()->dateValue() <= r.value()->dateValue(); 00921 FILL_VALUE( context, l, r ); 00922 context.value()->setValue( result ); 00923 return true; 00924 } 00925 case KSValue::TimeType: 00926 { 00927 KScript::Boolean result = l.value()->timeValue() <= r.value()->timeValue(); 00928 FILL_VALUE( context, l, r ); 00929 context.value()->setValue( result ); 00930 return true; 00931 } 00932 default: 00933 QString tmp( i18n("Operator <= not defined for type %1") ); 00934 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00935 return false; 00936 } 00937 00938 // Never reached 00939 return false; 00940 } 00941 00942 bool KSEval_t_greater_or_equal( KSParseNode* node, KSContext& context ) 00943 { 00944 EVAL_OPS( context, l, r, false ); 00945 00946 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 00947 return false; 00948 00949 switch( l.value()->type() ) 00950 { 00951 case KSValue::IntType: 00952 { 00953 KScript::Boolean result = l.value()->intValue() >= r.value()->intValue(); 00954 FILL_VALUE( context, l, r ); 00955 context.value()->setValue( result ); 00956 return true; 00957 } 00958 case KSValue::DoubleType: 00959 { 00960 KScript::Boolean result = l.value()->doubleValue() >= r.value()->doubleValue(); 00961 FILL_VALUE( context, l, r ); 00962 context.value()->setValue( result ); 00963 return true; 00964 } 00965 case KSValue::StringType: 00966 { 00967 KScript::Boolean result = l.value()->stringValue() >= r.value()->stringValue(); 00968 FILL_VALUE( context, l, r ); 00969 context.value()->setValue( result ); 00970 return true; 00971 } 00972 case KSValue::CharType: 00973 { 00974 KScript::Boolean result = l.value()->charValue() >= r.value()->charValue(); 00975 FILL_VALUE( context, l, r ); 00976 context.value()->setValue( result ); 00977 return true; 00978 } 00979 case KSValue::DateType: 00980 { 00981 KScript::Boolean result = l.value()->dateValue() >= r.value()->dateValue(); 00982 FILL_VALUE( context, l, r ); 00983 context.value()->setValue( result ); 00984 return true; 00985 } 00986 case KSValue::TimeType: 00987 { 00988 KScript::Boolean result = l.value()->timeValue() >= r.value()->timeValue(); 00989 FILL_VALUE( context, l, r ); 00990 context.value()->setValue( result ); 00991 return true; 00992 } 00993 default: 00994 QString tmp( i18n("Operator >= not defined for type %1") ); 00995 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 00996 return false; 00997 } 00998 00999 // Never reached 01000 return false; 01001 } 01002 01003 bool KSEval_t_array( KSParseNode* node, KSContext& context ) 01004 { 01005 EVAL_OPS( context, l, r, false ); 01006 01007 if ( !r.value()->cast( KSValue::IntType ) ) 01008 { 01009 QString tmp( i18n("From %1 to Integer in array index") ); 01010 context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) ); 01011 return false; 01012 } 01013 01014 int index = r.value()->intValue(); 01015 01016 if ( index < 0 ) 01017 { 01018 QString tmp( i18n("Negative array index %1")); 01019 context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) ); 01020 return false; 01021 } 01022 01023 // is it a string ? -> special handling 01024 if ( l.value()->type() == KSValue::StringType ) 01025 { 01026 int len = l.value()->stringValue().length(); 01027 01028 if ( index >= len && !context.leftExpr() ) 01029 { 01030 QString tmp( i18n("Too large index %1")); 01031 context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) ); 01032 return false; 01033 } 01034 01035 // Get a QChar 01036 if ( !context.leftExpr() ) 01037 { 01038 const QString& str = l.value()->stringValue(); 01039 context.setValue( new KSValue( str[ index ] ) ); 01040 return true; 01041 } 01042 01043 // Get a CharRef since leftexpr is needed 01044 context.setValue( new KSValue( KScript::CharRef( &(l.value()->stringValue()), index ) ) ); 01045 context.value()->setMode( KSValue::LeftExpr ); 01046 return true; 01047 } 01048 01049 if ( !l.value()->cast( KSValue::ListType ) ) 01050 { 01051 QString tmp( i18n("From %1 to List") ); 01052 context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01053 return false; 01054 } 01055 01056 int len = l.value()->listValue().count(); 01057 if ( index >= len ) 01058 { 01059 if ( !context.leftExpr() ) 01060 { 01061 QString tmp( i18n("Too large index %1")); 01062 context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) ); 01063 return false; 01064 } 01065 else 01066 { 01067 // Fill the list with empty values 01068 for( int i = 0; i <= index - len; ++i ) 01069 l.value()->listValue().append( new KSValue() ); 01070 } 01071 } 01072 01073 context.setValue( l.value()->listValue()[ index ] ); 01074 context.value()->setMode( l.value()->mode() ); 01075 01076 return true; 01077 } 01078 01079 bool KSEval_t_dict( KSParseNode* node, KSContext& context ) 01080 { 01081 EVAL_OPS( context, l, r, false ); 01082 01083 if ( !r.value()->cast( KSValue::StringType ) ) 01084 { 01085 QString tmp( i18n("From %1 to String in dict") ); 01086 context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) ); 01087 return false; 01088 } 01089 01090 if ( !l.value()->cast( KSValue::MapType ) ) 01091 { 01092 QString tmp( i18n("From %1 to Map") ); 01093 context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01094 return false; 01095 } 01096 01097 QMap<QString,KSValue::Ptr>::Iterator it = l.value()->mapValue().find( r.value()->stringValue() ); 01098 // Unknown element ? 01099 if ( it == l.value()->mapValue().end() ) 01100 { 01101 // No left expr needed-> return <none> 01102 if ( !context.leftExpr() ) 01103 { 01104 context.setValue( new KSValue() ); 01105 return true; 01106 } 01107 // Left expr needed 01108 // we got Left expr -> insert empty element 01109 else if ( l.value()->mode() == KSValue::LeftExpr ) 01110 { 01111 KSValue::Ptr v( new KSValue() ); 01112 v->setMode( l.value()->mode() ); 01113 l.value()->mapValue().insert( r.value()->stringValue(), v ); 01114 context.setValue( v ); 01115 return true; 01116 } 01117 // we can not provide a left expression 01118 else 01119 { 01120 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression."), node->getLineNo() ) ); 01121 return false; 01122 } 01123 } 01124 01125 context.setValue( it.data() ); 01126 context.value()->setMode( l.value()->mode() ); 01127 01128 return true; 01129 } 01130 01131 bool KSEval_func_params( KSParseNode* node, KSContext& context ) 01132 { 01133 // process a parameter 01134 if ( node->branch1() ) 01135 if ( !node->branch1()->eval( context ) ) 01136 return false; 01137 01138 // process more parameters 01139 if ( node->branch2() ) 01140 if ( !node->branch2()->eval( context ) ) 01141 return false; 01142 01143 return true; 01144 } 01145 01146 bool KSEval_func_param_in( KSParseNode* node, KSContext& context ) 01147 { 01148 KSValue* v = 0; 01149 01150 // No more arguments ? 01151 if ( context.value()->listValue().isEmpty() ) 01152 { 01153 // Do we have a default Argument ? 01154 if ( node->branch1() ) 01155 { 01156 KSContext d( context ); 01157 if ( !node->branch1()->eval( d ) ) 01158 return false; 01159 if ( d.value()->mode() == KSValue::Temp ) 01160 v = d.shareValue(); 01161 else 01162 v = new KSValue( *d.value() ); 01163 } 01164 else 01165 { 01166 QString tmp( i18n("Argument for parameters %1 missing") ); 01167 context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) ); 01168 return false; 01169 } 01170 } 01171 else 01172 { 01173 // Put the arguments as parameter in our namespace 01174 KSValue* arg = *(context.value()->listValue().begin()); 01175 if ( arg->mode() == KSValue::Temp ) 01176 { 01177 arg->ref(); 01178 v = arg; 01179 } 01180 else 01181 v = new KSValue( *arg ); 01182 01183 // Remove the argument from the list 01184 context.value()->listValue().remove( context.value()->listValue().begin() ); 01185 } 01186 01187 v->setMode( KSValue::LeftExpr ); 01188 context.scope()->addObject( node->getIdent(), v ); 01189 01190 return true; 01191 } 01192 01193 bool KSEval_func_param_out( KSParseNode* node, KSContext& context ) 01194 { 01195 // No more arguments ? 01196 if ( context.value()->listValue().isEmpty() ) 01197 { 01198 QString tmp( i18n("Argument for parameters %1 missing") ); 01199 context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) ); 01200 return false; 01201 } 01202 01203 KSValue* arg = *(context.value()->listValue().begin()); 01204 01205 // Is the argument not a leftexpr ? 01206 if ( arg->mode() != KSValue::LeftExpr ) 01207 { 01208 QString tmp( i18n("LeftExpr needed for parameter %1") ); 01209 context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) ); 01210 return false; 01211 } 01212 01213 // The difference between out/inout. We empty the value here to make 01214 // shure that nobody write "out" where he means "inout". 01215 context.value()->clear(); 01216 01217 // Put the arguments as parameter in our namespace 01218 arg->ref(); 01219 context.scope()->addObject( node->getIdent(), arg ); 01220 01221 // Remove the argument from the list 01222 context.value()->listValue().remove( context.value()->listValue().begin() ); 01223 01224 return true; 01225 } 01226 01227 bool KSEval_func_param_inout( KSParseNode* node, KSContext& context ) 01228 { 01229 // No more arguments ? 01230 if ( context.value()->listValue().isEmpty() ) 01231 { 01232 QString tmp( i18n("Argument for parameters %1 missing") ); 01233 context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) ); 01234 return false; 01235 } 01236 01237 KSValue* arg = *(context.value()->listValue().begin()); 01238 01239 // Is the argument not a leftexpr ? 01240 if ( arg->mode() != KSValue::LeftExpr ) 01241 { 01242 QString tmp( i18n("LeftExpr needed for parameter %1") ); 01243 context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) ); 01244 return false; 01245 } 01246 01247 // Put the arguments as parameter in our namespace 01248 arg->ref(); 01249 context.scope()->addObject( node->getIdent(), arg ); 01250 01251 // Remove the argument from the list 01252 context.value()->listValue().remove( context.value()->listValue().begin() ); 01253 01254 return true; 01255 } 01256 01257 bool KSEval_t_func_call( KSParseNode* node, KSContext& context ) 01258 { 01259 // Get the function object 01260 KSParseNode *left = node->branch1(); 01261 if ( !left ) 01262 return true; 01263 01264 KSContext l( context ); 01265 if ( !left->eval( l ) ) 01266 { 01267 context.setException( l ); 01268 return false; 01269 } 01270 01271 if ( !l.value()->cast( KSValue::FunctionType ) && 01272 !l.value()->cast( KSValue::MethodType ) && !l.value()->cast( KSValue::StructClassType ) ) 01273 { 01274 QString tmp( i18n("From %1 to Function") ); 01275 context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01276 return false; 01277 } 01278 01279 // Create a list of parameters 01280 context.setValue( new KSValue( KSValue::ListType ) ); 01281 context.setExtraData(new KSValue(KSValue::ListType)); 01282 01283 KSParseNode *right = node->branch2(); 01284 if ( right ) 01285 if ( !right->eval( context ) ) 01286 return false; 01287 01288 // Remove our namespaces 01289 KSSubScope* scope = context.scope()->popLocalScope(); 01290 KSModule* module = context.scope()->popModule(); 01291 01292 bool b = FALSE; 01293 if ( l.value()->cast( KSValue::FunctionType ) ) 01294 { 01295 context.scope()->pushModule( l.value()->functionValue()->module() ); 01296 // Call the function 01297 b = l.value()->functionValue()->call( context ); 01298 context.scope()->popModule(); 01299 } 01300 else if ( l.value()->cast( KSValue::StructClassType ) ) 01301 { 01302 context.scope()->pushModule( l.value()->structClassValue()->module() ); 01303 // Call struct constructor 01304 b = l.value()->structClassValue()->constructor( context ); 01305 context.scope()->popModule(); 01306 } 01307 else if ( l.value()->cast( KSValue::MethodType ) ) 01308 { 01309 context.scope()->pushModule( l.value()->methodValue()->module() ); 01310 // Call method 01311 b = l.value()->methodValue()->call( context ); 01312 context.scope()->popModule(); 01313 } 01314 else 01315 Q_ASSERT( 0 ); 01316 01317 // Resume namespaces 01318 context.scope()->pushLocalScope( scope ); 01319 context.scope()->pushModule( module ); 01320 01321 if ( !b ) 01322 return false; 01323 01324 // Lets have at least a <none> as return value 01325 if ( !context.value() ) 01326 context.setValue( KSValue::null() ); 01327 01328 return true; 01329 } 01330 01331 bool KSEval_member_expr( KSParseNode* node, KSContext& context ) 01332 { 01333 KSParseNode *left = node->branch1(); 01334 Q_ASSERT( left ); 01335 01336 // This resets leftExpr to FALSE 01337 KSContext l( context ); 01338 // Try to find the object 01339 if ( !left->eval( l ) ) 01340 { 01341 context.setException( l ); 01342 return false; 01343 } 01344 01351 if ( l.value()->type() == KSValue::FunctionType || l.value()->type() == KSValue::MethodType ) 01352 { 01353 // Copy l.value to func 01354 KSContext func( context ); 01355 func.setValue( new KSValue( *l.value() ) ); 01356 01357 // Create a list of parameters 01358 l.setValue( new KSValue( KSValue::ListType ) ); 01359 01360 // Remove our namespaces 01361 KSSubScope* scope = l.scope()->popLocalScope(); 01362 KSModule* module = l.scope()->popModule(); 01363 01364 bool b = FALSE; 01365 if ( func.value()->type() == KSValue::FunctionType ) 01366 { 01367 l.scope()->pushModule( l.value()->functionValue()->module() ); 01368 // Call the function 01369 b = func.value()->functionValue()->call( l ); 01370 l.scope()->popModule(); 01371 } 01372 else if ( func.value()->type() == KSValue::MethodType ) 01373 { 01374 l.scope()->pushModule( l.value()->methodValue()->module() ); 01375 // Call method 01376 b = func.value()->methodValue()->call( l ); 01377 l.scope()->popModule(); 01378 } 01379 else 01380 Q_ASSERT( 0 ); 01381 01382 // Resume namespaces 01383 l.scope()->pushLocalScope( scope ); 01384 l.scope()->pushModule( module ); 01385 01386 if ( !b ) 01387 { 01388 context.setException( l.exception() ); 01389 return false; 01390 } 01391 01392 // Lets have at least a <none> as return value 01393 if ( !l.value() ) 01394 l.setValue( KSValue::null() ); 01395 } 01398 // Special handling for modules 01399 if ( l.value()->cast( KSValue::ModuleType ) ) 01400 { 01401 KSValue::Ptr v = l.value()->moduleValue()->member( context, node->getIdent() ); 01402 if ( !v ) 01403 { 01404 context.exception()->addLine( node->getLineNo() ); 01405 return false; 01406 } 01407 01408 context.setValue( v ); 01409 01410 return true; 01411 } 01412 // Special handling for struct classes 01413 else if ( l.value()->cast( KSValue::StructClassType ) ) 01414 { 01415 KSValue::Ptr v = l.value()->structClassValue()->member( context, node->getIdent() ); 01416 if ( !v ) 01417 { 01418 context.exception()->addLine( node->getLineNo() ); 01419 return false; 01420 } 01421 01422 context.setValue( v ); 01423 01424 return true; 01425 } 01426 01427 KSValue::Ptr v; 01428 KSModule* module; 01429 if ( l.value()->cast( KSValue::StructType ) ) 01430 { 01431 v = l.value()->structValue()->member( context, node->getIdent() ); 01432 module = l.value()->structValue()->module(); 01433 } 01434 // Special handling for all kind of built in data types 01435 else 01436 { 01437 KSValue* v = context.object( node->getIdent() ); 01438 if ( !v ) 01439 { 01440 context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) ); 01441 return false; 01442 } 01443 if ( v->type() != KSValue::FunctionType ) 01444 { 01445 KSUtil::castingError( context, v, KSValue::FunctionType ); 01446 return false; 01447 } 01448 v->ref(); 01449 context.setValue( new KSValue( new KSMethod( context.scope()->module(), l.shareValue(), v ) ) ); 01450 return true; 01451 } 01452 /* 01453 else 01454 { 01455 QString tmp( "From %1 to Object" ); 01456 context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01457 return false; 01458 } */ 01459 01460 if ( !v ) 01461 { 01462 context.exception()->addLine( node->getLineNo() ); 01463 return false; 01464 } 01465 01466 if ( v->type() == KSValue::FunctionType ) 01467 context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v ) ) ); 01468 else if ( v->type() == KSValue::StructBuiltinMethodType ) 01469 context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v, node->getIdent() ) ) ); 01470 else 01471 context.setValue( v ); 01472 01473 return true; 01474 } 01475 01476 bool KSEval_t_array_const( KSParseNode* node, KSContext& context ) 01477 { 01478 context.setValue( new KSValue( KSValue::ListType ) ); 01479 01480 KSParseNode *right = node->branch1(); 01481 if ( !right ) 01482 return true; 01483 01484 if ( !right->eval( context ) ) 01485 return false; 01486 01487 return true; 01488 } 01489 01490 bool KSEval_t_array_element( KSParseNode* node, KSContext& context ) 01491 { 01492 KSParseNode *left = node->branch1(); 01493 if ( !left ) 01494 return true; 01495 01496 KSContext l( context ); 01497 if ( !left->eval( l ) ) 01498 { 01499 context.setException( l ); 01500 return false; 01501 } 01502 01503 if ( l.value()->mode() == KSValue::Temp ) 01504 { 01505 l.value()->ref(); 01506 context.value()->listValue().append( KSValue::Ptr( l.value() ) ); 01507 } 01508 else 01509 { 01510 KSValue::Ptr v( new KSValue ); 01511 v->suck( l.value() ); 01512 context.value()->listValue().append( v ); 01513 } 01514 01515 KSParseNode *right = node->branch2(); 01516 if ( !right ) 01517 return true; 01518 01519 if ( !right->eval( context ) ) 01520 return false; 01521 01522 return true; 01523 } 01524 01525 bool KSEval_t_dict_const( KSParseNode* node, KSContext& context ) 01526 { 01527 context.setValue( new KSValue( KSValue::MapType ) ); 01528 01529 KSParseNode *right = node->branch1(); 01530 if ( !right ) 01531 return true; 01532 01533 if ( !right->eval( context ) ) 01534 return false; 01535 01536 return true; 01537 } 01538 01539 bool KSEval_t_dict_element( KSParseNode* node, KSContext& context ) 01540 { 01541 EVAL_OPS( context, l, r, false ); 01542 01543 if ( !l.value()->cast( KSValue::StringType ) ) 01544 { 01545 QString tmp( i18n("From %1 to String") ); 01546 context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) ); 01547 return false; 01548 } 01549 01550 if ( r.value()->mode() == KSValue::Temp ) 01551 { 01552 r.value()->ref(); 01553 context.value()->mapValue().insert( l.value()->stringValue(), KSValue::Ptr( r.value() ) ); 01554 } 01555 else 01556 { 01557 KSValue::Ptr v( new KSValue ); 01558 v->suck( r.value() ); 01559 context.value()->mapValue().insert( l.value()->stringValue(), v ); 01560 } 01561 01562 KSParseNode *next = node->branch3(); 01563 if ( !next ) 01564 return true; 01565 01566 if ( !next->eval( context ) ) 01567 return false; 01568 01569 return true; 01570 } 01571 01572 bool KSEval_t_while( KSParseNode* node, KSContext& context ) 01573 { 01574 do 01575 { 01576 EVAL_LEFT_OP( context, l ); 01577 01578 if ( !l.value()->implicitCast( KSValue::BoolType ) ) 01579 { 01580 QString tmp( i18n("From %1 to Boolean") ); 01581 context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01582 return false; 01583 } 01584 01585 // Head of the while loop 01586 if ( !l.value()->boolValue() ) 01587 return true; 01588 01589 // Tail of the while loop 01590 EVAL_RIGHT_OP( context, r ); 01591 } while( 1 ); 01592 01593 // Never reached 01594 return false; 01595 } 01596 01597 bool KSEval_t_do( KSParseNode* node, KSContext& context ) 01598 { 01599 do 01600 { 01601 // Body of the loop 01602 if ( !node->branch1()->eval( context ) ) 01603 return false; 01604 01605 // Tail 01606 if ( !node->branch2()->eval( context ) ) 01607 return false; 01608 01609 if ( !context.value()->cast( KSValue::BoolType ) ) 01610 { 01611 KSUtil::castingError( context, context.value(), KSValue::BoolType ); 01612 return false; 01613 } 01614 01615 // Head of the while loop 01616 if ( !context.value()->boolValue() ) 01617 return true; 01618 01619 } while( 1 ); 01620 01621 // Never reached 01622 return false; 01623 } 01624 01625 bool KSEval_t_for( KSParseNode* node, KSContext& context ) 01626 { 01627 // Evaluate the start code 01628 if ( !node->branch1()->eval( context ) ) 01629 return false; 01630 01631 do 01632 { 01633 // Evaluate the condition 01634 if ( !node->branch2()->eval( context ) ) 01635 return false; 01636 01637 if ( !context.value()->cast( KSValue::BoolType ) ) 01638 { 01639 KSUtil::castingError( context, context.value(), KSValue::BoolType ); 01640 return false; 01641 } 01642 01643 // Condition failed ? 01644 if ( !context.value()->boolValue() ) 01645 return true; 01646 01647 // Evaluate the body 01648 if ( !node->branch4()->eval( context ) ) 01649 return false; 01650 01651 // Evaluate the iterator 01652 if ( !node->branch3()->eval( context ) ) 01653 return false; 01654 01655 } while(1); 01656 01657 // Bever reached 01658 return false; 01659 } 01660 01661 bool KSEval_t_if( KSParseNode* node, KSContext& context ) 01662 { 01663 // Evaluate the condition 01664 if ( !node->branch1()->eval( context ) ) 01665 return false; 01666 01667 if ( !context.value()->cast( KSValue::BoolType ) ) 01668 { 01669 KSUtil::castingError( context, context.value(), KSValue::BoolType ); 01670 return false; 01671 } 01672 01673 // Condition failed ? 01674 if ( !context.value()->boolValue() ) 01675 { 01676 if ( node->branch3() ) 01677 return node->branch3()->eval( context ); 01678 return true; 01679 } 01680 01681 return node->branch2()->eval( context ); 01682 } 01683 01684 bool KSEval_t_incr( KSParseNode* node, KSContext& context ) 01685 { 01686 // Evaluate the expression 01687 if ( !node->branch1()->eval( context ) ) 01688 return false; 01689 01690 if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) ) 01691 return false; 01692 01693 if ( context.value()->mode() != KSValue::LeftExpr ) 01694 { 01695 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) ); 01696 return false; 01697 } 01698 01699 // postfix ? 01700 if ( node->branch2() ) 01701 { 01702 KSValue::Ptr p = context.shareValue(); 01703 KScript::Long l = p->intValue(); 01704 p->setValue( p->intValue() + 1 ); 01705 context.setValue( new KSValue( l ) ); 01706 context.value()->setMode( KSValue::Temp ); 01707 } 01708 else 01709 context.value()->setValue( context.value()->intValue() + 1 ); 01710 01711 return true; 01712 } 01713 01714 bool KSEval_t_decr( KSParseNode* node, KSContext& context ) 01715 { 01716 // Evaluate the expression 01717 if ( !node->branch1()->eval( context ) ) 01718 return false; 01719 01720 if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) ) 01721 return false; 01722 01723 if ( context.value()->mode() != KSValue::LeftExpr ) 01724 { 01725 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) ); 01726 return false; 01727 } 01728 01729 // postfix ? 01730 if ( node->branch2() ) 01731 { 01732 KSValue::Ptr p = context.shareValue(); 01733 KScript::Long l = p->intValue(); 01734 p->setValue( p->intValue() - 1 ); 01735 context.setValue( new KSValue( l ) ); 01736 context.value()->setMode( KSValue::Temp ); 01737 } 01738 else 01739 context.value()->setValue( context.value()->intValue() - 1 ); 01740 01741 return true; 01742 } 01743 01744 bool KSEval_t_less( KSParseNode* node, KSContext& context ) 01745 { 01746 EVAL_OPS( context, l, r, false ); 01747 01748 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 01749 return false; 01750 01751 switch( l.value()->type() ) 01752 { 01753 case KSValue::IntType: 01754 { 01755 KScript::Boolean result = l.value()->intValue() < r.value()->intValue(); 01756 FILL_VALUE( context, l, r ); 01757 context.value()->setValue( result ); 01758 return true; 01759 } 01760 case KSValue::DoubleType: 01761 { 01762 KScript::Boolean result = l.value()->doubleValue() < r.value()->doubleValue(); 01763 FILL_VALUE( context, l, r ); 01764 context.value()->setValue( result ); 01765 return true; 01766 } 01767 case KSValue::StringType: 01768 { 01769 KScript::Boolean result = l.value()->stringValue() < r.value()->stringValue(); 01770 FILL_VALUE( context, l, r ); 01771 context.value()->setValue( result ); 01772 return true; 01773 } 01774 case KSValue::DateType: 01775 { 01776 KScript::Boolean result = l.value()->dateValue() < r.value()->dateValue(); 01777 FILL_VALUE( context, l, r ); 01778 context.value()->setValue( result ); 01779 return true; 01780 } 01781 case KSValue::TimeType: 01782 { 01783 KScript::Boolean result = l.value()->timeValue() < r.value()->timeValue(); 01784 FILL_VALUE( context, l, r ); 01785 context.value()->setValue( result ); 01786 return true; 01787 } 01788 case KSValue::CharType: 01789 { 01790 KScript::Boolean result = l.value()->charValue() < r.value()->charValue(); 01791 FILL_VALUE( context, l, r ); 01792 context.value()->setValue( result ); 01793 return true; 01794 } 01795 default: 01796 QString tmp( i18n("Operator < not defined for type %1") ); 01797 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01798 return false; 01799 } 01800 01801 // Never reached 01802 return false; 01803 } 01804 01805 bool KSEval_t_greater( KSParseNode* node, KSContext& context ) 01806 { 01807 EVAL_OPS( context, l, r, false ); 01808 01809 if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) ) 01810 return false; 01811 01812 switch( l.value()->type() ) 01813 { 01814 case KSValue::IntType: 01815 { 01816 KScript::Boolean result = l.value()->intValue() > r.value()->intValue(); 01817 FILL_VALUE( context, l, r ); 01818 context.value()->setValue( result ); 01819 return true; 01820 } 01821 case KSValue::DoubleType: 01822 { 01823 KScript::Boolean result = l.value()->doubleValue() > r.value()->doubleValue(); 01824 FILL_VALUE( context, l, r ); 01825 context.value()->setValue( result ); 01826 return true; 01827 } 01828 case KSValue::StringType: 01829 { 01830 KScript::Boolean result = l.value()->stringValue() > r.value()->stringValue(); 01831 FILL_VALUE( context, l, r ); 01832 context.value()->setValue( result ); 01833 return true; 01834 } 01835 case KSValue::CharType: 01836 { 01837 KScript::Boolean result = l.value()->charValue() > r.value()->charValue(); 01838 FILL_VALUE( context, l, r ); 01839 context.value()->setValue( result ); 01840 return true; 01841 } 01842 case KSValue::DateType: 01843 { 01844 KScript::Boolean result = l.value()->dateValue() > r.value()->dateValue(); 01845 FILL_VALUE( context, l, r ); 01846 context.value()->setValue( result ); 01847 return true; 01848 } 01849 case KSValue::TimeType: 01850 { 01851 KScript::Boolean result = l.value()->timeValue() > r.value()->timeValue(); 01852 FILL_VALUE( context, l, r ); 01853 context.value()->setValue( result ); 01854 return true; 01855 } 01856 default: 01857 QString tmp( i18n("Operator > not defined for type %1") ); 01858 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 01859 return false; 01860 } 01861 01862 // Never reached 01863 return false; 01864 } 01865 01866 01867 bool KSEval_t_foreach( KSParseNode* node, KSContext& context ) 01868 { 01869 // Evaluate the list/map 01870 if ( !node->branch1()->eval( context ) ) 01871 return false; 01872 01873 // Is the array a LeftExpr, Temp or Constant 01874 KSValue::Mode mode = context.value()->mode(); 01875 01876 // Little hack to test wether we are in list or map mode 01877 if ( node->branch3() ) 01878 { 01879 if ( !context.value()->cast( KSValue::MapType ) ) 01880 { 01881 KSUtil::castingError( context, context.value(), KSValue::MapType ); 01882 return false; 01883 } 01884 01885 KSNamespace nspace; 01886 context.scope()->localScope()->pushNamespace( &nspace ); 01887 01888 QMap<QString,KSValue::Ptr>::Iterator it = context.value()->mapValue().begin(); 01889 QMap<QString,KSValue::Ptr>::Iterator end = context.value()->mapValue().end(); 01890 for( ; it != end; ++it ) 01891 { 01892 // Get the element of the map in the local scope 01893 it.data()->ref(); 01894 KSValue* v = it.data(); 01895 // Same mode as the array 01896 v->setMode( mode ); 01897 context.scope()->addObject( node->getStringLiteral(), v ); 01898 01899 // Get the key of the map in the local scope 01900 v = new KSValue( it.key() ); 01901 v->setMode( KSValue::Constant ); 01902 context.scope()->addObject( node->getIdent(), v ); 01903 01904 // Evaluate the body 01905 KSContext ctx( context ); 01906 if ( !node->branch2()->eval( ctx ) ) 01907 { 01908 context.setException( ctx ); 01909 context.scope()->localScope()->popNamespace(); 01910 return false; 01911 } 01912 } 01913 01914 context.scope()->localScope()->popNamespace(); 01915 } 01916 else 01917 { 01918 if ( !context.value()->cast( KSValue::ListType ) ) 01919 { 01920 KSUtil::castingError( context, context.value(), KSValue::ListType ); 01921 return false; 01922 } 01923 01924 KSNamespace nspace; 01925 context.scope()->localScope()->pushNamespace( &nspace ); 01926 01927 QValueList<KSValue::Ptr>::Iterator it = context.value()->listValue().begin(); 01928 QValueList<KSValue::Ptr>::Iterator end = context.value()->listValue().end(); 01929 for( ; it != end; ++it ) 01930 { 01931 // Get the element of the array in our local variable 01932 (*it)->ref(); 01933 KSValue* v = (*it); 01934 // Same mode as the array 01935 v->setMode( mode ); 01936 context.scope()->addObject( node->getIdent(), v ); 01937 01938 // Evaluate the body 01939 KSContext ctx( context ); 01940 if ( !node->branch2()->eval( ctx ) ) 01941 { 01942 context.setException( ctx ); 01943 context.scope()->localScope()->popNamespace(); 01944 return false; 01945 } 01946 } 01947 01948 context.scope()->localScope()->popNamespace(); 01949 } 01950 01951 return true; 01952 } 01953 01954 bool KSEval_t_match( KSParseNode* node , KSContext& context ) 01955 { 01956 if ( !node->branch1()->eval( context ) ) 01957 return false; 01958 01959 if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) ) 01960 return FALSE; 01961 01962 KRegExp* exp = context.interpreter()->regexp(); 01963 exp->compile( node->getIdent().latin1() ); // identifiers are a-zA-Z etc, so latin1 is ok. (David) 01964 01965 kdDebug() << "Matching " << context.value()->stringValue() << " against " << node->getIdent() << endl; 01966 01967 context.setValue( new KSValue( exp->match( context.value()->stringValue().latin1() ) ) ); 01968 01969 return TRUE; 01970 } 01971 01972 bool KSEval_t_subst( KSParseNode* node, KSContext& context ) 01973 { 01974 KSContext l( context, TRUE ); 01975 if ( !node->branch1()->eval( l ) ) 01976 return false; 01977 01978 if ( l.value()->mode() != KSValue::LeftExpr ) 01979 { 01980 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in substitute."), node->getLineNo() ) ); 01981 return false; 01982 } 01983 01984 if ( !KSUtil::checkType( l, l.value(), KSValue::StringType, TRUE ) ) 01985 return FALSE; 01986 01987 int pos = node->getIdent().find( '/' ); 01988 Q_ASSERT( pos != -1 ); 01989 QString match = node->getIdent().left( pos ); 01990 QString subst = node->getIdent().mid( pos + 1 ); 01991 KRegExp* exp = context.interpreter()->regexp(); 01992 exp->compile( match.latin1() ); // identifiers are a-zA-Z etc, so latin1 is ok. (David) 01993 01994 kdDebug() << "Matching " << l.value()->stringValue() << " against " << node->getIdent() << endl; 01995 01996 if ( !exp->match( l.value()->stringValue().latin1() ) ) 01997 { 01998 context.setValue( new KSValue( FALSE ) ); 01999 return TRUE; 02000 } 02001 else 02002 { 02003 int len = subst.length(); 02004 int i = 0; 02005 while( i < len ) 02006 { 02007 if ( subst[i] == '\\' && i + 1 < len && subst[i+1].isDigit() ) 02008 { 02009 const char* grp = exp->group( subst[i+1].latin1() - '0' ); 02010 QString repl; 02011 if ( grp ) 02012 repl = grp; 02013 else 02014 repl = ""; 02015 subst.replace( i, 2, repl ); 02016 len += repl.length() + 1; 02017 i += repl.length(); 02018 } 02019 else 02020 ++i; 02021 } 02022 QString& str = l.value()->stringValue(); 02023 str.replace( exp->groupStart( 0 ), exp->groupEnd( 0 ) - exp->groupStart( 0 ), subst ); 02024 } 02025 02026 context.setValue( new KSValue( TRUE ) ); 02027 return TRUE; 02028 } 02029 02030 bool KSEval_t_not( KSParseNode* node, KSContext& context ) 02031 { 02032 if ( !node->branch1()->eval( context ) ) 02033 return false; 02034 02035 if ( !context.value()->cast( KSValue::BoolType ) ) 02036 { 02037 QString tmp( i18n("Unary Operator ! not defined for type %1") ); 02038 context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) ); 02039 return false; 02040 } 02041 02042 context.setValue( new KSValue( !( context.value()->boolValue() ) ) ); 02043 return true; 02044 } 02045 02046 bool KSEval_func_call_params( KSParseNode* node, KSContext& context ) 02047 { 02048 // Get parameter 02049 KSParseNode *left = node->branch1(); 02050 if ( !left ) 02051 return true; 02052 02053 KSContext l( context ); 02054 if ( !left->eval( l ) ) 02055 { 02056 context.setException( l ); 02057 return false; 02058 } 02059 02060 context.value()->listValue().append( l.shareValue() ); 02061 02062 if (left->getType() == t_cell || left->getType() == t_range) 02063 { 02064 context.extraData()->listValue().append(new KSValue(left->getStringLiteral())); 02065 } 02066 else 02067 { 02068 context.extraData()->listValue().append(new KSValue()); 02069 } 02070 02071 // More parameters ? 02072 KSParseNode *right = node->branch2(); 02073 if ( right ) 02074 if ( !right->eval( context ) ) 02075 return false; 02076 02077 return true; 02078 } 02079 02080 bool KSEval_t_return( KSParseNode* node, KSContext& context ) 02081 { 02082 // Get return value if available 02083 KSParseNode *left = node->branch1(); 02084 if ( left ) 02085 { 02086 if ( !left->eval( context ) ) 02087 { 02088 context.setException( context ); 02089 return false; 02090 } 02091 02092 // We may not return a LeftExpr here => make a copy 02093 if ( context.value()->mode() == KSValue::LeftExpr ) 02094 { 02095 KSValue* v = new KSValue( *context.value() ); 02096 context.setValue( v ); 02097 } 02098 } 02099 // No return value 02100 else 02101 { 02102 // TODO: return the none object here -> faster 02103 context.setValue( new KSValue() ); 02104 } 02105 02106 context.setReturnFlag(); 02107 02108 return true; 02109 } 02110 02111 bool KSEval_destructor_dcl( KSParseNode* node, KSContext& context ) 02112 { 02113 // We want an additional namespace in the scope 02114 KSNamespace nspace; 02115 KSSubScope scope( &nspace ); 02116 context.scope()->pushLocalScope( &scope ); 02117 02118 // Fill parameters in our namespace 02119 if ( node->branch1() ) 02120 if ( !node->branch1()->eval( context ) ) 02121 { 02122 context.scope()->popLocalScope(); 02123 return false; 02124 } 02125 02126 // Are parameters left ? 02127 if ( !context.value()->listValue().isEmpty() ) 02128 { 02129 const QString tmp( i18n("1 argument is not needed", "%n arguments are not needed", context.value()->listValue().count() ) ); 02130 context.setException( new KSException( "TooManyArguments", tmp, node->getLineNo() ) ); 02131 context.scope()->popLocalScope(); 02132 return false; 02133 } 02134 02135 // Call the function 02136 if ( node->branch2() ) 02137 if ( !node->branch2()->eval( context ) ) 02138 { 02139 context.scope()->popLocalScope(); 02140 return false; 02141 } 02142 02143 context.scope()->popLocalScope(); 02144 return true; 02145 } 02146 02147 bool KSEval_import( KSParseNode* node, KSContext& context ) 02148 { 02149 // KSNamespace space; 02150 // TODO: Find module in searchpath 02151 02152 KSContext d( context ); 02153 // This function puts a KSModule in d.value() 02154 if ( !context.interpreter()->runModule( d, node->getIdent() ) ) 02155 { 02156 context.setException( d ); 02157 return false; 02158 } 02159 02160 // Register the imported module in the scope 02161 context.scope()->addObject( node->getIdent(), d.shareValue() ); 02162 02163 return true; 02164 } 02165 02166 bool KSEval_t_struct( KSParseNode* node, KSContext& context ) 02167 { 02168 KSStructClass* p; 02169 02170 // All children should know about the new KSStructClass 02171 context.setValue( new KSValue( ( p = new KSStructClass( context.scope()->module(), node->getIdent() ) ) ) ); 02172 context.scope()->addObject( node->getIdent(), context.shareValue() ); 02173 02174 KSParseNode *left = node->branch1(); 02175 if ( left ) 02176 if ( !left->eval( context ) ) 02177 return false; 02178 02179 context.setValue( 0 ); 02180 02181 return true; 02182 } 02183 02184 bool KSEval_t_struct_members( KSParseNode* node, KSContext& context ) 02185 { 02186 Q_ASSERT( context.value() && context.value()->type() == KSValue::StructClassType ); 02187 02188 context.value()->structClassValue()->addVariable( node->getIdent() ); 02189 02190 // process more members if available 02191 if ( node->branch1() ) 02192 if ( !node->branch1()->eval( context ) ) 02193 return false; 02194 02195 return true; 02196 } 02197 02198 extern bool KSEval_t_qualified_names( KSParseNode* node, KSContext& context ) 02199 { 02200 Q_ASSERT( context.value() && context.value()->type() == KSValue::ListType ); 02201 02202 KSParseNode *left = node->branch1(); 02203 if ( !left ) 02204 return true; 02205 02206 KSContext l( context ); 02207 if ( !left->eval( l ) ) 02208 { 02209 context.setException( l ); 02210 return false; 02211 } 02212 02213 context.value()->listValue().append( l.shareValue() ); 02214 02215 KSParseNode *right = node->branch2(); 02216 if ( !right ) 02217 return true; 02218 02219 if ( !right->eval( context ) ) 02220 return false; 02221 02222 return true; 02223 } 02224 02225 extern bool KSEval_t_scope( KSParseNode* node, KSContext& context ) 02226 { 02227 KSParseNode *left = node->branch1(); 02228 // a construction like "{ }" ? 02229 if ( !left ) 02230 return TRUE; 02231 02232 KSNamespace nspace; 02233 context.scope()->localScope()->pushNamespace( &nspace ); 02234 02235 bool res = left->eval( context ); 02236 02237 context.scope()->localScope()->popNamespace(); 02238 02239 return res; 02240 } 02241 02242 extern bool KSEval_t_try( KSParseNode* node, KSContext& context ) 02243 { 02244 KSNamespace nspace; 02245 context.scope()->localScope()->pushNamespace( &nspace ); 02246 02247 // Execute the questionable code 02248 KSParseNode *left = node->branch1(); 02249 Q_ASSERT( left ); 02250 // No error -> Return 02251 if ( left->eval( context ) ) 02252 { 02253 context.scope()->localScope()->popNamespace(); 02254 return true; 02255 } 02256 02257 // We got an error. First resume the namespace. This 02258 // will do automatically a stack unwinding 02259 context.scope()->localScope()->popNamespace(); 02260 02261 // Execute the catch clauses 02262 KSParseNode *right = node->branch2(); 02263 Q_ASSERT( right ); 02264 return right->eval( context ); 02265 } 02266 02267 extern bool KSEval_t_catch( KSParseNode* node, KSContext& context ) 02268 { 02269 KSContext d( context ); 02270 02271 // Find the type to which we want to compare 02272 KSParseNode *left = node->branch1(); 02273 Q_ASSERT( left ); 02274 if ( !left->eval( d ) ) 02275 { 02276 context.setException( d ); 02277 return false; 02278 } 02279 02280 // Exception of the correct type ? 02281 Q_ASSERT( context.exception() ); 02282 if ( context.exception()->type()->cmp( *d.value() ) ) 02283 { 02284 // Get infos about the exception 02285 KSValue* value = context.exception()->value(); 02286 value->ref(); 02287 02288 // Add variables to the namespace 02289 KSNamespace nspace; 02290 nspace.insert( node->getIdent(), new KSValue( *value ) ); 02291 context.scope()->localScope()->pushNamespace( &nspace ); 02292 02293 // Clear the exception since we caught it 02294 context.setException( 0 ); 02295 02296 // Evaluate the catch code 02297 KSParseNode *right = node->branch2(); 02298 Q_ASSERT( right ); 02299 02300 /* bool res = */ right->eval( context ); 02301 02302 // Resume namespace 02303 context.scope()->localScope()->popNamespace(); 02304 02305 return true; 02306 } 02307 02308 // Could not catch. Try next if available 02309 KSParseNode* more = node->branch4(); 02310 if ( more ) 02311 return more->eval( context ); 02312 02313 // We could not catch :-( 02314 return false; 02315 } 02316 02317 extern bool KSEval_t_catch_default( KSParseNode* node, KSContext& context ) 02318 { 02319 KSContext d( context ); 02320 02321 // Find out na,me of the variable that 02322 // holds the type 02323 KSParseNode *left = node->branch1(); 02324 Q_ASSERT( left ); 02325 QString name1 = left->getIdent(); 02326 02327 // Clear the exception 02328 KSValue* type = context.exception()->type(); 02329 type->ref(); 02330 KSValue* value = context.exception()->value(); 02331 value->ref(); 02332 context.setException( 0 ); 02333 02334 // Add variables to the namespace 02335 KSNamespace nspace; 02336 nspace.insert( name1, new KSValue( *type ) ); 02337 nspace.insert( node->getIdent(), new KSValue( *value ) ); 02338 context.scope()->localScope()->pushNamespace( &nspace ); 02339 02340 // Evaluate the catch code 02341 KSParseNode *right = node->branch2(); 02342 Q_ASSERT( right ); 02343 bool res = right->eval( context ); 02344 02345 context.scope()->localScope()->popNamespace(); 02346 02347 return res; 02348 } 02349 02350 extern bool KSEval_t_raise( KSParseNode* node, KSContext& context ) 02351 { 02352 EVAL_OPS( context, l, r, false ); 02353 02354 // Raise the exception 02355 context.setException( new KSException( l.shareValue(), r.shareValue(), node->getLineNo() ) ); 02356 02357 return false; 02358 } 02359 02360 extern bool KSEval_t_cell( KSParseNode* node, KSContext& context ) 02361 { 02362 return context.interpreter()->processExtension( context, node ); 02363 } 02364 02365 extern bool KSEval_t_range( KSParseNode* node, KSContext& context ) 02366 { 02367 return context.interpreter()->processExtension( context, node ); 02368 } 02369 02370 extern bool KSEval_from( KSParseNode* node, KSContext& context ) 02371 { 02372 // Get the list of symbols which have to be imported. 02373 QStringList lst = QStringList::split( "/", node->getStringLiteral() ); 02374 02375 KSContext d( context ); 02376 // This function puts a KSModule in d.value() 02377 if ( !context.interpreter()->runModule( d, node->getIdent(), node->getIdent() + ".ks", QStringList() ) ) 02378 { 02379 context.setException( d ); 02380 return false; 02381 } 02382 02383 // Register the imported module in the scope 02384 context.scope()->addObject( node->getIdent(), d.shareValue() ); 02385 02386 // Import all symbols ? 02387 // Syntax: "from mymodule import *;" 02388 if ( lst.isEmpty() ) 02389 { 02390 // Iterate over all symbols of the module 02391 KSNamespace::Iterator it = d.value()->moduleValue()->nameSpace()->begin(); 02392 KSNamespace::Iterator end = d.value()->moduleValue()->nameSpace()->end(); 02393 for(; it != end; ++it ) 02394 context.scope()->module()->addObject( it.key(), it.data() ); 02395 } 02396 // Syntax: "from mymodule import sym1, sym2;" 02397 else 02398 { 02399 // Import from this module 02400 KSModule* m = d.value()->moduleValue(); 02401 02402 // Iterate over all symbols that we should import 02403 QStringList::ConstIterator sit = lst.begin(); 02404 for( ; sit != lst.end(); ++sit ) 02405 { 02406 // Symbol known ? 02407 KSValue* v = m->object( *sit ); 02408 if ( !v ) 02409 { 02410 QString tmp( i18n("The module %1 does not contain a symbol named %2") ); 02411 context.setException( new KSException( "SymbolUnknown", 02412 tmp.arg( node->getIdent() ).arg( *sit ), 02413 node->getLineNo() ) ); 02414 return false; 02415 } 02416 02417 // Add the symbol to the current namespace 02418 v->ref(); 02419 context.scope()->module()->addObject( *sit, v ); 02420 } 02421 } 02422 02423 return TRUE; 02424 } 02425 02426 bool KSEval_plus_assign( KSParseNode* node, KSContext& context ) 02427 { 02428 EVAL_OPS( context, l, r, true ); 02429 02430 if ( l.value()->mode() != KSValue::LeftExpr ) 02431 { 02432 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) ); 02433 return false; 02434 } 02435 02436 if ( l.value()->type() == KSValue::TimeType ) 02437 { 02438 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 02439 return false; 02440 QTime t = l.value()->timeValue(); 02441 t = t.addSecs( r.value()->intValue() ); 02442 l.value()->setValue( t ); 02443 } 02444 else if ( l.value()->type() == KSValue::DateType ) 02445 { 02446 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 02447 return false; 02448 QDate d = l.value()->dateValue(); 02449 d = d.addDays( r.value()->intValue() ); 02450 l.value()->setValue( d ); 02451 } 02452 else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 02453 return false; 02454 02455 switch( l.value()->type() ) 02456 { 02457 case KSValue::IntType: 02458 l.value()->setValue( r.value()->intValue() + l.value()->intValue() ); 02459 break; 02460 case KSValue::DoubleType: 02461 l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() ); 02462 break; 02463 case KSValue::StringType: 02464 l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() ); 02465 break; 02466 case KSValue::ListType: 02467 l.value()->setValue( l.value()->listValue() + r.value()->listValue() ); 02468 break; 02469 case KSValue::MapType: 02470 { 02471 QMap<QString,KSValue::Ptr>& map = l.value()->mapValue(); 02472 QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin(); 02473 QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end(); 02474 for( ; it != end; ++it ) 02475 map.insert( it.key(), it.data() ); 02476 } 02477 break; 02478 case KSValue::TimeType: 02479 case KSValue::DateType: 02480 // Handled above 02481 break; 02482 default: 02483 QString tmp( i18n("Operator += not defined for type %1") ); 02484 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 02485 return false; 02486 } 02487 02488 l.value()->setMode( KSValue::LeftExpr ); 02489 02490 context.setValue( l.shareValue() ); 02491 02492 return TRUE; 02493 } 02494 02495 bool KSEval_minus_assign( KSParseNode* node, KSContext& context ) 02496 { 02497 EVAL_OPS( context, l, r, true ); 02498 02499 if ( l.value()->mode() != KSValue::LeftExpr ) 02500 { 02501 context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) ); 02502 return false; 02503 } 02504 02505 if ( l.value()->type() == KSValue::TimeType ) 02506 { 02507 if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) ) 02508 { 02509 QTime d = r.value()->timeValue(); 02510 int diff = d.secsTo( l.value()->timeValue() ); 02511 l.value()->setValue( (KScript::Long)diff ); 02512 } 02513 else 02514 { 02515 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 02516 return false; 02517 QTime t = l.value()->timeValue(); 02518 t = t.addSecs( -r.value()->intValue() ); 02519 l.value()->setValue( t ); 02520 } 02521 } 02522 else if ( l.value()->type() == KSValue::DateType ) 02523 { 02524 if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) ) 02525 { 02526 QDate d = r.value()->dateValue(); 02527 int diff = d.daysTo( l.value()->dateValue() ); 02528 l.value()->setValue( (KScript::Long)diff ); 02529 } 02530 else 02531 { 02532 if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) ) 02533 return false; 02534 QDate d = l.value()->dateValue(); 02535 d = d.addDays( -r.value()->intValue() ); 02536 l.value()->setValue( d ); 02537 } 02538 } 02539 else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) ) 02540 return false; 02541 else 02542 { 02543 switch( l.value()->type() ) 02544 { 02545 case KSValue::IntType: 02546 l.value()->setValue( r.value()->intValue() + l.value()->intValue() ); 02547 break; 02548 case KSValue::DoubleType: 02549 l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() ); 02550 break; 02551 case KSValue::StringType: 02552 l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() ); 02553 break; 02554 case KSValue::ListType: 02555 l.value()->setValue( l.value()->listValue() + r.value()->listValue() ); 02556 break; 02557 case KSValue::MapType: 02558 { 02559 QMap<QString,KSValue::Ptr>& map = l.value()->mapValue(); 02560 QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin(); 02561 QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end(); 02562 for( ; it != end; ++it ) 02563 map.insert( it.key(), it.data() ); 02564 } 02565 break; 02566 case KSValue::TimeType: 02567 case KSValue::DateType: 02568 // Handled above 02569 break; 02570 default: 02571 QString tmp( i18n("Operator += not defined for type %1") ); 02572 context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) ); 02573 return false; 02574 } 02575 } 02576 02577 l.value()->setMode( KSValue::LeftExpr ); 02578 02579 context.setValue( l.shareValue() ); 02580 02581 return TRUE; 02582 } 02583 02584 bool KSEval_bool_or( KSParseNode* node, KSContext& context ) 02585 { 02586 EVAL_OPS( context, l, r, false ); 02587 02588 if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) || 02589 !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) ) 02590 { 02591 context.exception()->addLine( node->getLineNo() ); 02592 return false; 02593 } 02594 02595 context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() || r.value()->boolValue() ) ) ); 02596 02597 return true; 02598 } 02599 02600 bool KSEval_bool_and( KSParseNode* node, KSContext& context ) 02601 { 02602 EVAL_OPS( context, l, r, false ); 02603 02604 if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) || 02605 !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) ) 02606 { 02607 context.exception()->addLine( node->getLineNo() ); 02608 return false; 02609 } 02610 02611 context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() && r.value()->boolValue() ) ) ); 02612 02613 return true; 02614 } 02615 02616 bool KSEval_t_regexp_group( KSParseNode* node, KSContext& context ) 02617 { 02618 KRegExp* exp = context.interpreter()->regexp(); 02619 const char* grp = exp->group( node->getIntegerLiteral() ); 02620 if ( grp ) 02621 context.setValue( new KSValue( QString( grp ) ) ); 02622 else 02623 context.setValue( new KSValue( QString( "" ) ) ); 02624 02625 return TRUE; 02626 } 02627 02628 bool KSEval_t_input( KSParseNode*, KSContext& context ) 02629 { 02630 context.setValue( new KSValue( context.interpreter()->readInput() ) ); 02631 02632 return TRUE; 02633 } 02634 02635 bool KSEval_t_line( KSParseNode* /*node*/, KSContext& context ) 02636 { 02637 context.setValue( context.interpreter()->lastInputLine() ); 02638 02639 return TRUE; 02640 } 02641 02642 bool KSEval_t_match_line( KSParseNode* node, KSContext& context ) 02643 { 02644 KSValue::Ptr line = context.interpreter()->lastInputLine(); 02645 if ( !KSUtil::checkType( context, line, KSValue::StringType, TRUE ) ) 02646 return FALSE; 02647 02648 KRegExp* exp = context.interpreter()->regexp(); 02649 exp->compile( node->getIdent().latin1() ); // regexps are a-zA-Z etc, so latin1 is ok. (David) 02650 02651 context.setValue( new KSValue( exp->match( line->stringValue().latin1() ) ) ); 02652 02653 return TRUE; 02654 }
KDE Logo
This file is part of the documentation for lib Library Version 1.3.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Sep 28 04:04:01 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003