~ubuntu-branches/ubuntu/breezy/koffice/breezy

« back to all changes in this revision

Viewing changes to lib/kscript/kscript_eval.cc

  • Committer: Bazaar Package Importer
  • Author(s): Ben Burton
  • Date: 2004-05-09 11:33:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040509113300-vfrdadqsvjfuhn3b
Tags: 1:1.3.1-1
* New upstream bugfix release.
* Built against newer imagemagick (closes: #246623).
* Made koffice-libs/kformula recommend/depend on latex-xft-fonts, which
  provides mathematical fonts that the formula editor can use.  Also
  patched the kformula part to make these fonts the default.
* Changed kword menu hint from "WordProcessors" to "Word processors"
  (closes: #246209).
* Spellchecker configuration is now fixed (closes: #221256, #227568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "kscript_eval.h"
2
 
#include "kscript_value.h"
3
 
#include "kscript_context.h"
4
 
#include "kscript_func.h"
5
 
#include "kscript_class.h"
6
 
#include "kscript_object.h"
7
 
#include "kscript_struct.h"
8
 
#include "kscript_proxy.h"
9
 
#include "kscript_qobject.h"
10
 
#include "kscript.h"
11
 
#include "kscript_parsenode.h"
12
 
#include "kscript_util.h"
13
 
#include <stdio.h>
14
 
 
15
 
#include <kregexp.h>
16
 
 
17
 
#include <qfileinfo.h>
18
 
#include <klocale.h>
19
 
 
20
 
// Get a left and right operand for arithmetic
21
 
// operations like add, mul, div etc. If leftexpr
22
 
// is true, then the left value must be assignable.
23
 
#define EVAL_OPS( ctx, l, r, leftexpr ) \
24
 
  KSParseNode *left = node->branch1();  \
25
 
  KSParseNode *right = node->branch2(); \
26
 
  if ( !left || !right )                \
27
 
    return false;                       \
28
 
                                        \
29
 
  KSContext l( ctx, leftexpr );         \
30
 
  KSContext r( ctx );                   \
31
 
  if ( !left->eval( l ) )               \
32
 
  {                                     \
33
 
    ctx.setException( l );              \
34
 
    return false;                       \
35
 
  }                                     \
36
 
  if ( !right->eval( r ) )              \
37
 
  {                                     \
38
 
    ctx.setException( r );              \
39
 
    return false;                       \
40
 
  }
41
 
 
42
 
#define EVAL_LEFT_OP( ctx, l )          \
43
 
  KSParseNode *left = node->branch1();  \
44
 
  if ( !left )                          \
45
 
    return false;                       \
46
 
                                        \
47
 
  KSContext l( ctx );                   \
48
 
  if ( !left->eval( l ) )               \
49
 
  {                                     \
50
 
    ctx.setException( l );              \
51
 
    return false;                       \
52
 
  }                                     \
53
 
 
54
 
#define EVAL_RIGHT_OP( ctx, r )         \
55
 
  KSParseNode *right = node->branch2(); \
56
 
  if ( !right )                         \
57
 
    return false;                       \
58
 
                                        \
59
 
  KSContext r( ctx );                   \
60
 
  if ( !right->eval( r ) )              \
61
 
  {                                     \
62
 
    ctx.setException( r );              \
63
 
    return false;                       \
64
 
  }                                     \
65
 
 
66
 
// Try to reuse one of the KSValue objects l or r
67
 
// and assign it to ctx. This is faster than the default
68
 
// behaviour of creating a new KSValue object all the time.
69
 
#define FILL_VALUE( ctx, l, r )                  \
70
 
  if ( l.value()->mode() == KSValue::Temp )      \
71
 
    ctx.setValue( l.shareValue() );              \
72
 
  else if ( r.value()->mode() == KSValue::Temp ) \
73
 
    ctx.setValue( r.shareValue() );              \
74
 
  else                                           \
75
 
    ctx.setValue( new KSValue );
76
 
 
77
 
bool KSEval_definitions( KSParseNode* node, KSContext& context )
78
 
{
79
 
  if ( node->branch1() )
80
 
  {
81
 
    if ( node->branch1()->getType() == func_dcl )
82
 
    {
83
 
      ASSERT( context.scope() );
84
 
      context.scope()->addObject( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
85
 
    }
86
 
    else if ( !node->branch1()->eval( context ) )
87
 
      return false;
88
 
  }
89
 
  if ( node->branch2() )
90
 
  {
91
 
    if ( node->branch2()->getType() == func_dcl )
92
 
    {
93
 
      ASSERT( context.scope() );
94
 
      context.scope()->addObject( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
95
 
    }
96
 
    else if ( !node->branch2()->eval( context ) )
97
 
      return false;
98
 
  }
99
 
 
100
 
  return true;
101
 
}
102
 
 
103
 
bool KSEval_exports( KSParseNode* node, KSContext& context )
104
 
{
105
 
  ASSERT( context.value() );
106
 
 
107
 
  if ( context.value()->type() == KSValue::ClassType )
108
 
  {
109
 
    if ( node->branch1() )
110
 
    {
111
 
      if ( node->branch1()->getType() == func_dcl )
112
 
        context.value()->classValue()->nameSpace()->insert( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
113
 
      else if ( node->branch1()->getType() == destructor_dcl )
114
 
        context.value()->classValue()->nameSpace()->insert( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
115
 
      else if ( node->branch1()->getType() == signal_dcl )
116
 
        context.value()->classValue()->nameSpace()->insert( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
117
 
      else if ( !node->branch1()->eval( context ) )
118
 
        return false;
119
 
    }
120
 
    if ( node->branch2() )
121
 
    {
122
 
      if ( node->branch2()->getType() == func_dcl )
123
 
        context.value()->classValue()->nameSpace()->insert( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
124
 
      else if ( node->branch2()->getType() == destructor_dcl )
125
 
        context.value()->classValue()->nameSpace()->insert( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
126
 
      else if ( node->branch2()->getType() == signal_dcl )
127
 
        context.value()->classValue()->nameSpace()->insert( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
128
 
      else if ( !node->branch2()->eval( context ) )
129
 
        return false;
130
 
    }
131
 
  }
132
 
  else if ( context.value()->type() == KSValue::StructClassType )
133
 
  {
134
 
    if ( node->branch1() )
135
 
    {
136
 
      if ( node->branch1()->getType() == func_dcl )
137
 
        context.value()->structClassValue()->nameSpace()->insert( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
138
 
      else if ( !node->branch1()->eval( context ) )
139
 
        return false;
140
 
    }
141
 
    if ( node->branch2() )
142
 
    {
143
 
      if ( node->branch2()->getType() == func_dcl )
144
 
        context.value()->structClassValue()->nameSpace()->insert( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
145
 
      else if ( !node->branch2()->eval( context ) )
146
 
        return false;
147
 
    }
148
 
  }
149
 
  else
150
 
    ASSERT( 0 );
151
 
 
152
 
  return true;
153
 
}
154
 
 
155
 
bool KSEval_t_vertical_line( KSParseNode* node, KSContext& context )
156
 
{
157
 
    EVAL_OPS( context, l, r, false );
158
 
 
159
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
160
 
         !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
161
 
    {
162
 
        context.exception()->addLine( node->getLineNo() );
163
 
        return false;
164
 
    }
165
 
 
166
 
    context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() | r.value()->intValue() ) ) );
167
 
 
168
 
    return true;
169
 
}
170
 
 
171
 
bool KSEval_t_circumflex( KSParseNode* node, KSContext& context )
172
 
{
173
 
    EVAL_OPS( context, l, r, false );
174
 
 
175
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
176
 
         !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
177
 
    {
178
 
        context.exception()->addLine( node->getLineNo() );
179
 
        return false;
180
 
    }
181
 
 
182
 
    context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() ^ r.value()->intValue() ) ) );
183
 
 
184
 
    return true;
185
 
}
186
 
 
187
 
bool KSEval_t_ampersand( KSParseNode* node, KSContext& context )
188
 
{
189
 
    EVAL_OPS( context, l, r, false );
190
 
 
191
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
192
 
         !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
193
 
    {
194
 
        context.exception()->addLine( node->getLineNo() );
195
 
        return false;
196
 
    }
197
 
 
198
 
    context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() & r.value()->intValue() ) ) );
199
 
 
200
 
    return true;
201
 
}
202
 
 
203
 
bool KSEval_t_shiftright( KSParseNode* node, KSContext& context )
204
 
{
205
 
    EVAL_OPS( context, l, r, false );
206
 
 
207
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
208
 
         !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
209
 
    {
210
 
        context.exception()->addLine( node->getLineNo() );
211
 
        return false;
212
 
    }
213
 
 
214
 
    context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() >> r.value()->intValue() ) ) );
215
 
 
216
 
    return true;
217
 
}
218
 
 
219
 
bool KSEval_t_shiftleft( KSParseNode* node, KSContext& context )
220
 
{
221
 
    EVAL_OPS( context, l, r, false );
222
 
 
223
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
224
 
         !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
225
 
    {
226
 
        context.exception()->addLine( node->getLineNo() );
227
 
        return false;
228
 
    }
229
 
 
230
 
    context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() << r.value()->intValue() ) ) );
231
 
 
232
 
    return true;
233
 
}
234
 
 
235
 
bool KSEval_t_plus_sign( KSParseNode* node, KSContext& context )
236
 
{
237
 
  // Unary ?
238
 
  if ( node->branch1() && !node->branch2() )
239
 
  {
240
 
    if ( !node->branch1()->eval( context ) )
241
 
      return false;
242
 
    if ( context.value()->cast( KSValue::IntType ) )
243
 
      return true;
244
 
    if ( context.value()->cast( KSValue::DoubleType ) )
245
 
      return true;
246
 
 
247
 
    QString tmp( i18n("Unary Operator + not defined for type %1") );
248
 
    context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
249
 
    return false;
250
 
  }
251
 
 
252
 
  // Binary operator
253
 
  EVAL_OPS( context, l, r, false );
254
 
 
255
 
  if ( l.value()->type() == KSValue::TimeType )
256
 
  {
257
 
      if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
258
 
          return false;
259
 
      QTime t = l.value()->timeValue();
260
 
      t = t.addSecs( r.value()->intValue() );
261
 
      FILL_VALUE( context, l, r );
262
 
      context.value()->setValue( t );
263
 
      return TRUE;
264
 
  }
265
 
  else if ( l.value()->type() == KSValue::DateType )
266
 
  {
267
 
      if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
268
 
          return false;
269
 
      QDate d = l.value()->dateValue();
270
 
      d = d.addDays( r.value()->intValue() );
271
 
      FILL_VALUE( context, l, r );
272
 
      context.value()->setValue( d );
273
 
      return TRUE;
274
 
  }
275
 
  // If we have double and int, then always convert to double
276
 
  else if ( l.value()->type() == KSValue::DoubleType )
277
 
  {
278
 
      if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
279
 
          return false;
280
 
  }
281
 
  else
282
 
  {
283
 
      if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
284
 
          return false;
285
 
  }
286
 
 
287
 
  switch( l.value()->type() )
288
 
    {
289
 
    case KSValue::IntType:
290
 
      {
291
 
        KScript::Long result = r.value()->intValue() + l.value()->intValue();
292
 
        FILL_VALUE( context, l, r );
293
 
        context.value()->setValue( result );
294
 
        return true;
295
 
      }
296
 
      break;
297
 
    case KSValue::DoubleType:
298
 
      {
299
 
        KScript::Double result = l.value()->doubleValue() + r.value()->doubleValue();
300
 
        FILL_VALUE( context, l, r );
301
 
        context.value()->setValue( result );
302
 
        return true;
303
 
      }
304
 
    case KSValue::StringType:
305
 
      {
306
 
        QString result = l.value()->stringValue() + r.value()->stringValue();
307
 
        FILL_VALUE( context, l, r );
308
 
        context.value()->setValue( result );
309
 
        return true;
310
 
      }
311
 
      break;
312
 
    case KSValue::ListType:
313
 
      {
314
 
        QValueList<KSValue::Ptr> result = l.value()->listValue() + r.value()->listValue();
315
 
        FILL_VALUE( context, l, r );
316
 
        context.value()->setValue( result );
317
 
        return true;
318
 
      }
319
 
      break;
320
 
    case KSValue::MapType:
321
 
      {
322
 
          QMap<QString,KSValue::Ptr> result = l.value()->mapValue();
323
 
          QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin();
324
 
          QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end();
325
 
          for( ; it != end; ++it )
326
 
              result.insert( it.key(), it.data() );
327
 
        FILL_VALUE( context, l, r );
328
 
        context.value()->setValue( result );
329
 
        return true;
330
 
      }
331
 
      break;
332
 
    case KSValue::DateType:
333
 
    case KSValue::TimeType:
334
 
        // Handled above
335
 
        return true;
336
 
    default:
337
 
      QString tmp( i18n("Operator + not defined for type %1") );
338
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
339
 
      return false;
340
 
    }
341
 
 
342
 
  // Never reached
343
 
  return false;
344
 
}
345
 
 
346
 
