lib Library API Documentation

koscript_eval.cc

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