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     // x-gettext: no-c-format
00743     const QString tmp( i18n("1 argument is not needed", "%n arguments are not needed", context.value()->listValue().count() ) );
00744     context.setException( new KSException( "TooManyArguments", tmp, node->getLineNo() ) );
00745     context.scope()->popLocalScope();
00746     return false;
00747   }
00748 
00749   bool res = true;
00750   // Call the function
00751   if ( node->branch2() )
00752     res = node->branch2()->eval( context );
00753 
00754   // Finish stack unwinding
00755   context.clearReturnFlag();
00756 
00757   // Remove the local scope
00758   context.scope()->popLocalScope();
00759 
00760   return res;
00761 }
00762 
00763 bool KSEval_func_lines( KSParseNode* node, KSContext& context )
00764 {
00765   if ( node->branch1() )
00766   {
00767     context.interpreter()->context().setException( 0 ); // ### reset -- HACK (Simon)
00768     if ( !node->branch1()->eval( context ) )
00769       return false;
00770     if ( context.returnFlag() )
00771       return true;
00772     // if ( node->branch1()->getType() == t_return )
00773     // return true;
00774   }
00775 
00776   // We are not interested in the value of the evaluation
00777   // since it is not a return value.
00778   context.setValue( 0 );
00779 
00780   // Did some destructor cause a exception ?
00781   if ( context.interpreter()->context().exception() )
00782   {
00783     context.setException( context.interpreter()->context().exception() );
00784     return false;
00785   }
00786 
00787   // The second branch can only hold a "func_lines" parsenode.
00788   if ( node->branch2() )
00789     if ( !node->branch2()->eval( context ) )
00790       return false;
00791 
00792   return true;
00793 }
00794 
00795 bool KSEval_assign_expr( KSParseNode* node, KSContext& context )
00796 {
00797   EVAL_OPS( context, l, r, true );
00798 
00799   if ( l.value()->mode() != KSValue::LeftExpr )
00800   {
00801     context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
00802     return false;
00803   }
00804 
00805   // Special handling for strings
00806   if ( l.value()->type() == KSValue::CharRefType )
00807   {
00808     if ( !r.value()->cast( KSValue::CharType ) )
00809     {
00810       QString tmp( i18n("From %1 to Char") );
00811       context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
00812       return false;
00813     }
00814     l.value()->charRefValue() = r.value()->charValue();
00815 
00816     // Dont return the CharRef, so create a new value
00817     context.setValue( new KSValue( r.value()->charValue() ) );
00818     return true;
00819   }
00820 
00821   // Special handling for properties
00822   if ( l.value()->type() == KSValue::PropertyType )
00823   {
00824     if ( ! l.value()->propertyValue()->set( context, r.shareValue() ) )
00825       return false;
00826     // Return the value we just assigned
00827     context.setValue( r.shareValue() );
00828   }
00829   else
00830   {
00831     l.value()->suck( r.value() );
00832     // Return the value we just assigned
00833     context.setValue( l.shareValue() );
00834   }
00835   // Now it is a rightexpr. Dont allow to change it -> constant
00836   // context.value()->setMode( KSValue::Constant );
00837 
00838   return true;
00839 }
00840 
00841 bool KSEval_t_equal( KSParseNode* node, KSContext& context )
00842 {
00843   EVAL_OPS( context, l, r, false );
00844 
00845   KScript::Boolean result;
00846   if ( !r.value()->cast( l.value()->type() ) )
00847   {
00848     /* If we can't cast the values to match, then they definitely aren't
00849        equal.  Don't return a parse error here -- our users aren't expected
00850        to have detailed understanding of the syntax.
00851     */
00852     result = false;
00853   }
00854   else
00855   {
00856 
00857     result = ( r.value()->cmp( *l.value() ) );
00858   }
00859 
00860   FILL_VALUE( context, l, r );
00861   context.value()->setValue( result );
00862   return true;
00863 }
00864 
00865 bool KSEval_t_notequal( KSParseNode* node, KSContext& context )
00866 {
00867   EVAL_OPS( context, l, r, false );
00868 
00869   if ( !r.value()->cast( l.value()->type() ) )
00870   {
00871     QString tmp( i18n("From %1 to %2") );
00872     context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ).arg( l.value()->typeName() ), node->getLineNo() ) );
00873     return false;
00874   }
00875 
00876   KScript::Boolean result = !( r.value()->cmp( *l.value() ) );
00877   FILL_VALUE( context, l, r );
00878   context.value()->setValue( result );
00879   return true;
00880 }
00881 
00882 bool KSEval_t_less_or_equal( KSParseNode* node, KSContext& context )
00883 {
00884   EVAL_OPS( context, l, r, false );
00885 
00886   if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
00887     return false;
00888 
00889   switch( l.value()->type() )
00890     {
00891     case KSValue::IntType:
00892       {
00893         KScript::Boolean result = l.value()->intValue() <= r.value()->intValue();
00894         FILL_VALUE( context, l, r );
00895         context.value()->setValue( result );
00896         return true;
00897       }
00898     case KSValue::DoubleType:
00899       {
00900         KScript::Boolean result = l.value()->doubleValue() <= r.value()->doubleValue();
00901         FILL_VALUE( context, l, r );
00902         context.value()->setValue( result );
00903         return true;
00904       }
00905     case KSValue::CharType:
00906       {
00907         KScript::Boolean result = l.value()->charValue() <= r.value()->charValue();
00908         FILL_VALUE( context, l, r );
00909         context.value()->setValue( result );
00910         return true;
00911       }
00912     case KSValue::StringType:
00913       {
00914         KScript::Boolean result = l.value()->stringValue() <= r.value()->stringValue();
00915         FILL_VALUE( context, l, r );
00916         context.value()->setValue( result );
00917         return true;
00918       }
00919     case KSValue::DateType:
00920       {
00921     KScript::Boolean result = l.value()->dateValue() <= r.value()->dateValue();
00922         FILL_VALUE( context, l, r );
00923         context.value()->setValue( result );
00924         return true;
00925       }
00926     case KSValue::TimeType:
00927       {
00928     KScript::Boolean result = l.value()->timeValue() <= r.value()->timeValue();
00929         FILL_VALUE( context, l, r );
00930         context.value()->setValue( result );
00931         return true;
00932       }
00933     default:
00934       QString tmp( i18n("Operator <= not defined for type %1") );
00935       context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
00936       return false;
00937     }
00938 
00939   // Never reached
00940   return false;
00941 }
00942 
00943 bool KSEval_t_greater_or_equal( KSParseNode* node, KSContext& context )
00944 {
00945   EVAL_OPS( context, l, r, false );
00946 
00947   if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
00948     return false;
00949 
00950   switch( l.value()->type() )
00951     {
00952     case KSValue::IntType:
00953       {
00954         KScript::Boolean result = l.value()->intValue() >= r.value()->intValue();
00955         FILL_VALUE( context, l, r );
00956         context.value()->setValue( result );
00957         return true;
00958       }
00959     case KSValue::DoubleType:
00960       {
00961         KScript::Boolean result = l.value()->doubleValue() >= r.value()->doubleValue();
00962         FILL_VALUE( context, l, r );
00963         context.value()->setValue( result );
00964         return true;
00965       }
00966     case KSValue::StringType:
00967       {
00968         KScript::Boolean result = l.value()->stringValue() >= r.value()->stringValue();
00969         FILL_VALUE( context, l, r );
00970         context.value()->setValue( result );
00971         return true;
00972       }
00973     case KSValue::CharType:
00974       {
00975         KScript::Boolean result = l.value()->charValue() >= r.value()->charValue();
00976         FILL_VALUE( context, l, r );
00977         context.value()->setValue( result );
00978         return true;
00979       }
00980     case KSValue::DateType:
00981       {
00982         KScript::Boolean result = l.value()->dateValue() >= r.value()->dateValue();
00983         FILL_VALUE( context, l, r );
00984         context.value()->setValue( result );
00985         return true;
00986       }
00987     case KSValue::TimeType:
00988       {
00989         KScript::Boolean result = l.value()->timeValue() >= r.value()->timeValue();
00990         FILL_VALUE( context, l, r );
00991         context.value()->setValue( result );
00992         return true;
00993       }
00994     default:
00995       QString tmp( i18n("Operator >= not defined for type %1") );
00996       context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
00997       return false;
00998     }
00999 
01000   // Never reached
01001   return false;
01002 }
01003 
01004 bool KSEval_t_array( KSParseNode* node, KSContext& context )
01005 {
01006   EVAL_OPS( context, l, r, false );
01007 
01008   if ( !r.value()->cast( KSValue::IntType ) )
01009   {
01010     QString tmp( i18n("From %1 to Integer in array index") );
01011     context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
01012     return false;
01013   }
01014 
01015   int index = r.value()->intValue();
01016 
01017   if ( index < 0 )
01018   {
01019     QString tmp( i18n("Negative array index %1"));
01020     context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
01021     return false;
01022   }
01023 
01024   // is it a string ? -> special handling
01025   if ( l.value()->type() == KSValue::StringType )
01026   {
01027     int len = l.value()->stringValue().length();
01028 
01029     if ( index >= len && !context.leftExpr() )
01030     {
01031       QString tmp( i18n("Too large index %1"));
01032       context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
01033       return false;
01034     }
01035 
01036     // Get a QChar
01037     if ( !context.leftExpr() )
01038     {
01039       const QString& str = l.value()->stringValue();
01040       context.setValue( new KSValue( str[ index ] ) );
01041       return true;
01042     }
01043 
01044     // Get a CharRef since leftexpr is needed
01045     context.setValue( new KSValue( KScript::CharRef( &(l.value()->stringValue()), index ) ) );
01046     context.value()->setMode( KSValue::LeftExpr );
01047     return true;
01048   }
01049 
01050   if ( !l.value()->cast( KSValue::ListType ) )
01051   {
01052     QString tmp( i18n("From %1 to List") );
01053     context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01054     return false;
01055   }
01056 
01057   int len = l.value()->listValue().count();
01058   if ( index >= len )
01059   {
01060     if ( !context.leftExpr() )
01061     {
01062       QString tmp( i18n("Too large index %1"));
01063       context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
01064       return false;
01065     }
01066     else
01067     {
01068       // Fill the list with empty values
01069       for( int i = 0; i <= index - len; ++i )
01070         l.value()->listValue().append( new KSValue() );
01071     }
01072   }
01073 
01074   context.setValue( l.value()->listValue()[ index ] );
01075   context.value()->setMode( l.value()->mode() );
01076 
01077   return true;
01078 }
01079 
01080 bool KSEval_t_dict( KSParseNode* node, KSContext& context )
01081 {
01082   EVAL_OPS( context, l, r, false );
01083 
01084   if ( !r.value()->cast( KSValue::StringType ) )
01085   {
01086     QString tmp( i18n("From %1 to String in dict") );
01087     context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
01088     return false;
01089   }
01090 
01091   if ( !l.value()->cast( KSValue::MapType ) )
01092   {
01093     QString tmp( i18n("From %1 to Map") );
01094     context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01095     return false;
01096   }
01097 
01098   QMap<QString,KSValue::Ptr>::Iterator it = l.value()->mapValue().find( r.value()->stringValue() );
01099   // Unknown element ?
01100   if ( it == l.value()->mapValue().end() )
01101   {
01102     // No left expr needed-> return <none>
01103     if ( !context.leftExpr() )
01104     {
01105       context.setValue( new KSValue() );
01106       return true;
01107     }
01108     // Left expr needed
01109     //    we got Left expr -> insert empty element
01110     else if ( l.value()->mode() == KSValue::LeftExpr )
01111     {
01112       KSValue::Ptr v( new KSValue() );
01113       v->setMode( l.value()->mode() );
01114       l.value()->mapValue().insert( r.value()->stringValue(), v );
01115       context.setValue( v );
01116       return true;
01117     }
01118     //    we can not provide a left expression
01119     else
01120     {
01121       context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression."), node->getLineNo() ) );
01122       return false;
01123     }
01124   }
01125 
01126   context.setValue( it.data() );
01127   context.value()->setMode( l.value()->mode() );
01128 
01129   return true;
01130 }
01131 
01132 bool KSEval_func_params( KSParseNode* node, KSContext& context )
01133 {
01134   // process a parameter
01135   if ( node->branch1() )
01136     if ( !node->branch1()->eval( context ) )
01137       return false;
01138 
01139   // process more parameters
01140   if ( node->branch2() )
01141     if ( !node->branch2()->eval( context ) )
01142       return false;
01143 
01144   return true;
01145 }
01146 
01147 bool KSEval_func_param_in( KSParseNode* node, KSContext& context )
01148 {
01149   KSValue* v = 0;
01150 
01151   // No more arguments ?
01152   if ( context.value()->listValue().isEmpty() )
01153   {
01154     // Do we have a default Argument ?
01155     if ( node->branch1() )
01156     {
01157       KSContext d( context );
01158       if ( !node->branch1()->eval( d ) )
01159         return false;
01160       if ( d.value()->mode() == KSValue::Temp )
01161         v = d.shareValue();
01162       else
01163         v = new KSValue( *d.value() );
01164     }
01165     else
01166     {
01167       QString tmp( i18n("Argument for parameters %1 missing") );
01168       context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
01169       return false;
01170     }
01171   }
01172   else
01173   {
01174     // Put the arguments as parameter in our namespace
01175     KSValue* arg = *(context.value()->listValue().begin());
01176     if ( arg->mode() == KSValue::Temp )
01177     {
01178       arg->ref();
01179       v = arg;
01180     }
01181     else
01182       v = new KSValue( *arg );
01183 
01184     // Remove the argument from the list
01185     context.value()->listValue().remove( context.value()->listValue().begin() );
01186   }
01187 
01188   v->setMode( KSValue::LeftExpr );
01189   context.scope()->addObject( node->getIdent(), v );
01190 
01191   return true;
01192 }
01193 
01194 bool KSEval_func_param_out( KSParseNode* node, KSContext& context )
01195 {
01196   // No more arguments ?
01197   if ( context.value()->listValue().isEmpty() )
01198   {
01199     QString tmp( i18n("Argument for parameters %1 missing") );
01200     context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
01201     return false;
01202   }
01203 
01204   KSValue* arg = *(context.value()->listValue().begin());
01205 
01206   // Is the argument not a leftexpr ?
01207   if ( arg->mode() != KSValue::LeftExpr )
01208   {
01209     QString tmp( i18n("LeftExpr needed for parameter %1") );
01210     context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
01211     return false;
01212   }
01213 
01214   // The difference between out/inout. We empty the value here to make
01215   // shure that nobody write "out" where he means "inout".
01216   context.value()->clear();
01217 
01218   // Put the arguments as parameter in our namespace
01219   arg->ref();
01220   context.scope()->addObject( node->getIdent(), arg );
01221 
01222   // Remove the argument from the list
01223   context.value()->listValue().remove( context.value()->listValue().begin() );
01224 
01225   return true;
01226 }
01227 
01228 bool KSEval_func_param_inout( KSParseNode* node, KSContext& context )
01229 {
01230   // No more arguments ?
01231   if ( context.value()->listValue().isEmpty() )
01232   {
01233     QString tmp( i18n("Argument for parameters %1 missing") );
01234     context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
01235     return false;
01236   }
01237 
01238   KSValue* arg = *(context.value()->listValue().begin());
01239 
01240   // Is the argument not a leftexpr ?
01241   if ( arg->mode() != KSValue::LeftExpr )
01242   {
01243     QString tmp( i18n("LeftExpr needed for parameter %1") );
01244     context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
01245     return false;
01246   }
01247 
01248   // Put the arguments as parameter in our namespace
01249   arg->ref();
01250   context.scope()->addObject( node->getIdent(), arg );
01251 
01252   // Remove the argument from the list
01253   context.value()->listValue().remove( context.value()->listValue().begin() );
01254 
01255   return true;
01256 }
01257 
01258 bool KSEval_t_func_call( KSParseNode* node, KSContext& context )
01259 {
01260   // Get the function object
01261   KSParseNode *left = node->branch1();
01262   if ( !left )
01263     return true;
01264 
01265   KSContext l( context );
01266   if ( !left->eval( l ) )
01267   {
01268     context.setException( l );
01269     return false;
01270   }
01271 
01272   if ( !l.value()->cast( KSValue::FunctionType ) &&
01273        !l.value()->cast( KSValue::MethodType ) && !l.value()->cast( KSValue::StructClassType ) )
01274   {
01275     QString tmp( i18n("From %1 to Function") );
01276     context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01277     return false;
01278   }
01279 
01280   // Create a list of parameters
01281   context.setValue( new KSValue( KSValue::ListType ) );
01282   context.setExtraData(new KSValue(KSValue::ListType));
01283 
01284   KSParseNode *right = node->branch2();
01285   if ( right )
01286     if ( !right->eval( context ) )
01287       return false;
01288 
01289   // Remove our namespaces
01290   KSSubScope* scope = context.scope()->popLocalScope();
01291   KSModule* module = context.scope()->popModule();
01292 
01293   bool b = FALSE;
01294   if ( l.value()->cast( KSValue::FunctionType ) )
01295   {
01296     context.scope()->pushModule( l.value()->functionValue()->module() );
01297     // Call the function
01298     b = l.value()->functionValue()->call( context );
01299     context.scope()->popModule();
01300   }
01301   else if ( l.value()->cast( KSValue::StructClassType ) )
01302   {
01303     context.scope()->pushModule( l.value()->structClassValue()->module() );
01304     // Call struct constructor
01305     b = l.value()->structClassValue()->constructor( context );
01306     context.scope()->popModule();
01307   }
01308   else if ( l.value()->cast( KSValue::MethodType ) )
01309   {
01310     context.scope()->pushModule( l.value()->methodValue()->module() );
01311     // Call method
01312     b = l.value()->methodValue()->call( context );
01313     context.scope()->popModule();
01314   }
01315   else
01316     Q_ASSERT( 0 );
01317 
01318   // Resume namespaces
01319   context.scope()->pushLocalScope( scope );
01320   context.scope()->pushModule( module );
01321 
01322   if ( !b )
01323     return false;
01324 
01325   // Lets have at least a <none> as return value
01326   if ( !context.value() )
01327     context.setValue( KSValue::null() );
01328 
01329   return true;
01330 }
01331 
01332 bool KSEval_member_expr( KSParseNode* node, KSContext& context )
01333 {
01334   KSParseNode *left = node->branch1();
01335   Q_ASSERT( left );
01336 
01337   // This resets leftExpr to FALSE
01338   KSContext l( context );
01339   // Try to find the object
01340   if ( !left->eval( l ) )
01341   {
01342     context.setException( l );
01343     return false;
01344   }
01345 
01352   if ( l.value()->type() == KSValue::FunctionType || l.value()->type() == KSValue::MethodType )
01353   {
01354         // Copy l.value to func
01355         KSContext func( context );
01356         func.setValue( new KSValue( *l.value() ) );
01357 
01358         // Create a list of parameters
01359         l.setValue( new KSValue( KSValue::ListType ) );
01360 
01361         // Remove our namespaces
01362         KSSubScope* scope = l.scope()->popLocalScope();
01363         KSModule* module = l.scope()->popModule();
01364 
01365         bool b = FALSE;
01366         if ( func.value()->type() == KSValue::FunctionType )
01367         {
01368             l.scope()->pushModule( l.value()->functionValue()->module() );
01369             // Call the function
01370             b = func.value()->functionValue()->call( l );
01371             l.scope()->popModule();
01372         }
01373         else if ( func.value()->type() == KSValue::MethodType )
01374         {
01375             l.scope()->pushModule( l.value()->methodValue()->module() );
01376             // Call method
01377             b = func.value()->methodValue()->call( l );
01378             l.scope()->popModule();
01379         }
01380         else
01381             Q_ASSERT( 0 );
01382 
01383         // Resume namespaces
01384         l.scope()->pushLocalScope( scope );
01385         l.scope()->pushModule( module );
01386 
01387         if ( !b )
01388         {
01389             context.setException( l.exception() );
01390             return false;
01391         }
01392 
01393         // Lets have at least a <none> as return value
01394         if ( !l.value() )
01395             l.setValue( KSValue::null() );
01396   }
01399   // Special handling for modules
01400   if ( l.value()->cast( KSValue::ModuleType ) )
01401   {
01402     KSValue::Ptr v = l.value()->moduleValue()->member( context, node->getIdent() );
01403     if ( !v )
01404     {
01405       context.exception()->addLine( node->getLineNo() );
01406       return false;
01407     }
01408 
01409     context.setValue( v );
01410 
01411     return true;
01412   }
01413   // Special handling for struct classes
01414   else if ( l.value()->cast( KSValue::StructClassType ) )
01415   {
01416     KSValue::Ptr v = l.value()->structClassValue()->member( context, node->getIdent() );
01417     if ( !v )
01418     {
01419       context.exception()->addLine( node->getLineNo() );
01420       return false;
01421     }
01422 
01423     context.setValue( v );
01424 
01425     return true;
01426   }
01427 
01428   KSValue::Ptr v;
01429   KSModule* module;
01430   if ( l.value()->cast( KSValue::StructType ) )
01431   {
01432     v = l.value()->structValue()->member( context, node->getIdent() );
01433     module = l.value()->structValue()->module();
01434   }
01435   // Special handling for all kind of built in data types
01436   else
01437   {
01438     KSValue* v = context.object( node->getIdent() );
01439     if ( !v )
01440     {
01441       context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) );
01442       return false;
01443     }
01444     if ( v->type() != KSValue::FunctionType )
01445     {
01446       KSUtil::castingError( context, v, KSValue::FunctionType );
01447       return false;
01448     }
01449     v->ref();
01450     context.setValue( new KSValue( new KSMethod( context.scope()->module(), l.shareValue(), v ) ) );
01451     return true;
01452   }
01453   /*
01454   else
01455   {
01456     QString tmp( "From %1 to Object" );
01457     context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01458     return false;
01459     } */
01460 
01461   if ( !v )
01462   {
01463     context.exception()->addLine( node->getLineNo() );
01464     return false;
01465   }
01466 
01467   if ( v->type() == KSValue::FunctionType  )
01468       context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v ) ) );
01469   else if ( v->type() == KSValue::StructBuiltinMethodType )
01470     context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v, node->getIdent() ) ) );
01471   else
01472       context.setValue( v );
01473 
01474   return true;
01475 }
01476 
01477 bool KSEval_t_array_const( KSParseNode* node, KSContext& context )
01478 {
01479   context.setValue( new KSValue( KSValue::ListType ) );
01480 
01481   KSParseNode *right = node->branch1();
01482   if ( !right )
01483     return true;
01484 
01485   if ( !right->eval( context ) )
01486     return false;
01487 
01488   return true;
01489 }
01490 
01491 bool KSEval_t_array_element( KSParseNode* node, KSContext& context )
01492 {
01493   KSParseNode *left = node->branch1();
01494   if ( !left )
01495     return true;
01496 
01497   KSContext l( context );
01498   if ( !left->eval( l ) )
01499   {
01500     context.setException( l );
01501     return false;
01502   }
01503 
01504   if ( l.value()->mode() == KSValue::Temp )
01505   {
01506     l.value()->ref();
01507     context.value()->listValue().append( KSValue::Ptr( l.value() ) );
01508   }
01509   else
01510   {
01511     KSValue::Ptr v( new KSValue );
01512     v->suck( l.value() );
01513     context.value()->listValue().append( v );
01514   }
01515 
01516   KSParseNode *right = node->branch2();
01517   if ( !right )
01518     return true;
01519 
01520   if ( !right->eval( context ) )
01521     return false;
01522 
01523   return true;
01524 }
01525 
01526 bool KSEval_t_dict_const( KSParseNode* node, KSContext& context )
01527 {
01528   context.setValue( new KSValue( KSValue::MapType ) );
01529 
01530   KSParseNode *right = node->branch1();
01531   if ( !right )
01532     return true;
01533 
01534   if ( !right->eval( context ) )
01535     return false;
01536 
01537   return true;
01538 }
01539 
01540 bool KSEval_t_dict_element( KSParseNode* node, KSContext& context )
01541 {
01542   EVAL_OPS( context, l, r, false );
01543 
01544   if ( !l.value()->cast( KSValue::StringType ) )
01545   {
01546     QString tmp( i18n("From %1 to String") );
01547     context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
01548     return false;
01549   }
01550 
01551   if ( r.value()->mode() == KSValue::Temp )
01552   {
01553     r.value()->ref();
01554     context.value()->mapValue().insert( l.value()->stringValue(), KSValue::Ptr( r.value() ) );
01555   }
01556   else
01557   {
01558     KSValue::Ptr v( new KSValue );
01559     v->suck( r.value() );
01560     context.value()->mapValue().insert( l.value()->stringValue(), v );
01561   }
01562 
01563   KSParseNode *next = node->branch3();
01564   if ( !next )
01565     return true;
01566 
01567   if ( !next->eval( context ) )
01568     return false;
01569 
01570   return true;
01571 }
01572 
01573 bool KSEval_t_while( KSParseNode* node, KSContext& context )
01574 {
01575   do
01576   {
01577     EVAL_LEFT_OP( context, l );
01578 
01579     if ( !l.value()->implicitCast( KSValue::BoolType ) )
01580     {
01581       QString tmp( i18n("From %1 to Boolean") );
01582       context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01583       return false;
01584     }
01585 
01586     // Head of the while loop
01587     if ( !l.value()->boolValue() )
01588       return true;
01589 
01590     // Tail of the while loop
01591     EVAL_RIGHT_OP( context, r );
01592   } while( 1 );
01593 
01594   // Never reached
01595   return false;
01596 }
01597 
01598 bool KSEval_t_do( KSParseNode* node, KSContext& context )
01599 {
01600   do
01601   {
01602     // Body of the loop
01603     if ( !node->branch1()->eval( context ) )
01604       return false;
01605 
01606     // Tail
01607     if ( !node->branch2()->eval( context ) )
01608       return false;
01609 
01610     if ( !context.value()->cast( KSValue::BoolType ) )
01611     {
01612       KSUtil::castingError( context, context.value(), KSValue::BoolType );
01613       return false;
01614     }
01615 
01616     // Head of the while loop
01617     if ( !context.value()->boolValue() )
01618       return true;
01619 
01620   } while( 1 );
01621 
01622   // Never reached
01623   return false;
01624 }
01625 
01626 bool KSEval_t_for( KSParseNode* node, KSContext& context )
01627 {
01628   // Evaluate the start code
01629   if ( !node->branch1()->eval( context ) )
01630     return false;
01631 
01632   do
01633   {
01634     // Evaluate the condition
01635     if ( !node->branch2()->eval( context ) )
01636       return false;
01637 
01638     if ( !context.value()->cast( KSValue::BoolType ) )
01639     {
01640       KSUtil::castingError( context, context.value(), KSValue::BoolType );
01641       return false;
01642     }
01643 
01644     // Condition failed ?
01645     if ( !context.value()->boolValue() )
01646       return true;
01647 
01648     // Evaluate the body
01649     if ( !node->branch4()->eval( context ) )
01650       return false;
01651 
01652     // Evaluate the iterator
01653     if ( !node->branch3()->eval( context ) )
01654       return false;
01655 
01656   } while(1);
01657 
01658   // Bever reached
01659   return false;
01660 }
01661 
01662 bool KSEval_t_if( KSParseNode* node, KSContext& context )
01663 {
01664   // Evaluate the condition
01665   if ( !node->branch1()->eval( context ) )
01666     return false;
01667 
01668   if ( !context.value()->cast( KSValue::BoolType ) )
01669   {
01670     KSUtil::castingError( context, context.value(), KSValue::BoolType );
01671     return false;
01672   }
01673 
01674   // Condition failed ?
01675   if ( !context.value()->boolValue() )
01676   {
01677     if ( node->branch3() )
01678       return node->branch3()->eval( context );
01679     return true;
01680   }
01681 
01682   return node->branch2()->eval( context );
01683 }
01684 
01685 bool KSEval_t_incr( KSParseNode* node, KSContext& context )
01686 {
01687   // Evaluate the expression
01688   if ( !node->branch1()->eval( context ) )
01689     return false;
01690 
01691   if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
01692     return false;
01693 
01694   if ( context.value()->mode() != KSValue::LeftExpr )
01695   {
01696     context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
01697     return false;
01698   }
01699 
01700   // postfix ?
01701   if ( node->branch2() )
01702   {
01703     KSValue::Ptr p = context.shareValue();
01704     KScript::Long l = p->intValue();
01705     p->setValue( p->intValue() + 1 );
01706     context.setValue( new KSValue( l ) );
01707     context.value()->setMode( KSValue::Temp );
01708   }
01709   else
01710     context.value()->setValue( context.value()->intValue() + 1 );
01711 
01712   return true;
01713 }
01714 
01715 bool KSEval_t_decr( KSParseNode* node, KSContext& context )
01716 {
01717   // Evaluate the expression
01718   if ( !node->branch1()->eval( context ) )
01719     return false;
01720 
01721   if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
01722     return false;
01723 
01724   if ( context.value()->mode() != KSValue::LeftExpr )
01725   {
01726     context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) );
01727     return false;
01728   }
01729 
01730   // postfix ?
01731   if ( node->branch2() )
01732   {
01733     KSValue::Ptr p = context.shareValue();
01734     KScript::Long l = p->intValue();
01735     p->setValue( p->intValue() - 1 );
01736     context.setValue( new KSValue( l ) );
01737     context.value()->setMode( KSValue::Temp );
01738   }
01739   else
01740     context.value()->setValue( context.value()->intValue() - 1 );
01741 
01742   return true;
01743 }
01744 
01745 bool KSEval_t_less( KSParseNode* node, KSContext& context )
01746 {
01747   EVAL_OPS( context, l, r, false );
01748 
01749   if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
01750     return false;
01751 
01752   switch( l.value()->type() )
01753     {
01754     case KSValue::IntType:
01755       {
01756         KScript::Boolean result = l.value()->intValue() < r.value()->intValue();
01757         FILL_VALUE( context, l, r );
01758         context.value()->setValue( result );
01759         return true;
01760       }
01761     case KSValue::DoubleType:
01762       {
01763         KScript::Boolean result = l.value()->doubleValue() < r.value()->doubleValue();
01764         FILL_VALUE( context, l, r );
01765         context.value()->setValue( result );
01766         return true;
01767       }
01768     case KSValue::StringType:
01769       {
01770         KScript::Boolean result = l.value()->stringValue() < r.value()->stringValue();
01771         FILL_VALUE( context, l, r );
01772         context.value()->setValue( result );
01773         return true;
01774       }
01775     case KSValue::DateType:
01776       {
01777         KScript::Boolean result = l.value()->dateValue() < r.value()->dateValue();
01778         FILL_VALUE( context, l, r );
01779         context.value()->setValue( result );
01780         return true;
01781       }
01782     case KSValue::TimeType:
01783       {
01784         KScript::Boolean result = l.value()->timeValue() < r.value()->timeValue();
01785         FILL_VALUE( context, l, r );
01786         context.value()->setValue( result );
01787         return true;
01788       }
01789     case KSValue::CharType:
01790       {
01791         KScript::Boolean result = l.value()->charValue() < r.value()->charValue();
01792         FILL_VALUE( context, l, r );
01793         context.value()->setValue( result );
01794         return true;
01795       }
01796     default:
01797       QString tmp( i18n("Operator < not defined for type %1") );
01798       context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01799       return false;
01800     }
01801 
01802   // Never reached
01803   return false;
01804 }
01805 
01806 bool KSEval_t_greater( KSParseNode* node, KSContext& context )
01807 {
01808   EVAL_OPS( context, l, r, false );
01809 
01810   if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
01811     return false;
01812 
01813   switch( l.value()->type() )
01814     {
01815     case KSValue::IntType:
01816       {
01817         KScript::Boolean result = l.value()->intValue() > r.value()->intValue();
01818         FILL_VALUE( context, l, r );
01819         context.value()->setValue( result );
01820         return true;
01821       }
01822     case KSValue::DoubleType:
01823       {
01824         KScript::Boolean result = l.value()->doubleValue() > r.value()->doubleValue();
01825         FILL_VALUE( context, l, r );
01826         context.value()->setValue( result );
01827         return true;
01828       }
01829     case KSValue::StringType:
01830       {
01831         KScript::Boolean result = l.value()->stringValue() > r.value()->stringValue();
01832         FILL_VALUE( context, l, r );
01833         context.value()->setValue( result );
01834         return true;
01835       }
01836     case KSValue::CharType:
01837       {
01838         KScript::Boolean result = l.value()->charValue() > r.value()->charValue();
01839         FILL_VALUE( context, l, r );
01840         context.value()->setValue( result );
01841         return true;
01842       }
01843    case KSValue::DateType:
01844       {
01845         KScript::Boolean result = l.value()->dateValue() > r.value()->dateValue();
01846         FILL_VALUE( context, l, r );
01847         context.value()->setValue( result );
01848         return true;
01849       }
01850     case KSValue::TimeType:
01851       {
01852         KScript::Boolean result = l.value()->timeValue() > r.value()->timeValue();
01853         FILL_VALUE( context, l, r );
01854         context.value()->setValue( result );
01855         return true;
01856       }
01857     default:
01858       QString tmp( i18n("Operator > not defined for type %1") );
01859       context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
01860       return false;
01861     }
01862 
01863   // Never reached
01864   return false;
01865 }
01866 
01867 
01868 bool KSEval_t_foreach( KSParseNode* node, KSContext& context )
01869 {
01870   // Evaluate the list/map
01871   if ( !node->branch1()->eval( context ) )
01872     return false;
01873 
01874   // Is the array a LeftExpr, Temp or Constant
01875   KSValue::Mode mode = context.value()->mode();
01876 
01877   // Little hack to test wether we are in list or map mode
01878   if ( node->branch3() )
01879   {
01880     if ( !context.value()->cast( KSValue::MapType ) )
01881     {
01882       KSUtil::castingError( context, context.value(), KSValue::MapType );
01883       return false;
01884     }
01885 
01886     KSNamespace nspace;
01887     context.scope()->localScope()->pushNamespace( &nspace );
01888 
01889     QMap<QString,KSValue::Ptr>::Iterator it = context.value()->mapValue().begin();
01890     QMap<QString,KSValue::Ptr>::Iterator end = context.value()->mapValue().end();
01891     for( ; it != end; ++it )
01892     {
01893       // Get the element of the map in the local scope
01894       it.data()->ref();
01895       KSValue* v = it.data();
01896       // Same mode as the array
01897       v->setMode( mode );
01898       context.scope()->addObject( node->getStringLiteral(), v );
01899 
01900       // Get the key of the map in the local scope
01901       v = new KSValue( it.key() );
01902       v->setMode( KSValue::Constant );
01903       context.scope()->addObject( node->getIdent(), v );
01904 
01905       // Evaluate the body
01906       KSContext ctx( context );
01907       if ( !node->branch2()->eval( ctx ) )
01908       {
01909         context.setException( ctx );
01910         context.scope()->localScope()->popNamespace();
01911         return false;
01912       }
01913     }
01914 
01915     context.scope()->localScope()->popNamespace();
01916   }
01917   else
01918   {
01919     if ( !context.value()->cast( KSValue::ListType ) )
01920     {
01921       KSUtil::castingError( context, context.value(), KSValue::ListType );
01922       return false;
01923     }
01924 
01925     KSNamespace nspace;
01926     context.scope()->localScope()->pushNamespace( &nspace );
01927 
01928     QValueList<KSValue::Ptr>::Iterator it = context.value()->listValue().begin();
01929     QValueList<KSValue::Ptr>::Iterator end = context.value()->listValue().end();
01930     for( ; it != end; ++it )
01931     {
01932       // Get the element of the array in our local variable
01933       (*it)->ref();
01934       KSValue* v = (*it);
01935       // Same mode as the array
01936       v->setMode( mode );
01937       context.scope()->addObject( node->getIdent(), v );
01938 
01939       // Evaluate the body
01940       KSContext ctx( context );
01941       if ( !node->branch2()->eval( ctx ) )
01942       {
01943         context.setException( ctx );
01944         context.scope()->localScope()->popNamespace();
01945         return false;
01946       }
01947     }
01948 
01949     context.scope()->localScope()->popNamespace();
01950   }
01951 
01952   return true;
01953 }
01954 
01955 bool KSEval_t_match( KSParseNode* node , KSContext& context )
01956 {
01957     if ( !node->branch1()->eval( context ) )
01958         return false;
01959 
01960     if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) )
01961         return FALSE;
01962 
01963     KRegExp* exp = context.interpreter()->regexp();
01964     exp->compile( node->getIdent().latin1() ); // identifiers are a-zA-Z etc, so latin1 is ok. (David)
01965 
01966     kdDebug() << "Matching " << context.value()->stringValue() << " against " << node->getIdent() << endl;
01967 
01968     context.setValue( new KSValue( exp->match( context.value()->stringValue().latin1() ) ) );
01969 
01970     return TRUE;
01971 }
01972 
01973 bool KSEval_t_subst( KSParseNode* node, KSContext& context )
01974 {
01975     KSContext l( context, TRUE );
01976     if ( !node->branch1()->eval( l ) )
01977         return false;
01978 
01979     if ( l.value()->mode() != KSValue::LeftExpr )
01980     {
01981         context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in substitute."), node->getLineNo() ) );
01982         return false;
01983     }
01984 
01985     if ( !KSUtil::checkType( l, l.value(), KSValue::StringType, TRUE ) )
01986         return FALSE;
01987 
01988     int pos = node->getIdent().find( '/' );
01989     Q_ASSERT( pos != -1 );
01990     QString match = node->getIdent().left( pos );
01991     QString subst = node->getIdent().mid( pos + 1 );
01992     KRegExp* exp = context.interpreter()->regexp();
01993     exp->compile( match.latin1() ); // identifiers are a-zA-Z etc, so latin1 is ok. (David)
01994 
01995     kdDebug() << "Matching " << l.value()->stringValue() << " against " << node->getIdent() << endl;
01996 
01997     if ( !exp->match( l.value()->stringValue().latin1() ) )
01998     {
01999         context.setValue( new KSValue( FALSE ) );
02000         return TRUE;
02001     }
02002     else
02003     {
02004         int len = subst.length();
02005         int i = 0;
02006         while( i < len )
02007         {
02008             if ( subst[i] == '\\' && i + 1 < len && subst[i+1].isDigit() )
02009             {
02010                 const char* grp = exp->group( subst[i+1].latin1() - '0' );
02011                 QString repl;
02012                 if ( grp )
02013                     repl = grp;
02014                 else
02015                     repl = "";
02016                 subst.replace( i, 2, repl );
02017                 len += repl.length() + 1;
02018                 i += repl.length();
02019             }
02020             else
02021                 ++i;
02022         }
02023         QString& str = l.value()->stringValue();
02024         str.replace( exp->groupStart( 0 ), exp->groupEnd( 0 ) - exp->groupStart( 0 ), subst );
02025     }
02026 
02027     context.setValue( new KSValue( TRUE ) );
02028     return TRUE;
02029 }
02030 
02031 bool KSEval_t_not( KSParseNode* node, KSContext& context )
02032 {
02033   if ( !node->branch1()->eval( context ) )
02034     return false;
02035 
02036   if ( !context.value()->cast( KSValue::BoolType ) )
02037   {
02038     QString tmp( i18n("Unary Operator ! not defined for type %1") );
02039     context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
02040     return false;
02041   }
02042 
02043   context.setValue( new KSValue( !( context.value()->boolValue() ) ) );
02044   return true;
02045 }
02046 
02047 bool KSEval_func_call_params( KSParseNode* node, KSContext& context )
02048 {
02049   // Get parameter
02050   KSParseNode *left = node->branch1();
02051   if ( !left )
02052     return true;
02053 
02054   KSContext l( context );
02055   if ( !left->eval( l ) )
02056   {
02057     context.setException( l );
02058     return false;
02059   }
02060 
02061   context.value()->listValue().append( l.shareValue() );
02062 
02063   if (left->getType() == t_cell || left->getType() == t_range)
02064   {
02065     context.extraData()->listValue().append(new KSValue(left->getStringLiteral()));
02066   }
02067   else
02068   {
02069     context.extraData()->listValue().append(new KSValue());
02070   }
02071 
02072   // More parameters ?
02073   KSParseNode *right = node->branch2();
02074   if ( right )
02075     if ( !right->eval( context ) )
02076       return false;
02077 
02078   return true;
02079 }
02080 
02081 bool KSEval_t_return( KSParseNode* node, KSContext& context )
02082 {
02083   // Get return value if available
02084   KSParseNode *left = node->branch1();
02085   if ( left )
02086   {
02087     if ( !left->eval( context ) )
02088     {
02089       context.setException( context );
02090       return false;
02091     }
02092 
02093     // We may not return a LeftExpr here => make a copy
02094     if ( context.value()->mode() == KSValue::LeftExpr )
02095     {
02096       KSValue* v = new KSValue( *context.value() );
02097       context.setValue( v );
02098     }
02099   }
02100   // No return value
02101   else
02102   {
02103     // TODO: return the none object here -> faster
02104     context.setValue( new KSValue() );
02105   }
02106 
02107   context.setReturnFlag();
02108 
02109   return true;
02110 }
02111 
02112 bool KSEval_destructor_dcl( KSParseNode* node, KSContext& context )
02113 {
02114   // We want an additional namespace in the scope
02115   KSNamespace nspace;
02116   KSSubScope scope( &nspace );
02117   context.scope()->pushLocalScope( &scope );
02118 
02119   // Fill parameters in our namespace
02120   if ( node->branch1() )
02121     if ( !node->branch1()->eval( context ) )
02122     {
02123       context.scope()->popLocalScope();
02124       return false;
02125     }
02126 
02127   // Are parameters left ?
02128   if ( !context.value()->listValue().isEmpty() )
02129   {
02130     // x-gettext: no-c-format
02131     const QString tmp( i18n("1 argument is not needed", "%n arguments are not needed", context.value()->listValue().count() ) );
02132     context.setException( new KSException( "TooManyArguments", tmp, node->getLineNo() ) );
02133     context.scope()->popLocalScope();
02134     return false;
02135   }
02136 
02137   // Call the function
02138   if ( node->branch2() )
02139     if ( !node->branch2()->eval( context ) )
02140     {
02141       context.scope()->popLocalScope();
02142       return false;
02143     }
02144 
02145   context.scope()->popLocalScope();
02146   return true;
02147 }
02148 
02149 bool KSEval_import( KSParseNode* node, KSContext& context )
02150 {
02151     // KSNamespace space;
02152   // TODO: Find module in searchpath
02153 
02154   KSContext d( context );
02155   // This function puts a KSModule in d.value()
02156   if ( !context.interpreter()->runModule( d, node->getIdent() ) )
02157   {
02158     context.setException( d );
02159     return false;
02160   }
02161 
02162   // Register the imported module in the scope
02163   context.scope()->addObject( node->getIdent(), d.shareValue() );
02164 
02165   return true;
02166 }
02167 
02168 bool KSEval_t_struct( KSParseNode* node, KSContext& context )
02169 {
02170   KSStructClass* p;
02171 
02172   // All children should know about the new KSStructClass
02173   context.setValue( new KSValue( ( p = new KSStructClass( context.scope()->module(), node->getIdent() ) ) ) );
02174   context.scope()->addObject( node->getIdent(), context.shareValue() );
02175 
02176   KSParseNode *left = node->branch1();
02177   if ( left )
02178       if ( !left->eval( context ) )
02179           return false;
02180 
02181   context.setValue( 0 );
02182 
02183   return true;
02184 }
02185 
02186 bool KSEval_t_struct_members( KSParseNode* node, KSContext& context )
02187 {
02188   Q_ASSERT( context.value() && context.value()->type() == KSValue::StructClassType );
02189 
02190   context.value()->structClassValue()->addVariable( node->getIdent() );
02191 
02192   // process more members if available
02193   if ( node->branch1() )
02194     if ( !node->branch1()->eval( context ) )
02195       return false;
02196 
02197   return true;
02198 }
02199 
02200 extern bool KSEval_t_qualified_names( KSParseNode* node, KSContext& context )
02201 {
02202   Q_ASSERT( context.value() && context.value()->type() == KSValue::ListType );
02203 
02204   KSParseNode *left = node->branch1();
02205   if ( !left )
02206     return true;
02207 
02208   KSContext l( context );
02209   if ( !left->eval( l ) )
02210   {
02211     context.setException( l );
02212     return false;
02213   }
02214 
02215   context.value()->listValue().append( l.shareValue() );
02216 
02217   KSParseNode *right = node->branch2();
02218   if ( !right )
02219     return true;
02220 
02221   if ( !right->eval( context ) )
02222     return false;
02223 
02224   return true;
02225 }
02226 
02227 extern bool KSEval_t_scope( KSParseNode* node, KSContext& context )
02228 {
02229     KSParseNode *left = node->branch1();
02230     // a construction like "{ }" ?
02231     if ( !left )
02232         return TRUE;
02233 
02234     KSNamespace nspace;
02235     context.scope()->localScope()->pushNamespace( &nspace );
02236 
02237     bool res = left->eval( context );
02238 
02239     context.scope()->localScope()->popNamespace();
02240 
02241     return res;
02242 }
02243 
02244 extern bool KSEval_t_try( KSParseNode* node, KSContext& context )
02245 {
02246   KSNamespace nspace;
02247   context.scope()->localScope()->pushNamespace( &nspace );
02248 
02249   // Execute the questionable code
02250   KSParseNode *left = node->branch1();
02251   Q_ASSERT( left );
02252   // No error -> Return
02253   if ( left->eval( context ) )
02254   {
02255     context.scope()->localScope()->popNamespace();
02256     return true;
02257   }
02258 
02259   // We got an error. First resume the namespace. This
02260   // will do automatically a stack unwinding
02261   context.scope()->localScope()->popNamespace();
02262 
02263   // Execute the catch clauses
02264   KSParseNode *right = node->branch2();
02265   Q_ASSERT( right );
02266   return right->eval( context );
02267 }
02268 
02269 extern bool KSEval_t_catch( KSParseNode* node, KSContext& context )
02270 {
02271   KSContext d( context );
02272 
02273   // Find the type to which we want to compare
02274   KSParseNode *left = node->branch1();
02275   Q_ASSERT( left );
02276   if ( !left->eval( d ) )
02277   {
02278     context.setException( d );
02279     return false;
02280   }
02281 
02282   // Exception of the correct type ?
02283   Q_ASSERT( context.exception() );
02284   if ( context.exception()->type()->cmp( *d.value() ) )
02285   {
02286      // Get infos about the exception
02287     KSValue* value = context.exception()->value();
02288     value->ref();
02289 
02290     // Add variables to the namespace
02291     KSNamespace nspace;
02292     nspace.insert( node->getIdent(), new KSValue( *value ) );
02293     context.scope()->localScope()->pushNamespace( &nspace );
02294 
02295     // Clear the exception since we caught it
02296     context.setException( 0 );
02297 
02298     // Evaluate the catch code
02299     KSParseNode *right = node->branch2();
02300     Q_ASSERT( right );
02301 
02302     /* bool res = */ right->eval( context );
02303 
02304     // Resume namespace
02305     context.scope()->localScope()->popNamespace();
02306 
02307     return true;
02308   }
02309 
02310   // Could not catch. Try next if available
02311   KSParseNode* more = node->branch4();
02312   if ( more )
02313     return more->eval( context );
02314 
02315   // We could not catch :-(
02316   return false;
02317 }
02318 
02319 extern bool KSEval_t_catch_default( KSParseNode* node, KSContext& context )
02320 {
02321   KSContext d( context );
02322 
02323   // Find out na,me of the variable that
02324   // holds the type
02325   KSParseNode *left = node->branch1();
02326   Q_ASSERT( left );
02327   QString name1 = left->getIdent();
02328 
02329   // Clear the exception
02330   KSValue* type = context.exception()->type();
02331   type->ref();
02332   KSValue* value = context.exception()->value();
02333   value->ref();
02334   context.setException( 0 );
02335 
02336   // Add variables to the namespace
02337   KSNamespace nspace;
02338   nspace.insert( name1, new KSValue( *type ) );
02339   nspace.insert( node->getIdent(), new KSValue( *value ) );
02340   context.scope()->localScope()->pushNamespace( &nspace );
02341 
02342   // Evaluate the catch code
02343   KSParseNode *right = node->branch2();
02344   Q_ASSERT( right );
02345   bool res = right->eval( context );
02346 
02347   context.scope()->localScope()->popNamespace();
02348 
02349   return res;
02350 }
02351 
02352 extern bool KSEval_t_raise( KSParseNode* node, KSContext& context )
02353 {
02354   EVAL_OPS( context, l, r, false );
02355 
02356   // Raise the exception
02357   context.setException( new KSException( l.shareValue(), r.shareValue(), node->getLineNo() ) );
02358 
02359   return false;
02360 }
02361 
02362 extern bool KSEval_t_cell( KSParseNode* node, KSContext& context )
02363 {
02364   return context.interpreter()->processExtension( context, node );
02365 }
02366 
02367 extern bool KSEval_t_range( KSParseNode* node, KSContext& context )
02368 {
02369   return context.interpreter()->processExtension( context, node );
02370 }
02371 
02372 extern bool KSEval_from( KSParseNode* node, KSContext& context )
02373 {
02374     // Get the list of symbols which have to be imported.
02375     QStringList lst = QStringList::split( "/", node->getStringLiteral() );
02376 
02377     KSContext d( context );
02378     // This function puts a KSModule in d.value()
02379     if ( !context.interpreter()->runModule( d, node->getIdent(), node->getIdent() + ".ks", QStringList() ) )
02380     {
02381         context.setException( d );
02382         return false;
02383     }
02384 
02385     // Register the imported module in the scope
02386     context.scope()->addObject( node->getIdent(), d.shareValue() );
02387 
02388     // Import all symbols ?
02389     // Syntax: "from mymodule import *;"
02390     if ( lst.isEmpty() )
02391     {
02392         // Iterate over all symbols of the module
02393         KSNamespace::Iterator it = d.value()->moduleValue()->nameSpace()->begin();
02394         KSNamespace::Iterator end = d.value()->moduleValue()->nameSpace()->end();
02395         for(; it != end; ++it )
02396             context.scope()->module()->addObject( it.key(), it.data() );
02397     }
02398     // Syntax: "from mymodule import sym1, sym2;"
02399     else
02400     {
02401         // Import from this module
02402         KSModule* m = d.value()->moduleValue();
02403 
02404         // Iterate over all symbols that we should import
02405         QStringList::ConstIterator sit = lst.begin();
02406         for( ; sit != lst.end(); ++sit )
02407         {
02408             // Symbol known ?
02409             KSValue* v = m->object( *sit );
02410             if ( !v )
02411             {
02412                 QString tmp( i18n("The module %1 does not contain a symbol named %2") );
02413                 context.setException( new KSException( "SymbolUnknown",
02414                                                        tmp.arg( node->getIdent() ).arg( *sit ),
02415                                                        node->getLineNo() ) );
02416                 return false;
02417             }
02418 
02419             // Add the symbol to the current namespace
02420             v->ref();
02421             context.scope()->module()->addObject( *sit, v );
02422         }
02423     }
02424 
02425     return TRUE;
02426 }
02427 
02428 bool KSEval_plus_assign( KSParseNode* node, KSContext& context )
02429 {
02430     EVAL_OPS( context, l, r, true );
02431 
02432     if ( l.value()->mode() != KSValue::LeftExpr )
02433     {
02434         context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) );
02435         return false;
02436     }
02437 
02438     if ( l.value()->type() == KSValue::TimeType )
02439     {
02440         if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
02441             return false;
02442         QTime t = l.value()->timeValue();
02443         t = t.addSecs( r.value()->intValue() );
02444         l.value()->setValue( t );
02445     }
02446     else if ( l.value()->type() == KSValue::DateType )
02447     {
02448         if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
02449             return false;
02450         QDate d = l.value()->dateValue();
02451         d = d.addDays( r.value()->intValue() );
02452         l.value()->setValue( d );
02453     }
02454     else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
02455         return false;
02456 
02457     switch( l.value()->type() )
02458     {
02459     case KSValue::IntType:
02460         l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
02461         break;
02462     case KSValue::DoubleType:
02463         l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
02464         break;
02465     case KSValue::StringType:
02466         l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
02467         break;
02468     case KSValue::ListType:
02469         l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
02470         break;
02471     case KSValue::MapType:
02472         {
02473             QMap<QString,KSValue::Ptr>& map = l.value()->mapValue();
02474             QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin();
02475             QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end();
02476             for( ; it != end; ++it )
02477                 map.insert( it.key(), it.data() );
02478         }
02479         break;
02480     case KSValue::TimeType:
02481     case KSValue::DateType:
02482         // Handled above
02483         break;
02484     default:
02485       QString tmp( i18n("Operator += not defined for type %1") );
02486       context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
02487       return false;
02488     }
02489 
02490     l.value()->setMode( KSValue::LeftExpr );
02491 
02492     context.setValue( l.shareValue() );
02493 
02494     return TRUE;
02495 }
02496 
02497 bool KSEval_minus_assign( KSParseNode* node, KSContext& context )
02498 {
02499     EVAL_OPS( context, l, r, true );
02500 
02501     if ( l.value()->mode() != KSValue::LeftExpr )
02502     {
02503         context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment."), node->getLineNo() ) );
02504         return false;
02505     }
02506 
02507     if ( l.value()->type() == KSValue::TimeType )
02508     {
02509         if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) )
02510         {
02511             QTime d = r.value()->timeValue();
02512             int diff = d.secsTo( l.value()->timeValue() );
02513             l.value()->setValue( (KScript::Long)diff );
02514         }
02515         else
02516         {
02517             if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
02518                 return false;
02519             QTime t = l.value()->timeValue();
02520             t = t.addSecs( -r.value()->intValue() );
02521             l.value()->setValue( t );
02522         }
02523     }
02524     else if ( l.value()->type() == KSValue::DateType )
02525     {
02526         if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) )
02527         {
02528             QDate d = r.value()->dateValue();
02529             int diff = d.daysTo( l.value()->dateValue() );
02530             l.value()->setValue( (KScript::Long)diff );
02531         }
02532         else
02533         {
02534             if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
02535                 return false;
02536             QDate d = l.value()->dateValue();
02537             d = d.addDays( -r.value()->intValue() );
02538             l.value()->setValue( d );
02539         }
02540     }
02541     else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
02542         return false;
02543     else
02544     {
02545         switch( l.value()->type() )
02546         {
02547         case KSValue::IntType:
02548             l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
02549             break;
02550         case KSValue::DoubleType:
02551             l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
02552             break;
02553         case KSValue::StringType:
02554             l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
02555             break;
02556         case KSValue::ListType:
02557             l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
02558             break;
02559         case KSValue::MapType:
02560         {
02561             QMap<QString,KSValue::Ptr>& map = l.value()->mapValue();
02562             QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin();
02563             QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end();
02564             for( ; it != end; ++it )
02565                 map.insert( it.key(), it.data() );
02566         }
02567         break;
02568         case KSValue::TimeType:
02569         case KSValue::DateType:
02570             // Handled above
02571             break;
02572         default:
02573             QString tmp( i18n("Operator += not defined for type %1") );
02574             context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
02575             return false;
02576         }
02577     }
02578 
02579     l.value()->setMode( KSValue::LeftExpr );
02580 
02581     context.setValue( l.shareValue() );
02582 
02583     return TRUE;
02584 }
02585 
02586 bool KSEval_bool_or( KSParseNode* node, KSContext& context )
02587 {
02588     EVAL_OPS( context, l, r, false );
02589 
02590     if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
02591          !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
02592     {
02593         context.exception()->addLine( node->getLineNo() );
02594         return false;
02595     }
02596 
02597     context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() || r.value()->boolValue() ) ) );
02598 
02599     return true;
02600 }
02601 
02602 bool KSEval_bool_and( KSParseNode* node, KSContext& context )
02603 {
02604     EVAL_OPS( context, l, r, false );
02605 
02606     if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
02607          !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
02608     {
02609         context.exception()->addLine( node->getLineNo() );
02610         return false;
02611     }
02612 
02613     context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() && r.value()->boolValue() ) ) );
02614 
02615     return true;
02616 }
02617 
02618 bool KSEval_t_regexp_group( KSParseNode* node, KSContext& context )
02619 {
02620     KRegExp* exp = context.interpreter()->regexp();
02621     const char* grp = exp->group( node->getIntegerLiteral() );
02622     if ( grp )
02623         context.setValue( new KSValue( QString( grp ) ) );
02624     else
02625         context.setValue( new KSValue( QString( "" ) ) );
02626 
02627     return TRUE;
02628 }
02629 
02630 bool KSEval_t_input( KSParseNode*, KSContext& context )
02631 {
02632     context.setValue( new KSValue( context.interpreter()->readInput() ) );
02633 
02634     return TRUE;
02635 }
02636 
02637 bool KSEval_t_line( KSParseNode* /*node*/, KSContext& context )
02638 {
02639     context.setValue( context.interpreter()->lastInputLine() );
02640 
02641     return TRUE;
02642 }
02643 
02644 bool KSEval_t_match_line( KSParseNode* node, KSContext& context )
02645 {
02646     KSValue::Ptr line = context.interpreter()->lastInputLine();
02647     if ( !KSUtil::checkType( context, line, KSValue::StringType, TRUE ) )
02648         return FALSE;
02649 
02650     KRegExp* exp = context.interpreter()->regexp();
02651     exp->compile( node->getIdent().latin1() ); // regexps are a-zA-Z etc, so latin1 is ok. (David)
02652 
02653     context.setValue( new KSValue( exp->match( line->stringValue().latin1() ) ) );
02654 
02655     return TRUE;
02656 }
KDE Logo
This file is part of the documentation for lib Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:40:07 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003