bool KSEval_t_minus_sign( KSParseNode* node, KSContext& context )
347
 
{
348
 
  // Unary ?
349
 
  if ( node->branch1() && !node->branch2() )
350
 
  {
351
 
    if ( !node->branch1()->eval( context ) )
352
 
      return false;
353
 
    if ( context.value()->type() == KSValue::IntType )
354
 
    {
355
 
      context.setValue( new KSValue( -( context.value()->intValue() ) ) );
356
 
      return true;
357
 
    }
358
 
    if ( context.value()->type() == KSValue::DoubleType )
359
 
    {
360
 
      context.setValue( new KSValue( -( context.value()->doubleValue() ) ) );
361
 
      return true;
362
 
    }
363
 
 
364
 
    QString tmp( i18n("Unary Operator - not defined for type %1") );
365
 
    context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
366
 
    return false;
367
 
  }
368
 
 
369
 
  EVAL_OPS( context, l, r, false );
370
 
 
371
 
  if ( l.value()->type() == KSValue::TimeType )
372
 
  {
373
 
      if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) )
374
 
      {
375
 
          QTime d = r.value()->timeValue();
376
 
          int diff = d.secsTo( l.value()->timeValue() );
377
 
          FILL_VALUE( context, l, r );
378
 
          context.value()->setValue( (KScript::Long) diff );
379
 
          return TRUE;
380
 
      }
381
 
 
382
 
      if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
383
 
          return false;
384
 
      QTime t = l.value()->timeValue();
385
 
      t = t.addSecs( -r.value()->intValue() );
386
 
      FILL_VALUE( context, l, r );
387
 
      context.value()->setValue( t );
388
 
      return TRUE;
389
 
  }
390
 
  else if ( l.value()->type() == KSValue::DateType )
391
 
  {
392
 
      if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) )
393
 
      {
394
 
          QDate d = r.value()->dateValue();
395
 
          int diff = d.daysTo( l.value()->dateValue() );
396
 
          FILL_VALUE( context, l, r );
397
 
          context.value()->setValue( (KScript::Long)diff );
398
 
          return TRUE;
399
 
      }
400
 
 
401
 
      if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
402
 
          return false;
403
 
      QDate d = l.value()->dateValue();
404
 
      d = d.addDays( -r.value()->intValue() );
405
 
      FILL_VALUE( context, l, r );
406
 
      context.value()->setValue( d );
407
 
      return TRUE;
408
 
  }
409
 
  // If we have double and int, then always convert to double
410
 
  else if ( l.value()->type() == KSValue::DoubleType )
411
 
  {
412
 
    if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
413
 
      return false;
414
 
  }
415
 
  else
416
 
  {
417
 
    if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
418
 
      return false;
419
 
  }
420
 
 
421
 
  switch( l.value()->type() )
422
 
    {
423
 
    case KSValue::IntType:
424
 
      {
425
 
        KScript::Long result = l.value()->intValue() - r.value()->intValue();
426
 
        FILL_VALUE( context, l, r );
427
 
        context.value()->setValue( result );
428
 
        return true;
429
 
      }
430
 
    case KSValue::DoubleType:
431
 
      {
432
 
        KScript::Double result = l.value()->doubleValue() - r.value()->doubleValue();
433
 
        FILL_VALUE( context, l, r );
434
 
        context.value()->setValue( result );
435
 
        return true;
436
 
      }
437
 
    default:
438
 
      QString tmp( i18n("Operator - not defined for type %1") );
439
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
440
 
      return false;
441
 
    }
442
 
 
443
 
  // Never reached
444
 
  return false;
445
 
}
446
 
 
447
 
bool KSEval_t_asterik( KSParseNode* node, KSContext& context )
448
 
{
449
 
  EVAL_OPS( context, l, r, false );
450
 
 
451
 
  // If we have double and int, then always convert to double
452
 
  if ( l.value()->type() == KSValue::DoubleType )
453
 
  {
454
 
    if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
455
 
      return false;
456
 
  }
457
 
  else
458
 
  {
459
 
    if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
460
 
      return false;
461
 
  }
462
 
 
463
 
  switch( l.value()->type() )
464
 
    {
465
 
    case KSValue::IntType:
466
 
      {
467
 
        KScript::Long result = r.value()->intValue() * l.value()->intValue();
468
 
        FILL_VALUE( context, l, r );
469
 
        context.value()->setValue( result );
470
 
        return true;
471
 
      }
472
 
    case KSValue::DoubleType:
473
 
      {
474
 
        KScript::Double result = r.value()->doubleValue() * l.value()->doubleValue();
475
 
        FILL_VALUE( context, l, r );
476
 
        context.value()->setValue( result );
477
 
        return true;
478
 
      }
479
 
    default:
480
 
      QString tmp( i18n("Operator * not defined for type %1") );
481
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
482
 
      return false;
483
 
    }
484
 
 
485
 
  // Never reached
486
 
  return false;
487
 
}
488
 
 
489
 
bool KSEval_t_solidus( KSParseNode* node, KSContext& context )
490
 
{
491
 
  EVAL_OPS( context, l, r, false );
492
 
 
493
 
  // If we have double and int, then always convert to double
494
 
  if ( l.value()->type() == KSValue::DoubleType )
495
 
  {
496
 
    if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
497
 
      return false;
498
 
  }
499
 
  else
500
 
  {
501
 
    if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
502
 
      return false;
503
 
  }
504
 
 
505
 
  switch( l.value()->type() )
506
 
    {
507
 
    case KSValue::IntType:
508
 
      {
509
 
        // If the devision has a "rest" then we have to convert to doubles
510
 
        if ( ( l.value()->intValue() % r.value()->intValue() ) == 0 )
511
 
        {
512
 
          KScript::Long result = l.value()->intValue() / r.value()->intValue();
513
 
          FILL_VALUE( context, l, r );
514
 
          context.value()->setValue( result );
515
 
        }
516
 
        else
517
 
        {
518
 
          KScript::Double result = (double)l.value()->intValue() / (double)r.value()->intValue();
519
 
          FILL_VALUE( context, l, r );
520
 
          context.value()->setValue( result );
521
 
        }
522
 
        return true;
523
 
      }
524
 
    case KSValue::DoubleType:
525
 
      {
526
 
        KScript::Double result = l.value()->doubleValue() / r.value()->doubleValue();
527
 
        FILL_VALUE( context, l, r );
528
 
        context.value()->setValue( result );
529
 
        return true;
530
 
      }
531
 
    default:
532
 
      QString tmp( i18n("Operator / not defined for type %1") );
533
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
534
 
      return false;
535
 
    }
536
 
 
537
 
  // Never reached
538
 
  return false;
539
 
}
540
 
 
541
 
bool KSEval_t_percent_sign( KSParseNode* node, KSContext& context )
542
 
{
543
 
  EVAL_OPS( context, l, r, false );
544
 
 
545
 
  if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) )
546
 
    return false;
547
 
  if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
548
 
    return false;
549
 
 
550
 
  KScript::Long result = l.value()->intValue() % r.value()->intValue();
551
 
  FILL_VALUE( context, l, r );
552
 
  context.value()->setValue( result );
553
 
  return true;
554
 
}
555
 
 
556
 
bool KSEval_t_tilde( KSParseNode* , KSContext& ) { return false; }
557
 
 
558
 
bool KSEval_t_integer_literal( KSParseNode* node, KSContext& context )
559
 
{
560
 
  context.setValue( new KSValue( node->getIntegerLiteral() ) );
561
 
  return true;
562
 
}
563
 
 
564
 
bool KSEval_t_string_literal( KSParseNode* node, KSContext& context )
565
 
{
566
 
  context.setValue( new KSValue( node->getStringLiteral() ) );
567
 
  return true;
568
 
}
569
 
 
570
 
bool KSEval_t_character_literal( KSParseNode* node, KSContext& context )
571
 
{
572
 
  context.setValue( new KSValue( node->getCharacterLiteral() ) );
573
 
  return true;
574
 
}
575
 
 
576
 
bool KSEval_t_floating_pt_literal( KSParseNode* node, KSContext& context )
577
 
{
578
 
  context.setValue( new KSValue( node->getFloatingPtLiteral() ) );
579
 
  return true;
580
 
}
581
 
 
582
 
bool KSEval_t_boolean_literal( KSParseNode* node, KSContext& context )
583
 
{
584
 
  context.setValue( new KSValue( node->getBooleanLiteral() ) );
585
 
  return true;
586
 
}
587
 
 
588
 
bool KSEval_scoped_name( KSParseNode* node, KSContext& context )
589
 
{
590
 
  KSValue* v = context.object( node->getIdent() );
591
 
  if ( !v )
592
 
  {
593
 
    context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) );
594
 
    return false;
595
 
  }
596
 
 
597
 
  v->ref();
598
 
  context.setValue( v );
599
 
 
600
 
  return true;
601
 
}
602
 
 
603
 
 
604
 
bool KSEval_const_dcl( KSParseNode* node, KSContext& context )
605
 
{
606
 
  ASSERT( node->branch1() );
607
 
 
608
 
  KSContext( l );
609
 
  if ( !node->branch1()->eval( l ) )
610
 
  {
611
 
    context.setException( l );
612
 
    return false;
613
 
  }
614
 
 
615
 
  if ( !context.value() )
616
 
    context.scope()->addObject( node->getIdent(), l.shareValue() );
617
 
  else if ( context.value()->type() == KSValue::ClassType )
618
 
    context.value()->classValue()->nameSpace()->insert( node->getIdent(), l.shareValue() );
619
 
  else if ( context.value()->type() == KSValue::StructClassType )
620
 
    context.value()->structClassValue()->nameSpace()->insert( node->getIdent(), l.shareValue() );
621
 
  else
622
 
    ASSERT( 0 );
623
 
 
624
 
  return true;
625
 
}
626
 
 
627
 
bool KSEval_t_pragma( KSParseNode*, KSContext& ) { return false; }
628
 
 
629
 
bool KSEval_class_dcl( KSParseNode* node, KSContext& context )
630
 
{
631
 
  KSParseNode *left = node->branch1();
632
 
  ASSERT( left );
633
 
 
634
 
  // All child nodes should know about the new KSScriptClass
635
 
  context.setValue( new KSValue( new KSScriptClass( context.scope()->module(), left->getIdent(), node ) ) );
636
 
 
637
 
  if ( !left->eval( context ) )
638
 
    return false;
639
 
 
640
 
  KSParseNode *right = node->branch2();
641
 
  if ( right )
642
 
    if ( !right->eval( context ) )
643
 
      return false;
644
 
 
645
 
  context.setValue( 0 );
646
 
 
647
 
  return true;
648
 
}
649
 
 
650
 
bool KSEval_class_header( KSParseNode* node, KSContext& context )
651
 
{
652
 
  ASSERT( context.value() && context.value()->type() == KSValue::ClassType );
653
 
 
654
 
  // TODO: Avoid circles in super classes
655
 
 
656
 
  // Is the symbol already used ?
657
 
  KSValue* v = context.scope()->object( node->getIdent() );
658
 
  if ( v )
659
 
  {
660
 
    QString tmp( i18n("The symbol %1 is defined twice") );
661
 
    context.setException( new KSException( "SymbolDefinedTwice", tmp.arg( node->getIdent() ), node->getLineNo() ) );
662
 
    return false;
663
 
  }
664
 
 
665
 
  context.scope()->addObject( node->getIdent(), context.shareValue() );
666
 
 
667
 
  // Search super classes
668
 
  KSContext l( context );
669
 
  KSParseNode *left = node->branch1();
670
 
  if ( !left )
671
 
    return true;
672
 
 
673
 
  l.setValue( new KSValue( KSValue::ListType ) );
674
 
 
675
 
  if ( !left->eval( l ) )
676
 
  {
677
 
    context.setException( l );
678
 
    return false;
679
 
  }
680
 
 
681
 
  context.value()->classValue()->setSuperClasses( l.value()->listValue() );
682
 
 
683
 
  return true;
684
 
}
685
 
 
686
 
bool KSEval_func_dcl( KSParseNode* node, KSContext& context )
687
 
{
688
 
  // We want an additional namespace in the scope
689
 
  KSNamespace nspace;
690
 
  KSSubScope scope( &nspace );
691
 
  context.scope()->pushLocalScope( &scope );
692
 
 
693
 
  // Fill parameters in our namespace
694
 
  if ( node->branch1() )
695
 
    if ( !node->branch1()->eval( context ) )
696
 
    {
697
 
      context.scope()->popLocalScope();
698
 
      return false;
699
 
    }
700
 
 
701
 
  // Are parameters left ?
702
 
  if ( !context.value()->listValue().isEmpty() )
703
 
  {
704
 
    QString tmp( i18n("%1 arguments are not needed") );
705
 
    context.setException( new KSException( "TooManyArguments", tmp.arg( context.value()->listValue().count() ), node->getLineNo() ) );
706
 
    context.scope()->popLocalScope();
707
 
    return false;
708
 
  }
709
 
 
710
 
  bool res = true;
711
 
  // Call the function
712
 
  if ( node->branch2() )
713
 
    res = node->branch2()->eval( context );
714
 
 
715
 
  // Finish stack unwinding
716
 
  context.clearReturnFlag();
717
 
 
718
 
  // Remove the local scope
719
 
  context.scope()->popLocalScope();
720
 
 
721
 
  return res;
722
 
}
723
 
 
724
 
bool KSEval_func_lines( KSParseNode* node, KSContext& context )
725
 
{
726
 
  if ( node->branch1() )
727
 
  {
728
 
    context.interpreter()->context().setException( 0 ); // ### reset -- HACK (Simon)
729
 
    if ( !node->branch1()->eval( context ) )
730
 
      return false;
731
 
    if ( context.returnFlag() )
732
 
      return true;
733
 
    // if ( node->branch1()->getType() == t_return )
734
 
    // return true;
735
 
  }
736
 
 
737
 
  // We are not interested in the value of the evaluation
738
 
  // since it is not a return value.
739
 
  context.setValue( 0 );
740
 
 
741
 
  // Did some destructor cause a exception ?
742
 
  if ( context.interpreter()->context().exception() )
743
 
  {
744
 
    context.setException( context.interpreter()->context().exception() );
745
 
    return false;
746
 
  }
747
 
 
748
 
  // The second branch can only hold a "func_lines" parsenode.
749
 
  if ( node->branch2() )
750
 
    if ( !node->branch2()->eval( context ) )
751
 
      return false;
752
 
 
753
 
  return true;
754
 
}
755
 
 
756
 
bool KSEval_assign_expr( KSParseNode* node, KSContext& context )
757
 
{
758
 
  EVAL_OPS( context, l, r, true );
759
 
 
760
 
  if ( l.value()->mode() != KSValue::LeftExpr )
761
 
  {
762
 
    context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
763
 
    return false;
764
 
  }
765
 
 
766
 
  // Special handling for strings
767
 
  if ( l.value()->type() == KSValue::CharRefType )
768
 
  {
769
 
    if ( !r.value()->cast( KSValue::CharType ) )
770
 
    {
771
 
      QString tmp( i18n("From %1 to Char") );
772
 
      context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
773
 
      return false;
774
 
    }
775
 
    l.value()->charRefValue() = r.value()->charValue();
776
 
 
777
 
    // Dont return the CharRef, so create a new value
778
 
    context.setValue( new KSValue( r.value()->charValue() ) );
779
 
    return true;
780
 
  }
781
 
 
782
 
  // Special handling for properties
783
 
  if ( l.value()->type() == KSValue::PropertyType )
784
 
  {
785
 
    if ( ! l.value()->propertyValue()->set( context, r.shareValue() ) )
786
 
      return false;
787
 
    // Return the value we just assigned
788
 
    context.setValue( r.shareValue() );
789
 
  }
790
 
  else
791
 
  {
792
 
    l.value()->suck( r.value() );
793
 
    // Return the value we just assigned
794
 
    context.setValue( l.shareValue() );
795
 
  }
796
 
  // Now it is a rightexpr. Dont allow to change it -> constant
797
 
  // context.value()->setMode( KSValue::Constant );
798
 
 
799
 
  return true;
800
 
}
801
 
 
802
 
bool KSEval_t_equal( KSParseNode* node, KSContext& context )
803
 
{
804
 
  EVAL_OPS( context, l, r, false );
805
 
 
806
 
  if ( !r.value()->cast( l.value()->type() ) )
807
 
  {
808
 
    QString tmp( i18n("From %1 to %2") );
809
 
    context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ).arg( l.value()->typeName() ), node->getLineNo() ) );
810
 
    return false;
811
 
  }
812
 
 
813
 
  KScript::Boolean result = ( r.value()->cmp( *l.value() ) );
814
 
  FILL_VALUE( context, l, r );
815
 
  context.value()->setValue( result );
816
 
  return true;
817
 
}
818
 
 
819
 
bool KSEval_t_notequal( KSParseNode* node, KSContext& context )
820
 
{
821
 
  EVAL_OPS( context, l, r, false );
822
 
 
823
 
  if ( !r.value()->cast( l.value()->type() ) )
824
 
  {
825
 
    QString tmp( i18n("From %1 to %2") );
826
 
    context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ).arg( l.value()->typeName() ), node->getLineNo() ) );
827
 
    return false;
828
 
  }
829
 
 
830
 
  KScript::Boolean result = !( r.value()->cmp( *l.value() ) );
831
 
  FILL_VALUE( context, l, r );
832
 
  context.value()->setValue( result );
833
 
  return true;
834
 
}
835
 
 
836
 
bool KSEval_t_less_or_equal( KSParseNode* node, KSContext& context )
837
 
{
838
 
  EVAL_OPS( context, l, r, false );
839
 
 
840
 
  if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
841
 
    return false;
842
 
 
843
 
  switch( l.value()->type() )
844
 
    {
845
 
    case KSValue::IntType:
846
 
      {
847
 
        KScript::Boolean result = l.value()->intValue() <= r.value()->intValue();
848
 
        FILL_VALUE( context, l, r );
849
 
        context.value()->setValue( result );
850
 
        return true;
851
 
      }
852
 
    case KSValue::DoubleType:
853
 
      {
854
 
        KScript::Boolean result = l.value()->doubleValue() <= r.value()->doubleValue();
855
 
        FILL_VALUE( context, l, r );
856
 
        context.value()->setValue( result );
857
 
        return true;
858
 
      }
859
 
    case KSValue::CharType:
860
 
      {
861
 
        KScript::Boolean result = l.value()->charValue() <= r.value()->charValue();
862
 
        FILL_VALUE( context, l, r );
863
 
        context.value()->setValue( result );
864
 
        return true;
865
 
      }
866
 
    case KSValue::StringType:
867
 
      {
868
 
        KScript::Boolean result = l.value()->stringValue() <= r.value()->stringValue();
869
 
        FILL_VALUE( context, l, r );
870
 
        context.value()->setValue( result );
871
 
        return true;
872
 
      }
873
 
    default:
874
 
      QString tmp( i18n("Operator <= not defined for type %1") );
875
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
876
 
      return false;
877
 
    }
878
 
 
879
 
  // Never reached
880
 
  return false;
881
 
}
882
 
 
883
 
bool KSEval_t_greater_or_equal( KSParseNode* node, KSContext& context )
884
 
{
885
 
  EVAL_OPS( context, l, r, false );
886
 
 
887
 
  if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
888
 
    return false;
889
 
 
890
 
  switch( l.value()->type() )
891
 
    {
892
 
    case KSValue::IntType:
893
 
      {
894
 
        KScript::Boolean result = l.value()->intValue() >= r.value()->intValue();
895
 
        FILL_VALUE( context, l, r );
896
 
        context.value()->setValue( result );
897
 
        return true;
898
 
      }
899
 
    case KSValue::DoubleType:
900
 
      {
901
 
        KScript::Boolean result = l.value()->doubleValue() >= r.value()->doubleValue();
902
 
        FILL_VALUE( context, l, r );
903
 
        context.value()->setValue( result );
904
 
        return true;
905
 
      }
906
 
    case KSValue::StringType:
907
 
      {
908
 
        KScript::Boolean result = l.value()->stringValue() >= r.value()->stringValue();
909
 
        FILL_VALUE( context, l, r );
910
 
        context.value()->setValue( result );
911
 
        return true;
912
 
      }
913
 
    case KSValue::CharType:
914
 
      {
915
 
        KScript::Boolean result = l.value()->charValue() >= r.value()->charValue();
916
 
        FILL_VALUE( context, l, r );
917
 
        context.value()->setValue( result );
918
 
        return true;
919
 
      }
920
 
    default:
921
 
      QString tmp( i18n("Operator >= not defined for type %1") );
922
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
923
 
      return false;
924
 
    }
925
 
 
926
 
  // Never reached
927
 
  return false;
928
 
}
929
 
 
930
 
bool KSEval_t_array( KSParseNode* node, KSContext& context )
931
 
{
932
 
  EVAL_OPS( context, l, r, false );
933
 
 
934
 
  if ( !r.value()->cast( KSValue::IntType ) )
935
 
  {
936
 
    QString tmp( i18n("From %1 to Integer in array index") );
937
 
    context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
938
 
    return false;
939
 
  }
940
 
 
941
 
  int index = r.value()->intValue();
942
 
 
943
 
  if ( index < 0 )
944
 
  {
945
 
    QString tmp( i18n("Negative array index %1"));
946
 
    context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
947
 
    return false;
948
 
  }
949
 
 
950
 
  // is it a string ? -> special handling
951
 
  if ( l.value()->type() == KSValue::StringType )
952
 
  {
953
 
    int len = l.value()->stringValue().length();
954
 
 
955
 
    if ( index >= len && !context.leftExpr() )
956
 
    {
957
 
      QString tmp( i18n("Too large index %1"));
958
 
      context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
959
 
      return false;
960
 
    }
961
 
 
962
 
    // Get a QChar
963
 
    if ( !context.leftExpr() )
964
 
    {
965
 
      const QString& str = l.value()->stringValue();
966
 
      context.setValue( new KSValue( str[ index ] ) );
967
 
      return true;
968
 
    }
969
 
 
970
 
    // Get a CharRef since leftexpr is needed
971
 
    context.setValue( new KSValue( KScript::CharRef( &(l.value()->stringValue()), index ) ) );
972
 
    context.value()->setMode( KSValue::LeftExpr );
973
 
    return true;
974
 
  }
975
 
 
976
 
  if ( !l.value()->cast( KSValue::ListType ) )
977
 
  {
978
 
    QString tmp( i18n("From %1 to List") );
979
 
    context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
980
 
    return false;
981
 
  }
982
 
 
983
 
  int len = l.value()->listValue().count();
984
 
  if ( index >= len )
985
 
  {
986
 
    if ( !context.leftExpr() )
987
 
    {
988
 
      QString tmp( i18n("Too large index %1"));
989
 
      context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
990
 
      return false;
991
 
    }
992
 
    else
993
 
    {
994
 
      // Fill the list with empty values
995
 
      for( int i = 0; i <= index - len; ++i )
996
 
        l.value()->listValue().append( new KSValue() );
997
 
    }
998
 
  }
999
 
 
1000
 
  context.setValue( l.value()->listValue()[ index ] );
1001
 
  context.value()->setMode( l.value()->mode() );
1002
 
 
1003
 
  return true;
1004
 
}
1005
 
 
1006
 
bool KSEval_t_dict( KSParseNode* node, KSContext& context )
1007
 
{
1008
 
  EVAL_OPS( context, l, r, false );
1009
 
 
1010
 
  if ( !r.value()->cast( KSValue::StringType ) )
1011
 
  {
1012
 
    QString tmp( i18n("From %1 to String in dict") );
1013
 
    context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
1014
 
    return false;
1015
 
  }
1016
 
 
1017
 
  if ( !l.value()->cast( KSValue::MapType ) )
1018
 
  {
1019
 
    QString tmp( i18n("From %1 to Map") );
1020
 
    context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1021
 
    return false;
1022
 
  }
1023
 
 
1024
 
  QMap<QString,KSValue::Ptr>::Iterator it = l.value()->mapValue().find( r.value()->stringValue() );
1025
 
  // Unknown element ?
1026
 
  if ( it == l.value()->mapValue().end() )
1027
 
  {
1028
 
    // No left expr needed-> return <none>
1029
 
    if ( !context.leftExpr() )
1030
 
    {
1031
 
      context.setValue( new KSValue() );
1032
 
      return true;
1033
 
    }
1034
 
    // Left expr needed
1035
 
    //    we got Left expr -> insert empty element
1036
 
    else if ( l.value()->mode() == KSValue::LeftExpr )
1037
 
    {
1038
 
      KSValue::Ptr v( new KSValue() );
1039
 
      v->setMode( l.value()->mode() );
1040
 
      l.value()->mapValue().insert( r.value()->stringValue(), v );
1041
 
      context.setValue( v );
1042
 
      return true;
1043
 
    }
1044
 
    //    we can not provide a left expression
1045
 
    else
1046
 
    {
1047
 
      context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression"), node->getLineNo() ) );
1048
 
      return false;
1049
 
    }
1050
 
  }
1051
 
 
1052
 
  context.setValue( it.data() );
1053
 
  context.value()->setMode( l.value()->mode() );
1054
 
 
1055
 
  return true;
1056
 
}
1057
 
 
1058
 
bool KSEval_func_params( KSParseNode* node, KSContext& context )
1059
 
{
1060
 
  // process a parameter
1061
 
  if ( node->branch1() )
1062
 
    if ( !node->branch1()->eval( context ) )
1063
 
      return false;
1064
 
 
1065
 
  // process more parameters
1066
 
  if ( node->branch2() )
1067
 
    if ( !node->branch2()->eval( context ) )
1068
 
      return false;
1069
 
 
1070
 
  return true;
1071
 
}
1072
 
 
1073
 
bool KSEval_func_param_in( KSParseNode* node, KSContext& context )
1074
 
{
1075
 
  KSValue* v = 0;
1076
 
 
1077
 
  // No more arguments ?
1078
 
  if ( context.value()->listValue().isEmpty() )
1079
 
  {
1080
 
    // Do we have a default Argument ?
1081
 
    if ( node->branch1() )
1082
 
    {
1083
 
      KSContext d( context );
1084
 
      if ( !node->branch1()->eval( d ) )
1085
 
        return false;
1086
 
      if ( d.value()->mode() == KSValue::Temp )
1087
 
        v = d.shareValue();
1088
 
      else
1089
 
        v = new KSValue( *d.value() );
1090
 
    }
1091
 
    else
1092
 
    {
1093
 
      QString tmp( i18n("Argument for parameters %1 missing") );
1094
 
      context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1095
 
      return false;
1096
 
    }
1097
 
  }
1098
 
  else
1099
 
  {
1100
 
    // Put the arguments as parameter in our namespace
1101
 
    KSValue* arg = *(context.value()->listValue().begin());
1102
 
    if ( arg->mode() == KSValue::Temp )
1103
 
    {
1104
 
      arg->ref();
1105
 
      v = arg;
1106
 
    }
1107
 
    else
1108
 
      v = new KSValue( *arg );
1109
 
 
1110
 
    // Remove the argument from the list
1111
 
    context.value()->listValue().remove( context.value()->listValue().begin() );
1112
 
  }
1113
 
 
1114
 
  v->setMode( KSValue::LeftExpr );
1115
 
  context.scope()->addObject( node->getIdent(), v );
1116
 
 
1117
 
  return true;
1118
 
}
1119
 
 
1120
 
bool KSEval_func_param_out( KSParseNode* node, KSContext& context )
1121
 
{
1122
 
  // No more arguments ?
1123
 
  if ( context.value()->listValue().isEmpty() )
1124
 
  {
1125
 
    QString tmp( i18n("Argument for parameters %1 missing") );
1126
 
    context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1127
 
    return false;
1128
 
  }
1129
 
 
1130
 
  KSValue* arg = *(context.value()->listValue().begin());
1131
 
 
1132
 
  // Is the argument not a leftexpr ?
1133
 
  if ( arg->mode() != KSValue::LeftExpr )
1134
 
  {
1135
 
    QString tmp( i18n("LeftExpr needed for parameter %1") );
1136
 
    context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1137
 
    return false;
1138
 
  }
1139
 
 
1140
 
  // The difference between out/inout. We empty the value here to make
1141
 
  // shure that nobody write "out" where he means "inout".
1142
 
  context.value()->clear();
1143
 
 
1144
 
  // Put the arguments as parameter in our namespace
1145
 
  arg->ref();
1146
 
  context.scope()->addObject( node->getIdent(), arg );
1147
 
 
1148
 
  // Remove the argument from the list
1149
 
  context.value()->listValue().remove( context.value()->listValue().begin() );
1150
 
 
1151
 
  return true;
1152
 
}
1153
 
 
1154
 
bool KSEval_func_param_inout( KSParseNode* node, KSContext& context )
1155
 
{
1156
 
  // No more arguments ?
1157
 
  if ( context.value()->listValue().isEmpty() )
1158
 
  {
1159
 
    QString tmp( i18n("Argument for parameters %1 missing") );
1160
 
    context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1161
 
    return false;
1162
 
  }
1163
 
 
1164
 
  KSValue* arg = *(context.value()->listValue().begin());
1165
 
 
1166
 
  // Is the argument not a leftexpr ?
1167
 
  if ( arg->mode() != KSValue::LeftExpr )
1168
 
  {
1169
 
    QString tmp( i18n("LeftExpr needed for parameter %1") );
1170
 
    context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1171
 
    return false;
1172
 
  }
1173
 
 
1174
 
  // Put the arguments as parameter in our namespace
1175
 
  arg->ref();
1176
 
  context.scope()->addObject( node->getIdent(), arg );
1177
 
 
1178
 
  // Remove the argument from the list
1179
 
  context.value()->listValue().remove( context.value()->listValue().begin() );
1180
 
 
1181
 
  return true;
1182
 
}
1183
 
 
1184
 
bool KSEval_t_func_call( KSParseNode* node, KSContext& context )
1185
 
{
1186
 
  // Get the function object
1187
 
  KSParseNode *left = node->branch1();
1188
 
  if ( !left )
1189
 
    return true;
1190
 
 
1191
 
  KSContext l( context );
1192
 
  if ( !left->eval( l ) )
1193
 
  {
1194
 
    context.setException( l );
1195
 
    return false;
1196
 
  }
1197
 
 
1198
 
  if ( !l.value()->cast( KSValue::FunctionType ) && !l.value()->cast( KSValue::ClassType ) &&
1199
 
       !l.value()->cast( KSValue::MethodType ) && !l.value()->cast( KSValue::StructClassType ) )
1200
 
  {
1201
 
    QString tmp( i18n("From %1 to Function") );
1202
 
    context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1203
 
    return false;
1204
 
  }
1205
 
 
1206
 
  // Create a list of parameters
1207
 
  context.setValue( new KSValue( KSValue::ListType ) );
1208
 
 
1209
 
  KSParseNode *right = node->branch2();
1210
 
  if ( right )
1211
 
    if ( !right->eval( context ) )
1212
 
      return false;
1213
 
 
1214
 
  // Remove our namespaces
1215
 
  KSSubScope* scope = context.scope()->popLocalScope();
1216
 
  KSModule* module = context.scope()->popModule();
1217
 
 
1218
 
  bool b = FALSE;;
1219
 
  if ( l.value()->cast( KSValue::FunctionType ) )
1220
 
  {
1221
 
    context.scope()->pushModule( l.value()->functionValue()->module() );
1222
 
    // Call the function
1223
 
    b = l.value()->functionValue()->call( context );
1224
 
    context.scope()->popModule();
1225
 
  }
1226
 
  else if ( l.value()->cast( KSValue::ClassType ) )
1227
 
  {
1228
 
    context.scope()->pushModule( l.value()->classValue()->module() );
1229
 
    // Call constructor
1230
 
    b = l.value()->classValue()->constructor( node, context );
1231
 
    context.scope()->popModule();
1232
 
  }
1233
 
  else if ( l.value()->cast( KSValue::StructClassType ) )
1234
 
  {
1235
 
    context.scope()->pushModule( l.value()->structClassValue()->module() );
1236
 
    // Call struct constructor
1237
 
    b = l.value()->structClassValue()->constructor( context );
1238
 
    context.scope()->popModule();
1239
 
  }
1240
 
  else if ( l.value()->cast( KSValue::MethodType ) )
1241
 
  {
1242
 
    context.scope()->pushModule( l.value()->methodValue()->module() );
1243
 
    // Call method
1244
 
    b = l.value()->methodValue()->call( context );
1245
 
    context.scope()->popModule();
1246
 
  }
1247
 
  else
1248
 
    ASSERT( 0 );
1249
 
 
1250
 
  // Resume namespaces
1251
 
  context.scope()->pushLocalScope( scope );
1252
 
  context.scope()->pushModule( module );
1253
 
 
1254
 
  if ( !b )
1255
 
    return false;
1256
 
 
1257
 
  // Lets have at least a <none> as return value
1258
 
  if ( !context.value() )
1259
 
    context.setValue( KSValue::null() );
1260
 
 
1261
 
  return true;
1262
 
}
1263
 
 
1264
 
bool KSEval_member_expr( KSParseNode* node, KSContext& context )
1265
 
{
1266
 
  KSParseNode *left = node->branch1();
1267
 
  ASSERT( left );
1268
 
 
1269
 
  // This resets leftExpr to FALSE
1270
 
  KSContext l( context );
1271
 
  // Try to find the object
1272
 
  if ( !left->eval( l ) )
1273
 
  {
1274
 
    context.setException( l );
1275
 
    return false;
1276
 
  }
1277
 
 
1278
 
  /**
1279
 
   * This is a syntax shortcut. If a function or method returns a object and takes
1280
 
   * no arguments, then you can skip the explizit function call.
1281
 
   * Instead of map().Table1().B3().setText("Hallo") you can write
1282
 
   * map.Table1.B3.setText("Hallo")
1283
 
   */
1284
 
  if ( l.value()->type() == KSValue::FunctionType || l.value()->type() == KSValue::MethodType )
1285
 
  {
1286
 
        // Copy l.value to func
1287
 
        KSContext func( context );
1288
 
        func.setValue( new KSValue( *l.value() ) );
1289
 
 
1290
 
        // Create a list of parameters
1291
 
        l.setValue( new KSValue( KSValue::ListType ) );
1292
 
 
1293
 
        // Remove our namespaces
1294
 
        KSSubScope* scope = l.scope()->popLocalScope();
1295
 
        KSModule* module = l.scope()->popModule();
1296
 
 
1297
 
        bool b = FALSE;
1298
 
        if ( func.value()->type() == KSValue::FunctionType )
1299
 
        {
1300
 
            l.scope()->pushModule( l.value()->functionValue()->module() );
1301
 
            // Call the function
1302
 
            b = func.value()->functionValue()->call( l );
1303
 
            l.scope()->popModule();
1304
 
        }
1305
 
        else if ( func.value()->type() == KSValue::MethodType )
1306
 
        {
1307
 
            l.scope()->pushModule( l.value()->methodValue()->module() );
1308
 
            // Call method
1309
 
            b = func.value()->methodValue()->call( l );
1310
 
            l.scope()->popModule();
1311
 
        }
1312
 
        else
1313
 
            ASSERT( 0 );
1314
 
 
1315
 
        // Resume namespaces
1316
 
        l.scope()->pushLocalScope( scope );
1317
 
        l.scope()->pushModule( module );
1318
 
 
1319
 
        if ( !b )
1320
 
        {
1321
 
            context.setException( l.exception() );
1322
 
            return false;
1323
 
        }
1324
 
 
1325
 
        // Lets have at least a <none> as return value
1326
 
        if ( !l.value() )
1327
 
            l.setValue( KSValue::null() );
1328
 
  }
1329
 
  /** End of Syntax trick ;-) **/
1330
 
 
1331
 
  // Special handling for modules
1332
 
  if ( l.value()->cast( KSValue::ModuleType ) )
1333
 
  {
1334
 
    KSValue::Ptr v = l.value()->moduleValue()->member( context, node->getIdent() );
1335
 
    if ( !v )
1336
 
    {
1337
 
      context.exception()->addLine( node->getLineNo() );
1338
 
      return false;
1339
 
    }
1340
 
 
1341
 
    context.setValue( v );
1342
 
 
1343
 
    return true;
1344
 
  }
1345
 
  // Special handling for classess
1346
 
  else if ( l.value()->cast( KSValue::ClassType ) )
1347
 
  {
1348
 
    KSValue::Ptr v = l.value()->classValue()->member( context, node->getIdent() );
1349
 
    if ( !v )
1350
 
    {
1351
 
      context.exception()->addLine( node->getLineNo() );
1352
 
      return false;
1353
 
    }
1354
 
 
1355
 
    context.setValue( v );
1356
 
 
1357
 
    return true;
1358
 
  }
1359
 
  // Special handling for struct classes
1360
 
  else if ( l.value()->cast( KSValue::StructClassType ) )
1361
 
  {
1362
 
    KSValue::Ptr v = l.value()->structClassValue()->member( context, node->getIdent() );
1363
 
    if ( !v )
1364
 
    {
1365
 
      context.exception()->addLine( node->getLineNo() );
1366
 
      return false;
1367
 
    }
1368
 
 
1369
 
    context.setValue( v );
1370
 
 
1371
 
    return true;
1372
 
  }
1373
 
 
1374
 
  KSValue::Ptr v;
1375
 
  KSModule* module;
1376
 
  if ( l.value()->cast( KSValue::ObjectType ) )
1377
 
  {
1378
 
    v = l.value()->objectValue()->member( context, node->getIdent() );
1379
 
    module = l.value()->objectValue()->module();
1380
 
  }
1381
 
  else if ( l.value()->cast( KSValue::StructType ) )
1382
 
  {
1383
 
    v = l.value()->structValue()->member( context, node->getIdent() );
1384
 
    module = l.value()->structValue()->module();
1385
 
  }
1386
 
  else if ( l.value()->cast( KSValue::ProxyType ) )
1387
 
  {
1388
 
    v = l.value()->proxyValue()->member( context, node->getIdent() );
1389
 
    module = context.scope()->module();
1390
 
  }
1391
 
  else if ( l.value()->cast( KSValue::QObjectType ) )
1392
 
  {
1393
 
    v = l.value()->qobjectValue()->member( context, node->getIdent() );
1394
 
    module = context.scope()->module();
1395
 
  }
1396
 
  // Special handling for all kind of built in data types
1397
 
  else
1398
 
  {
1399
 
    KSValue* v = context.object( node->getIdent() );
1400
 
    if ( !v )
1401
 
    {
1402
 
      context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) );
1403
 
      return false;
1404
 
    }
1405
 
    if ( v->type() != KSValue::FunctionType )
1406
 
    {
1407
 
      KSUtil::castingError( context, v, KSValue::FunctionType );
1408
 
      return false;
1409
 
    }
1410
 
    v->ref();
1411
 
    context.setValue( new KSValue( new KSMethod( context.scope()->module(), l.shareValue(), v ) ) );
1412
 
    return true;
1413
 
  }
1414
 
  /*
1415
 
  else
1416
 
  {
1417
 
    QString tmp( "From %1 to Object" );
1418
 
    context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1419
 
    return false;
1420
 
    } */
1421
 
 
1422
 
  if ( !v )
1423
 
  {
1424
 
    context.exception()->addLine( node->getLineNo() );
1425
 
    return false;
1426
 
  }
1427
 
 
1428
 
  if ( v->type() == KSValue::FunctionType  )
1429
 
      context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v ) ) );
1430
 
  else if ( v->type() == KSValue::BuiltinMethodType || v->type() == KSValue::StructBuiltinMethodType ||
1431
 
            v->type() == KSValue::ProxyBuiltinMethodType )
1432
 
    context.setValue( new KSValue( new KSMethod( module, l.shareValue(), v, node->getIdent() ) ) );
1433
 
  else
1434
 
      context.setValue( v );
1435
 
 
1436
 
  return true;
1437
 
}
1438
 
 
1439
 
bool KSEval_t_array_const( KSParseNode* node, KSContext& context )
1440
 
{
1441
 
  context.setValue( new KSValue( KSValue::ListType ) );
1442
 
 
1443
 
  KSParseNode *right = node->branch1();
1444
 
  if ( !right )
1445
 
    return true;
1446
 
 
1447
 
  if ( !right->eval( context ) )
1448
 
    return false;
1449
 
 
1450
 
  return true;
1451
 
}
1452
 
 
1453
 
bool KSEval_t_array_element( KSParseNode* node, KSContext& context )
1454
 
{
1455
 
  KSParseNode *left = node->branch1();
1456
 
  if ( !left )
1457
 
    return true;
1458
 
 
1459
 
  KSContext l( context );
1460
 
  if ( !left->eval( l ) )
1461
 
  {
1462
 
    context.setException( l );
1463
 
    return false;
1464
 
  }
1465
 
 
1466
 
  if ( l.value()->mode() == KSValue::Temp )
1467
 
  {
1468
 
    l.value()->ref();
1469
 
    context.value()->listValue().append( KSValue::Ptr( l.value() ) );
1470
 
  }
1471
 
  else
1472
 
  {
1473
 
    KSValue::Ptr v( new KSValue );
1474
 
    v->suck( l.value() );
1475
 
    context.value()->listValue().append( v );
1476
 
  }
1477
 
 
1478
 
  KSParseNode *right = node->branch2();
1479
 
  if ( !right )
1480
 
    return true;
1481
 
 
1482
 
  if ( !right->eval( context ) )
1483
 
    return false;
1484
 
 
1485
 
  return true;
1486
 
}
1487
 
 
1488
 
bool KSEval_t_dict_const( KSParseNode* node, KSContext& context )
1489
 
{
1490
 
  context.setValue( new KSValue( KSValue::MapType ) );
1491
 
 
1492
 
  KSParseNode *right = node->branch1();
1493
 
  if ( !right )
1494
 
    return true;
1495
 
 
1496
 
  if ( !right->eval( context ) )
1497
 
    return false;
1498
 
 
1499
 
  return true;
1500
 
}
1501
 
 
1502
 
bool KSEval_t_dict_element( KSParseNode* node, KSContext& context )
1503
 
{
1504
 
  EVAL_OPS( context, l, r, false );
1505
 
 
1506
 
  if ( !l.value()->cast( KSValue::StringType ) )
1507
 
  {
1508
 
    QString tmp( i18n("From %1 to String") );
1509
 
    context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
1510
 
    return false;
1511
 
  }
1512
 
 
1513
 
  if ( r.value()->mode() == KSValue::Temp )
1514
 
  {
1515
 
    r.value()->ref();
1516
 
    context.value()->mapValue().insert( l.value()->stringValue(), KSValue::Ptr( r.value() ) );
1517
 
  }
1518
 
  else
1519
 
  {
1520
 
    KSValue::Ptr v( new KSValue );
1521
 
    v->suck( r.value() );
1522
 
    context.value()->mapValue().insert( l.value()->stringValue(), v );
1523
 
  }
1524
 
 
1525
 
  KSParseNode *next = node->branch3();
1526
 
  if ( !next )
1527
 
    return true;
1528
 
 
1529
 
  if ( !next->eval( context ) )
1530
 
    return false;
1531
 
 
1532
 
  return true;
1533
 
}
1534
 
 
1535
 
bool KSEval_t_new( KSParseNode*, KSContext& ) { return false; }
1536
 
bool KSEval_t_delete( KSParseNode*, KSContext& ) { return false; }
1537
 
 
1538
 
bool KSEval_t_while( KSParseNode* node, KSContext& context )
1539
 
{
1540
 
  do
1541
 
  {
1542
 
    EVAL_LEFT_OP( context, l );
1543
 
 
1544
 
    if ( !l.value()->implicitCast( KSValue::BoolType ) )
1545
 
    {
1546
 
      QString tmp( i18n("From %1 to Boolean") );
1547
 
      context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1548
 
      return false;
1549
 
    }
1550
 
 
1551
 
    // Head of the while loop
1552
 
    if ( !l.value()->boolValue() )
1553
 
      return true;
1554
 
 
1555
 
    // Tail of the while loop
1556
 
    EVAL_RIGHT_OP( context, r );
1557
 
  } while( 1 );
1558
 
 
1559
 
  // Never reached
1560
 
  return false;
1561
 
}
1562
 
 
1563
 
bool KSEval_t_do( KSParseNode* node, KSContext& context )
1564
 
{
1565
 
  do
1566
 
  {
1567
 
    // Body of the loop
1568
 
    if ( !node->branch1()->eval( context ) )
1569
 
      return false;
1570
 
 
1571
 
    // Tail
1572
 
    if ( !node->branch2()->eval( context ) )
1573
 
      return false;
1574
 
 
1575
 
    if ( !context.value()->cast( KSValue::BoolType ) )
1576
 
    {
1577
 
      KSUtil::castingError( context, context.value(), KSValue::BoolType );
1578
 
      return false;
1579
 
    }
1580
 
 
1581
 
    // Head of the while loop
1582
 
    if ( !context.value()->boolValue() )
1583
 
      return true;
1584
 
 
1585
 
  } while( 1 );
1586
 
 
1587
 
  // Never reached
1588
 
  return false;
1589
 
}
1590
 
 
1591
 
bool KSEval_t_for( KSParseNode* node, KSContext& context )
1592
 
{
1593
 
  // Evaluate the start code
1594
 
  if ( !node->branch1()->eval( context ) )
1595
 
    return false;
1596
 
 
1597
 
  do
1598
 
  {
1599
 
    // Evaluate the condition
1600
 
    if ( !node->branch2()->eval( context ) )
1601
 
      return false;
1602
 
 
1603
 
    if ( !context.value()->cast( KSValue::BoolType ) )
1604
 
    {
1605
 
      KSUtil::castingError( context, context.value(), KSValue::BoolType );
1606
 
      return false;
1607
 
    }
1608
 
 
1609
 
    // Condition failed ?
1610
 
    if ( !context.value()->boolValue() )
1611
 
      return true;
1612
 
 
1613
 
    // Evaluate the body
1614
 
    if ( !node->branch4()->eval( context ) )
1615
 
      return false;
1616
 
 
1617
 
    // Evaluate the iterator
1618
 
    if ( !node->branch3()->eval( context ) )
1619
 
      return false;
1620
 
 
1621
 
  } while(1);
1622
 
 
1623
 
  // Bever reached
1624
 
  return false;
1625
 
}
1626
 
 
1627
 
bool KSEval_t_if( KSParseNode* node, KSContext& context )
1628
 
{
1629
 
  // Evaluate the condition
1630
 
  if ( !node->branch1()->eval( context ) )
1631
 
    return false;
1632
 
 
1633
 
  if ( !context.value()->cast( KSValue::BoolType ) )
1634
 
  {
1635
 
    KSUtil::castingError( context, context.value(), KSValue::BoolType );
1636
 
    return false;
1637
 
  }
1638
 
 
1639
 
  // Condition failed ?
1640
 
  if ( !context.value()->boolValue() )
1641
 
  {
1642
 
    if ( node->branch3() )
1643
 
      return node->branch3()->eval( context );
1644
 
    return true;
1645
 
  }
1646
 
 
1647
 
  return node->branch2()->eval( context );
1648
 
}
1649
 
 
1650
 
bool KSEval_t_incr( KSParseNode* node, KSContext& context )
1651
 
{
1652
 
  // Evaluate the expression
1653
 
  if ( !node->branch1()->eval( context ) )
1654
 
    return false;
1655
 
 
1656
 
  if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
1657
 
    return false;
1658
 
 
1659
 
  if ( context.value()->mode() != KSValue::LeftExpr )
1660
 
  {
1661
 
    context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
1662
 
    return false;
1663
 
  }
1664
 
 
1665
 
  // postfix ?
1666
 
  if ( node->branch2() )
1667
 
  {
1668
 
    KSValue::Ptr p = context.shareValue();
1669
 
    KScript::Long l = p->intValue();
1670
 
    p->setValue( p->intValue() + 1 );
1671
 
    context.setValue( new KSValue( l ) );
1672
 
    context.value()->setMode( KSValue::Temp );
1673
 
  }
1674
 
  else
1675
 
    context.value()->setValue( context.value()->intValue() + 1 );
1676
 
 
1677
 
  return true;
1678
 
}
1679
 
 
1680
 
bool KSEval_t_decr( KSParseNode* node, KSContext& context )
1681
 
{
1682
 
  // Evaluate the expression
1683
 
  if ( !node->branch1()->eval( context ) )
1684
 
    return false;
1685
 
 
1686
 
  if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
1687
 
    return false;
1688
 
 
1689
 
  if ( context.value()->mode() != KSValue::LeftExpr )
1690
 
  {
1691
 
    context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
1692
 
    return false;
1693
 
  }
1694
 
 
1695
 
  // postfix ?
1696
 
  if ( node->branch2() )
1697
 
  {
1698
 
    KSValue::Ptr p = context.shareValue();
1699
 
    KScript::Long l = p->intValue();
1700
 
    p->setValue( p->intValue() - 1 );
1701
 
    context.setValue( new KSValue( l ) );
1702
 
    context.value()->setMode( KSValue::Temp );
1703
 
  }
1704
 
  else
1705
 
    context.value()->setValue( context.value()->intValue() - 1 );
1706
 
 
1707
 
  return true;
1708
 
}
1709
 
 
1710
 
bool KSEval_t_less( KSParseNode* node, KSContext& context )
1711
 
{
1712
 
  EVAL_OPS( context, l, r, false );
1713
 
 
1714
 
  if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
1715
 
    return false;
1716
 
 
1717
 
  switch( l.value()->type() )
1718
 
    {
1719
 
    case KSValue::IntType:
1720
 
      {
1721
 
        KScript::Boolean result = l.value()->intValue() < r.value()->intValue();
1722
 
        FILL_VALUE( context, l, r );
1723
 
        context.value()->setValue( result );
1724
 
        return true;
1725
 
      }
1726
 
    case KSValue::DoubleType:
1727
 
      {
1728
 
        KScript::Boolean result = l.value()->doubleValue() < r.value()->doubleValue();
1729
 
        FILL_VALUE( context, l, r );
1730
 
        context.value()->setValue( result );
1731
 
        return true;
1732
 
      }
1733
 
    case KSValue::StringType:
1734
 
      {
1735
 
        KScript::Boolean result = l.value()->stringValue() < r.value()->stringValue();
1736
 
        FILL_VALUE( context, l, r );
1737
 
        context.value()->setValue( result );
1738
 
        return true;
1739
 
      }
1740
 
    case KSValue::CharType:
1741
 
      {
1742
 
        KScript::Boolean result = l.value()->charValue() < r.value()->charValue();
1743
 
        FILL_VALUE( context, l, r );
1744
 
        context.value()->setValue( result );
1745
 
        return true;
1746
 
      }
1747
 
    default:
1748
 
      QString tmp( i18n("Operator < not defined for type %1") );
1749
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1750
 
      return false;
1751
 
    }
1752
 
 
1753
 
  // Never reached
1754
 
  return false;
1755
 
}
1756
 
 
1757
 
bool KSEval_t_greater( KSParseNode* node, KSContext& context )
1758
 
{
1759
 
  EVAL_OPS( context, l, r, false );
1760
 
 
1761
 
  if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
1762
 
    return false;
1763
 
 
1764
 
  switch( l.value()->type() )
1765
 
    {
1766
 
    case KSValue::IntType:
1767
 
      {
1768
 
        KScript::Boolean result = l.value()->intValue() > r.value()->intValue();
1769
 
        FILL_VALUE( context, l, r );
1770
 
        context.value()->setValue( result );
1771
 
        return true;
1772
 
      }
1773
 
    case KSValue::DoubleType:
1774
 
      {
1775
 
        KScript::Boolean result = l.value()->doubleValue() > r.value()->doubleValue();
1776
 
        FILL_VALUE( context, l, r );
1777
 
        context.value()->setValue( result );
1778
 
        return true;
1779
 
      }
1780
 
    case KSValue::StringType:
1781
 
      {
1782
 
        KScript::Boolean result = l.value()->stringValue() > r.value()->stringValue();
1783
 
        FILL_VALUE( context, l, r );
1784
 
        context.value()->setValue( result );
1785
 
        return true;
1786
 
      }
1787
 
    case KSValue::CharType:
1788
 
      {
1789
 
        KScript::Boolean result = l.value()->charValue() > r.value()->charValue();
1790
 
        FILL_VALUE( context, l, r );
1791
 
        context.value()->setValue( result );
1792
 
        return true;
1793
 
      }
1794
 
    default:
1795
 
      QString tmp( i18n("Operator > not defined for type %1") );
1796
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1797
 
      return false;
1798
 
    }
1799
 
 
1800
 
  // Never reached
1801
 
  return false;
1802
 
}
1803
 
 
1804
 
 
1805
 
bool KSEval_t_foreach( KSParseNode* node, KSContext& context )
1806
 
{
1807
 
  // Evaluate the list/map
1808
 
  if ( !node->branch1()->eval( context ) )
1809
 
    return false;
1810
 
 
1811
 
  // Is the array a LeftExpr, Temp or Constant
1812
 
  KSValue::Mode mode = context.value()->mode();
1813
 
 
1814
 
  // Little hack to test wether we are in list or map mode
1815
 
  if ( node->branch3() )
1816
 
  {
1817
 
    if ( !context.value()->cast( KSValue::MapType ) )
1818
 
    {
1819
 
      KSUtil::castingError( context, context.value(), KSValue::MapType );
1820
 
      return false;
1821
 
    }
1822
 
 
1823
 
    KSNamespace nspace;
1824
 
    context.scope()->localScope()->pushNamespace( &nspace );
1825
 
 
1826
 
    QMap<QString,KSValue::Ptr>::Iterator it = context.value()->mapValue().begin();
1827
 
    QMap<QString,KSValue::Ptr>::Iterator end = context.value()->mapValue().end();
1828
 
    for( ; it != end; ++it )
1829
 
    {
1830
 
      // Get the element of the map in the local scope
1831
 
      it.data()->ref();
1832
 
      KSValue* v = it.data();
1833
 
      // Same mode as the array
1834
 
      v->setMode( mode );
1835
 
      context.scope()->addObject( node->getStringLiteral(), v );
1836
 
 
1837
 
      // Get the key of the map in the local scope
1838
 
      v = new KSValue( it.key() );
1839
 
      v->setMode( KSValue::Constant );
1840
 
      context.scope()->addObject( node->getIdent(), v );
1841
 
 
1842
 
      // Evaluate the body
1843
 
      KSContext ctx( context );
1844
 
      if ( !node->branch2()->eval( ctx ) )
1845
 
      {
1846
 
        context.setException( ctx );
1847
 
        context.scope()->localScope()->popNamespace();
1848
 
        return false;
1849
 
      }
1850
 
    }
1851
 
 
1852
 
    context.scope()->localScope()->popNamespace();
1853
 
  }
1854
 
  else
1855
 
  {
1856
 
    if ( !context.value()->cast( KSValue::ListType ) )
1857
 
    {
1858
 
      KSUtil::castingError( context, context.value(), KSValue::ListType );
1859
 
      return false;
1860
 
    }
1861
 
 
1862
 
    KSNamespace nspace;
1863
 
    context.scope()->localScope()->pushNamespace( &nspace );
1864
 
 
1865
 
    QValueList<KSValue::Ptr>::Iterator it = context.value()->listValue().begin();
1866
 
    QValueList<KSValue::Ptr>::Iterator end = context.value()->listValue().end();
1867
 
    for( ; it != end; ++it )
1868
 
    {
1869
 
      // Get the element of the array in our local variable
1870
 
      (*it)->ref();
1871
 
      KSValue* v = (*it);
1872
 
      // Same mode as the array
1873
 
      v->setMode( mode );
1874
 
      context.scope()->addObject( node->getIdent(), v );
1875
 
 
1876
 
      // Evaluate the body
1877
 
      KSContext ctx( context );
1878
 
      if ( !node->branch2()->eval( ctx ) )
1879
 
      {
1880
 
        context.setException( ctx );
1881
 
        context.scope()->localScope()->popNamespace();
1882
 
        return false;
1883
 
      }
1884
 
    }
1885
 
 
1886
 
    context.scope()->localScope()->popNamespace();
1887
 
  }
1888
 
 
1889
 
  return true;
1890
 
}
1891
 
 
1892
 
bool KSEval_t_match( KSParseNode* node , KSContext& context )
1893
 
{
1894
 
    if ( !node->branch1()->eval( context ) )
1895
 
        return false;
1896
 
 
1897
 
    if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) )
1898
 
        return FALSE;
1899
 
 
1900
 
    KRegExp* exp = context.interpreter()->regexp();
1901
 
    exp->compile( node->getIdent().latin1() );
1902
 
 
1903
 
    qDebug("Matching %s against %s",context.value()->stringValue().latin1(), node->getIdent().latin1() );
1904
 
 
1905
 
    context.setValue( new KSValue( exp->match( context.value()->stringValue().latin1() ) ) );
1906
 
 
1907
 
    return TRUE;
1908
 
}
1909
 
 
1910
 
bool KSEval_t_subst( KSParseNode* node, KSContext& context )
1911
 
{
1912
 
    KSContext l( context, TRUE );
1913
 
    if ( !node->branch1()->eval( l ) )
1914
 
        return false;
1915
 
 
1916
 
    if ( l.value()->mode() != KSValue::LeftExpr )
1917
 
    {
1918
 
        context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in substitute"), node->getLineNo() ) );
1919
 
        return false;
1920
 
    }
1921
 
 
1922
 
    if ( !KSUtil::checkType( l, l.value(), KSValue::StringType, TRUE ) )
1923
 
        return FALSE;
1924
 
 
1925
 
    int pos = node->getIdent().find( '/' );
1926
 
    ASSERT( pos != -1 );
1927
 
    QString match = node->getIdent().left( pos );
1928
 
    QString subst = node->getIdent().mid( pos + 1 );
1929
 
    KRegExp* exp = context.interpreter()->regexp();
1930
 
    exp->compile( match.latin1() );
1931
 
 
1932
 
    qDebug("Matching %s against %s",l.value()->stringValue().latin1(), node->getIdent().latin1() );
1933
 
 
1934
 
    if ( !exp->match( l.value()->stringValue().latin1() ) )
1935
 
    {
1936
 
        context.setValue( new KSValue( FALSE ) );
1937
 
        return TRUE;
1938
 
    }
1939
 
    else
1940
 
    {
1941
 
        int len = subst.length();
1942
 
        int i = 0;
1943
 
        while( i < len )
1944
 
        {
1945
 
            if ( subst[i] == '\\' && i + 1 < len && subst[i+1].isDigit() )
1946
 
            {
1947
 
                const char* grp = exp->group( subst[i+1].latin1() - '0' );
1948
 
                QString repl;
1949
 
                if ( grp )
1950
 
                    repl = grp;
1951
 
                else
1952
 
                    repl = "";
1953
 
                subst.replace( i, 2, repl );
1954
 
                len += repl.length() + 1;
1955
 
                i += repl.length();
1956
 
            }
1957
 
            else
1958
 
                ++i;
1959
 
        }
1960
 
        QString& str = l.value()->stringValue();
1961
 
        str.replace( exp->groupStart( 0 ), exp->groupEnd( 0 ) - exp->groupStart( 0 ), subst );
1962
 
    }
1963
 
 
1964
 
    context.setValue( new KSValue( TRUE ) );
1965
 
    return TRUE;
1966
 
}
1967
 
 
1968
 
bool KSEval_t_not( KSParseNode* node, KSContext& context )
1969
 
{
1970
 
  if ( !node->branch1()->eval( context ) )
1971
 
    return false;
1972
 
 
1973
 
  if ( !context.value()->cast( KSValue::BoolType ) )
1974
 
  {
1975
 
    QString tmp( i18n("Unary Operator ! not defined for type %1") );
1976
 
    context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
1977
 
    return false;
1978
 
  }
1979
 
 
1980
 
  context.setValue( new KSValue( !( context.value()->boolValue() ) ) );
1981
 
  return true;
1982
 
}
1983
 
 
1984
 
bool KSEval_func_call_params( KSParseNode* node, KSContext& context )
1985
 
{
1986
 
  // Get parameter
1987
 
  KSParseNode *left = node->branch1();
1988
 
  if ( !left )
1989
 
    return true;
1990
 
 
1991
 
  KSContext l( context );
1992
 
  if ( !left->eval( l ) )
1993
 
  {
1994
 
    context.setException( l );
1995
 
    return false;
1996
 
  }
1997
 
 
1998
 
  context.value()->listValue().append( l.shareValue() );
1999
 
 
2000
 
  // More parameters ?
2001
 
  KSParseNode *right = node->branch2();
2002
 
  if ( right )
2003
 
    if ( !right->eval( context ) )
2004
 
      return false;
2005
 
 
2006
 
  return true;
2007
 
}
2008
 
 
2009
 
bool KSEval_t_return( KSParseNode* node, KSContext& context )
2010
 
{
2011
 
  // Get return value if available
2012
 
  KSParseNode *left = node->branch1();
2013
 
  if ( left )
2014
 
  {
2015
 
    if ( !left->eval( context ) )
2016
 
    {
2017
 
      context.setException( context );
2018
 
      return false;
2019
 
    }
2020
 
 
2021
 
    // We may not return a LeftExpr here => make a copy
2022
 
    if ( context.value()->mode() == KSValue::LeftExpr )
2023
 
    {
2024
 
      KSValue* v = new KSValue( *context.value() );
2025
 
      context.setValue( v );
2026
 
    }
2027
 
  }
2028
 
  // No return value
2029
 
  else
2030
 
  {
2031
 
    // TODO: return the none object here -> faster
2032
 
    context.setValue( new KSValue() );
2033
 
  }
2034
 
 
2035
 
  context.setReturnFlag();
2036
 
 
2037
 
  return true;
2038
 
}
2039
 
 
2040
 
bool KSEval_destructor_dcl( KSParseNode* node, KSContext& context )
2041
 
{
2042
 
  // We want an additional namespace in the scope
2043
 
  KSNamespace nspace;
2044
 
  KSSubScope scope( &nspace );
2045
 
  context.scope()->pushLocalScope( &scope );
2046
 
 
2047
 
  // Fill parameters in our namespace
2048
 
  if ( node->branch1() )
2049
 
    if ( !node->branch1()->eval( context ) )
2050
 
    {
2051
 
      context.scope()->popLocalScope();
2052
 
      return false;
2053
 
    }
2054
 
 
2055
 
  // Are parameters left ?
2056
 
  if ( !context.value()->listValue().isEmpty() )
2057
 
  {
2058
 
    QString tmp( i18n("%1 arguments are not needed") );
2059
 
    context.setException( new KSException( "TooManyArguments", tmp.arg( context.value()->listValue().count() ), node->getLineNo() ) );
2060
 
    context.scope()->popLocalScope();
2061
 
    return false;
2062
 
  }
2063
 
 
2064
 
  // Call the function
2065
 
  if ( node->branch2() )
2066
 
    if ( !node->branch2()->eval( context ) )
2067
 
    {
2068
 
      context.scope()->popLocalScope();
2069
 
      return false;
2070
 
    }
2071
 
 
2072
 
  context.scope()->popLocalScope();
2073
 
  return true;
2074
 
}
2075
 
 
2076
 
bool KSEval_signal_dcl( KSParseNode* node, KSContext& context )
2077
 
{
2078
 
  // Get the object. It is always the first parameter
2079
 
  KSValue::Ptr v = context.value()->listValue().first();
2080
 
  // Remove it from the arguments list
2081
 
  context.value()->listValue().remove( context.value()->listValue().begin() );
2082
 
 
2083
 
  // Fill in default arguments if needed
2084
 
  context.tmpInt = 0;
2085
 
  if ( node->branch1() )
2086
 
    if ( !node->branch1()->eval( context ) )
2087
 
      return false;
2088
 
 
2089
 
  // Are parameters left ?
2090
 
  if ( context.value()->listValue().count() != (uint)context.tmpInt )
2091
 
  {
2092
 
    QString tmp( i18n("%1 arguments are not needed") );
2093
 
    context.setException( new KSException( "TooManyArguments", tmp.arg( context.value()->listValue().count() - context.tmpInt ), node->getLineNo() ) );
2094
 
    return false;
2095
 
  }
2096
 
 
2097
 
  // Call the signal
2098
 
  if ( !v->objectValue()->emitSignal( node->getIdent(), context ) )
2099
 
    return false;
2100
 
 
2101
 
  return true;
2102
 
}
2103
 
 
2104
 
bool KSEval_signal_params( KSParseNode* node, KSContext& context )
2105
 
{
2106
 
  // process a parameter
2107
 
  if ( node->branch1() )
2108
 
    if ( !node->branch1()->eval( context ) )
2109
 
      return false;
2110
 
 
2111
 
  // process more parameters
2112
 
  if ( node->branch2() )
2113
 
    if ( !node->branch2()->eval( context ) )
2114
 
      return false;
2115
 
 
2116
 
  return true;
2117
 
}
2118
 
 
2119
 
bool KSEval_signal_param( KSParseNode* node, KSContext& context )
2120
 
{
2121
 
  KSValue* v = 0;
2122
 
 
2123
 
  QValueList<KSValue::Ptr>::Iterator it = context.value()->listValue().at( context.tmpInt );
2124
 
 
2125
 
  // No more arguments ?
2126
 
  if ( it == context.value()->listValue().end() )
2127
 
  {
2128
 
    // Do we have a default Argument ?
2129
 
    if ( node->branch1() )
2130
 
    {
2131
 
      KSContext d( context );
2132
 
      if ( !node->branch1()->eval( d ) )
2133
 
        return false;
2134
 
      if ( d.value()->mode() == KSValue::Temp )
2135
 
      {
2136
 
        v = d.value();
2137
 
        v->ref();
2138
 
      }
2139
 
      else
2140
 
        v = new KSValue( *d.value() );
2141
 
 
2142
 
      context.value()->listValue().append( v );
2143
 
    }
2144
 
    else
2145
 
    {
2146
 
      QString tmp( i18n("Argument for parameters %1 missing") );
2147
 
      context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
2148
 
      return false;
2149
 
    }
2150
 
  }
2151
 
 
2152
 
  context.tmpInt++;
2153
 
 
2154
 
  return true;
2155
 
}
2156
 
 
2157
 
bool KSEval_t_emit( KSParseNode* node, KSContext& context )
2158
 
{
2159
 
  KSParseNode *left = node->branch1();
2160
 
  ASSERT( left );
2161
 
 
2162
 
  return left->eval( context );
2163
 
}
2164
 
 
2165
 
bool KSEval_import( KSParseNode* node, KSContext& context )
2166
 
{
2167
 
    // KSNamespace space;
2168
 
  // TODO: Find module in searchpath
2169
 
 
2170
 
  KSContext d( context );
2171
 
  // This function puts a KSModule in d.value()
2172
 
  if ( !context.interpreter()->runModule( d, node->getIdent() ) )
2173
 
  {
2174
 
    context.setException( d );
2175
 
    return false;
2176
 
  }
2177
 
 
2178
 
  // Register the imported module in the scope
2179
 
  context.scope()->addObject( node->getIdent(), d.shareValue() );
2180
 
 
2181
 
  return true;
2182
 
}
2183
 
 
2184
 
bool KSEval_t_struct( KSParseNode* node, KSContext& context )
2185
 
{
2186
 
  KSStructClass* p;
2187
 
 
2188
 
  // A struct in a class ?
2189
 
  if ( context.value() && context.value()->type() == KSValue::ClassType )
2190
 
  {
2191
 
    p = new KSStructClass( context.scope()->module(), node->getIdent() );
2192
 
    KSValue::Ptr v = new KSValue( p );
2193
 
 
2194
 
    context.value()->classValue()->nameSpace()->insert( node->getIdent(), v );
2195
 
 
2196
 
    KSParseNode *left = node->branch1();
2197
 
    if ( !left )
2198
 
      return true;
2199
 
 
2200
 
    KSContext d( context );
2201
 
    // All children should know about the new KSStructClass
2202
 
    d.setValue( v );
2203
 
    if ( !left->eval( d ) )
2204
 
    {
2205
 
      context.setException( d );
2206
 
      return false;
2207
 
    }
2208
 
  }
2209
 
  else
2210
 
  {
2211
 
    // All children should know about the new KSStructClass
2212
 
    context.setValue( new KSValue( ( p = new KSStructClass( context.scope()->module(), node->getIdent() ) ) ) );
2213
 
    context.scope()->addObject( node->getIdent(), context.shareValue() );
2214
 
 
2215
 
    KSParseNode *left = node->branch1();
2216
 
    if ( left )
2217
 
      if ( !left->eval( context ) )
2218
 
        return false;
2219
 
 
2220
 
    context.setValue( 0 );
2221
 
  }
2222
 
 
2223
 
  return true;
2224
 
}
2225
 
 
2226
 
bool KSEval_t_struct_members( KSParseNode* node, KSContext& context )
2227
 
{
2228
 
  ASSERT( context.value() && context.value()->type() == KSValue::StructClassType );
2229
 
 
2230
 
  context.value()->structClassValue()->addVariable( node->getIdent() );
2231
 
 
2232
 
  // process more members if available
2233
 
  if ( node->branch1() )
2234
 
    if ( !node->branch1()->eval( context ) )
2235
 
      return false;
2236
 
 
2237
 
  return true;
2238
 
}
2239
 
 
2240
 
extern bool KSEval_t_qualified_names( KSParseNode* node, KSContext& context )
2241
 
{
2242
 
  ASSERT( context.value() && context.value()->type() == KSValue::ListType );
2243
 
 
2244
 
  KSParseNode *left = node->branch1();
2245
 
  if ( !left )
2246
 
    return true;
2247
 
 
2248
 
  KSContext l( context );
2249
 
  if ( !left->eval( l ) )
2250
 
  {
2251
 
    context.setException( l );
2252
 
    return false;
2253
 
  }
2254
 
 
2255
 
  context.value()->listValue().append( l.shareValue() );
2256
 
 
2257
 
  KSParseNode *right = node->branch2();
2258
 
  if ( !right )
2259
 
    return true;
2260
 
 
2261
 
  if ( !right->eval( context ) )
2262
 
    return false;
2263
 
 
2264
 
  return true;
2265
 
}
2266
 
 
2267
 
extern bool KSEval_t_scope( KSParseNode* node, KSContext& context )
2268
 
{
2269
 
    KSParseNode *left = node->branch1();
2270
 
    // a construction like "{ }" ?
2271
 
    if ( !left )
2272
 
        return TRUE;
2273
 
 
2274
 
    KSNamespace nspace;
2275
 
    context.scope()->localScope()->pushNamespace( &nspace );
2276
 
 
2277
 
    bool res = left->eval( context );
2278
 
 
2279
 
    context.scope()->localScope()->popNamespace();
2280
 
 
2281
 
    return res;
2282
 
}
2283
 
 
2284
 
extern bool KSEval_t_try( KSParseNode* node, KSContext& context )
2285
 
{
2286
 
  KSNamespace nspace;
2287
 
  context.scope()->localScope()->pushNamespace( &nspace );
2288
 
 
2289
 
  // Execute the questionable code
2290
 
  KSParseNode *left = node->branch1();
2291
 
  ASSERT( left );
2292
 
  // No error -> Return
2293
 
  if ( left->eval( context ) )
2294
 
  {
2295
 
    context.scope()->localScope()->popNamespace();
2296
 
    return true;
2297
 
  }
2298
 
 
2299
 
  // We got an error. First resume the namespace. This
2300
 
  // will do automatically a stack unwinding
2301
 
  context.scope()->localScope()->popNamespace();
2302
 
 
2303
 
  // Execute the catch clauses
2304
 
  KSParseNode *right = node->branch2();
2305
 
  ASSERT( right );
2306
 
  return right->eval( context );
2307
 
}
2308
 
 
2309
 
extern bool KSEval_t_catch( KSParseNode* node, KSContext& context )
2310
 
{
2311
 
  KSContext d( context );
2312
 
 
2313
 
  // Find the type to which we want to compare
2314
 
  KSParseNode *left = node->branch1();
2315
 
  ASSERT( left );
2316
 
  if ( !left->eval( d ) )
2317
 
  {
2318
 
    context.setException( d );
2319
 
    return false;
2320
 
  }
2321
 
 
2322
 
  // Exception of the correct type ?
2323
 
  ASSERT( context.exception() );
2324
 
  if ( context.exception()->type()->cmp( *d.value() ) )
2325
 
  {
2326
 
     // Get infos about the exception
2327
 
    KSValue* value = context.exception()->value();
2328
 
    value->ref();
2329
 
 
2330
 
    // Add variables to the namespace
2331
 
    KSNamespace nspace;
2332
 
    nspace.insert( node->getIdent(), new KSValue( *value ) );
2333
 
    context.scope()->localScope()->pushNamespace( &nspace );
2334
 
 
2335
 
    // Clear the exception since we catched it
2336
 
    context.setException( 0 );
2337
 
 
2338
 
    // Evaluate the catch code
2339
 
    KSParseNode *right = node->branch2();
2340
 
    ASSERT( right );
2341
 
 
2342
 
    /* bool res = */ right->eval( context );
2343
 
 
2344
 
    // Resume namespace
2345
 
    context.scope()->localScope()->popNamespace();
2346
 
 
2347
 
    return true;
2348
 
  }
2349
 
 
2350
 
  // Could not catch. Try next if available
2351
 
  KSParseNode* more = node->branch4();
2352
 
  if ( more )
2353
 
    return more->eval( context );
2354
 
 
2355
 
  // We could not catch :-(
2356
 
  return false;
2357
 
}
2358
 
 
2359
 
extern bool KSEval_t_catch_default( KSParseNode* node, KSContext& context )
2360
 
{
2361
 
  KSContext d( context );
2362
 
 
2363
 
  // Find out na,me of the variable that
2364
 
  // holds the type
2365
 
  KSParseNode *left = node->branch1();
2366
 
  ASSERT( left );
2367
 
  QString name1 = left->getIdent();
2368
 
 
2369
 
  // Clear the exception
2370
 
  KSValue* type = context.exception()->type();
2371
 
  type->ref();
2372
 
  KSValue* value = context.exception()->value();
2373
 
  value->ref();
2374
 
  context.setException( 0 );
2375
 
 
2376
 
  // Add variables to the namespace
2377
 
  KSNamespace nspace;
2378
 
  nspace.insert( name1, new KSValue( *type ) );
2379
 
  nspace.insert( node->getIdent(), new KSValue( *value ) );
2380
 
  context.scope()->localScope()->pushNamespace( &nspace );
2381
 
 
2382
 
  // Evaluate the catch code
2383
 
  KSParseNode *right = node->branch2();
2384
 
  ASSERT( right );
2385
 
  bool res = right->eval( context );
2386
 
 
2387
 
  context.scope()->localScope()->popNamespace();
2388
 
 
2389
 
  return res;
2390
 
}
2391
 
 
2392
 
extern bool KSEval_t_raise( KSParseNode* node, KSContext& context )
2393
 
{
2394
 
  EVAL_OPS( context, l, r, false );
2395
 
 
2396
 
  // Raise the exception
2397
 
  context.setException( new KSException( l.shareValue(), r.shareValue(), node->getLineNo() ) );
2398
 
 
2399
 
  return false;
2400
 
}
2401
 
 
2402
 
extern bool KSEval_t_cell( KSParseNode* node, KSContext& context )
2403
 
{
2404
 
  return context.interpreter()->processExtension( context, node );
2405
 
}
2406
 
 
2407
 
extern bool KSEval_t_range( KSParseNode* node, KSContext& context )
2408
 
{
2409
 
  return context.interpreter()->processExtension( context, node );
2410
 
}
2411
 
 
2412
 
extern bool KSEval_from( KSParseNode* node, KSContext& context )
2413
 
{
2414
 
    // Get the list of symbols which have to be imported.
2415
 
    QStringList lst = QStringList::split( "/", node->getStringLiteral() );
2416
 
 
2417
 
    KSContext d( context );
2418
 
    // This function puts a KSModule in d.value()
2419
 
    if ( !context.interpreter()->runModule( d, node->getIdent(), node->getIdent() + ".ks", QStringList() ) )
2420
 
    {
2421
 
        context.setException( d );
2422
 
        return false;
2423
 
    }
2424
 
 
2425
 
    // Register the imported module in the scope
2426
 
    context.scope()->addObject( node->getIdent(), d.shareValue() );
2427
 
 
2428
 
    // Import all symbols ?
2429
 
    // Syntax: "from mymodule import *;"
2430
 
    if ( lst.isEmpty() )
2431
 
    {
2432
 
        // Iterate over all symbols of the module
2433
 
        KSNamespace::Iterator it = d.value()->moduleValue()->nameSpace()->begin();
2434
 
        KSNamespace::Iterator end = d.value()->moduleValue()->nameSpace()->end();
2435
 
        for(; it != end; ++it )
2436
 
            context.scope()->module()->addObject( it.key(), it.data() );
2437
 
    }
2438
 
    // Syntax: "from mymodule import sym1, sym2;"
2439
 
    else
2440
 
    {
2441
 
        // Import from this module
2442
 
        KSModule* m = d.value()->moduleValue();
2443
 
 
2444
 
        // Iterate over all symbols that we should import
2445
 
        QStringList::ConstIterator sit = lst.begin();
2446
 
        for( ; sit != lst.end(); ++sit )
2447
 
        {
2448
 
            // Symbol known ?
2449
 
            KSValue* v = m->object( *sit );
2450
 
            if ( !v )
2451
 
            {
2452
 
                QString tmp( i18n("The module %1 does not contain a symbol named %2") );
2453
 
                context.setException( new KSException( "SymbolUnknown",
2454
 
                                                       tmp.arg( node->getIdent() ).arg( *sit ),
2455
 
                                                       node->getLineNo() ) );
2456
 
                return false;
2457
 
            }
2458
 
 
2459
 
            // Add the symbol to the current namespace
2460
 
            v->ref();
2461
 
            context.scope()->module()->addObject( *sit, v );
2462
 
        }
2463
 
    }
2464
 
 
2465
 
    return TRUE;
2466
 
}
2467
 
 
2468
 
bool KSEval_plus_assign( KSParseNode* node, KSContext& context )
2469
 
{
2470
 
    EVAL_OPS( context, l, r, true );
2471
 
 
2472
 
    if ( l.value()->mode() != KSValue::LeftExpr )
2473
 
    {
2474
 
        context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
2475
 
        return false;
2476
 
    }
2477
 
 
2478
 
    if ( l.value()->type() == KSValue::TimeType )
2479
 
    {
2480
 
        if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2481
 
            return false;
2482
 
        QTime t = l.value()->timeValue();
2483
 
        t = t.addSecs( r.value()->intValue() );
2484
 
        l.value()->setValue( t );
2485
 
    }
2486
 
    else if ( l.value()->type() == KSValue::DateType )
2487
 
    {
2488
 
        if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2489
 
            return false;
2490
 
        QDate d = l.value()->dateValue();
2491
 
        d = d.addDays( r.value()->intValue() );
2492
 
        l.value()->setValue( d );
2493
 
    }
2494
 
    else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
2495
 
        return false;
2496
 
 
2497
 
    switch( l.value()->type() )
2498
 
    {
2499
 
    case KSValue::IntType:
2500
 
        l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
2501
 
        break;
2502
 
    case KSValue::DoubleType:
2503
 
        l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
2504
 
        break;
2505
 
    case KSValue::StringType:
2506
 
        l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
2507
 
        break;
2508
 
    case KSValue::ListType:
2509
 
        l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
2510
 
        break;
2511
 
    case KSValue::MapType:
2512
 
        {
2513
 
            QMap<QString,KSValue::Ptr>& map = l.value()->mapValue();
2514
 
            QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin();
2515
 
            QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end();
2516
 
            for( ; it != end; ++it )
2517
 
                map.insert( it.key(), it.data() );
2518
 
        }
2519
 
        break;
2520
 
    case KSValue::TimeType:
2521
 
    case KSValue::DateType:
2522
 
        // Handled above
2523
 
        break;
2524
 
    default:
2525
 
      QString tmp( i18n("Operator += not defined for type %1") );
2526
 
      context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
2527
 
      return false;
2528
 
    }
2529
 
 
2530
 
    l.value()->setMode( KSValue::LeftExpr );
2531
 
 
2532
 
    context.setValue( l.shareValue() );
2533
 
 
2534
 
    return TRUE;
2535
 
}
2536
 
 
2537
 
bool KSEval_minus_assign( KSParseNode* node, KSContext& context )
2538
 
{
2539
 
    EVAL_OPS( context, l, r, true );
2540
 
 
2541
 
    if ( l.value()->mode() != KSValue::LeftExpr )
2542
 
    {
2543
 
        context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
2544
 
        return false;
2545
 
    }
2546
 
 
2547
 
    if ( l.value()->type() == KSValue::TimeType )
2548
 
    {
2549
 
        if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) )
2550
 
        {
2551
 
            QTime d = r.value()->timeValue();
2552
 
            int diff = d.secsTo( l.value()->timeValue() );
2553
 
            l.value()->setValue( (KScript::Long)diff );
2554
 
        }
2555
 
        else
2556
 
        {
2557
 
            if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2558
 
                return false;
2559
 
            QTime t = l.value()->timeValue();
2560
 
            t = t.addSecs( -r.value()->intValue() );
2561
 
            l.value()->setValue( t );
2562
 
        }
2563
 
    }
2564
 
    else if ( l.value()->type() == KSValue::DateType )
2565
 
    {
2566
 
        if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) )
2567
 
        {
2568
 
            QDate d = r.value()->dateValue();
2569
 
            int diff = d.daysTo( l.value()->dateValue() );
2570
 
            l.value()->setValue( (KScript::Long)diff );
2571
 
        }
2572
 
        else
2573
 
        {
2574
 
            if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2575
 
                return false;
2576
 
            QDate d = l.value()->dateValue();
2577
 
            d = d.addDays( -r.value()->intValue() );
2578
 
            l.value()->setValue( d );
2579
 
        }
2580
 
    }
2581
 
    else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
2582
 
        return false;
2583
 
    else
2584
 
    {
2585
 
        switch( l.value()->type() )
2586
 
        {
2587
 
        case KSValue::IntType:
2588
 
            l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
2589
 
            break;
2590
 
        case KSValue::DoubleType:
2591
 
            l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
2592
 
            break;
2593
 
        case KSValue::StringType:
2594
 
            l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
2595
 
            break;
2596
 
        case KSValue::ListType:
2597
 
            l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
2598
 
            break;
2599
 
        case KSValue::MapType:
2600
 
        {
2601
 
            QMap<QString,KSValue::Ptr>& map = l.value()->mapValue();
2602
 
            QMap<QString,KSValue::Ptr>::ConstIterator it = r.value()->mapValue().begin();
2603
 
            QMap<QString,KSValue::Ptr>::ConstIterator end = r.value()->mapValue().end();
2604
 
            for( ; it != end; ++it )
2605
 
                map.insert( it.key(), it.data() );
2606
 
        }
2607
 
        break;
2608
 
        case KSValue::TimeType:
2609
 
        case KSValue::DateType:
2610
 
            // Handled above
2611
 
            break;
2612
 
        default:
2613
 
            QString tmp( i18n("Operator += not defined for type %1") );
2614
 
            context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
2615
 
            return false;
2616
 
        }
2617
 
    }
2618
 
 
2619
 
    l.value()->setMode( KSValue::LeftExpr );
2620
 
 
2621
 
    context.setValue( l.shareValue() );
2622
 
 
2623
 
    return TRUE;
2624
 
}
2625
 
 
2626
 
bool KSEval_bool_or( KSParseNode* node, KSContext& context )
2627
 
{
2628
 
    EVAL_OPS( context, l, r, false );
2629
 
 
2630
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
2631
 
         !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
2632
 
    {
2633
 
        context.exception()->addLine( node->getLineNo() );
2634
 
        return false;
2635
 
    }
2636
 
 
2637
 
    context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() || r.value()->boolValue() ) ) );
2638
 
 
2639
 
    return true;
2640
 
}
2641
 
 
2642
 
bool KSEval_bool_and( KSParseNode* node, KSContext& context )
2643
 
{
2644
 
    EVAL_OPS( context, l, r, false );
2645
 
 
2646
 
    if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
2647
 
         !KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
2648
 
    {
2649
 
        context.exception()->addLine( node->getLineNo() );
2650
 
        return false;
2651
 
    }
2652
 
 
2653
 
    context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() && r.value()->boolValue() ) ) );
2654
 
 
2655
 
    return true;
2656
 
}
2657
 
 
2658
 
bool KSEval_t_regexp_group( KSParseNode* node, KSContext& context )
2659
 
{
2660
 
    KRegExp* exp = context.interpreter()->regexp();
2661
 
    const char* grp = exp->group( node->getIntegerLiteral() );
2662
 
    if ( grp )
2663
 
        context.setValue( new KSValue( QString( grp ) ) );
2664
 
    else
2665
 
        context.setValue( new KSValue( QString( "" ) ) );
2666
 
 
2667
 
    return TRUE;
2668
 
}
2669
 
 
2670
 
bool KSEval_t_input( KSParseNode*, KSContext& context )
2671
 
{
2672
 
    context.setValue( new KSValue( context.interpreter()->readInput() ) );
2673
 
 
2674
 
    return TRUE;
2675
 
}
2676
 
 
2677
 
bool KSEval_t_line( KSParseNode* /*node*/, KSContext& context )
2678
 
{
2679
 
    context.setValue( context.interpreter()->lastInputLine() );
2680
 
 
2681
 
    return TRUE;
2682
 
}
2683
 
 
2684
 
bool KSEval_t_match_line( KSParseNode* node, KSContext& context )
2685
 
{
2686
 
    KSValue::Ptr line = context.interpreter()->lastInputLine();
2687
 
    if ( !KSUtil::checkType( context, line, KSValue::StringType, TRUE ) )
2688
 
        return FALSE;
2689
 
 
2690
 
    KRegExp* exp = context.interpreter()->regexp();
2691
 
    exp->compile( node->getIdent().latin1() );
2692
 
 
2693
 
    context.setValue( new KSValue( exp->match( line->stringValue().latin1() ) ) );
2694
 
 
2695
 
    return TRUE;
2696
 
}
2697
 
 
2698
 
bool KSEval_t_file_op( KSParseNode* node, KSContext& context )
2699
 
{
2700
 
    if ( !node->branch1()->eval( context ) )
2701
 
        return false;
2702
 
 
2703
 
    if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) )
2704
 
        return FALSE;
2705
 
 
2706
 
    QFileInfo info( context.value()->stringValue() );
2707
 
    if ( node->getIdent()[0] == 'r' )
2708
 
        context.setValue( new KSValue( info.isReadable() ) );
2709
 
    else if ( node->getIdent()[0] == 'w' )
2710
 
        context.setValue( new KSValue( info.isWritable() ) );
2711
 
    else if ( node->getIdent()[0] == 'd' )
2712
 
        context.setValue( new KSValue( info.isDir() ) );
2713
 
    else if ( node->getIdent()[0] == 'l' )
2714
 
        context.setValue( new KSValue( info.isSymLink() ) );
2715
 
    else if ( node->getIdent()[0] == 'f' )
2716
 
        context.setValue( new KSValue( info.isFile() ) );
2717
 
    else if ( node->getIdent()[0] == 'e' )
2718
 
        context.setValue( new KSValue( info.isExecutable() ) );
2719
 
    else if ( node->getIdent()[0] == 'x' )
2720
 
        context.setValue( new KSValue( info.exists() ) );
2721
 
    else if ( node->getIdent()[0] == 'g' )
2722
 
        context.setValue( new KSValue( info.group() ) );
2723
 
    else if ( node->getIdent()[0] == 'o' )
2724
 
        context.setValue( new KSValue( info.owner() ) );
2725
 
    else if ( node->getIdent()[0] == 's' )
2726
 
        context.setValue( new KSValue( (KScript::Long)info.size() ) );
2727
 
    else
2728
 
        ASSERT( 0 );
2729
 
 
2730
 
    return TRUE;
2731
 
}