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"
11
#include "kscript_parsenode.h"
12
#include "kscript_util.h"
17
#include <qfileinfo.h>
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 ) \
29
KSContext l( ctx, leftexpr ); \
31
if ( !left->eval( l ) ) \
33
ctx.setException( l ); \
36
if ( !right->eval( r ) ) \
38
ctx.setException( r ); \
42
#define EVAL_LEFT_OP( ctx, l ) \
43
KSParseNode *left = node->branch1(); \
48
if ( !left->eval( l ) ) \
50
ctx.setException( l ); \
54
#define EVAL_RIGHT_OP( ctx, r ) \
55
KSParseNode *right = node->branch2(); \
60
if ( !right->eval( r ) ) \
62
ctx.setException( r ); \
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() ); \
75
ctx.setValue( new KSValue );
77
bool KSEval_definitions( KSParseNode* node, KSContext& context )
79
if ( node->branch1() )
81
if ( node->branch1()->getType() == func_dcl )
83
ASSERT( context.scope() );
84
context.scope()->addObject( node->branch1()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch1() ) ) );
86
else if ( !node->branch1()->eval( context ) )
89
if ( node->branch2() )
91
if ( node->branch2()->getType() == func_dcl )
93
ASSERT( context.scope() );
94
context.scope()->addObject( node->branch2()->getIdent(), new KSValue( new KSScriptFunction( context.scope()->module(), node->branch2() ) ) );
96
else if ( !node->branch2()->eval( context ) )
103
bool KSEval_exports( KSParseNode* node, KSContext& context )
105
ASSERT( context.value() );
107
if ( context.value()->type() == KSValue::ClassType )
109
if ( node->branch1() )
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 ) )
120
if ( node->branch2() )
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 ) )
132
else if ( context.value()->type() == KSValue::StructClassType )
134
if ( node->branch1() )
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 ) )
141
if ( node->branch2() )
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 ) )
155
bool KSEval_t_vertical_line( KSParseNode* node, KSContext& context )
157
EVAL_OPS( context, l, r, false );
159
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
160
!KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
162
context.exception()->addLine( node->getLineNo() );
166
context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() | r.value()->intValue() ) ) );
171
bool KSEval_t_circumflex( KSParseNode* node, KSContext& context )
173
EVAL_OPS( context, l, r, false );
175
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
176
!KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
178
context.exception()->addLine( node->getLineNo() );
182
context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() ^ r.value()->intValue() ) ) );
187
bool KSEval_t_ampersand( KSParseNode* node, KSContext& context )
189
EVAL_OPS( context, l, r, false );
191
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
192
!KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
194
context.exception()->addLine( node->getLineNo() );
198
context.setValue( new KSValue( (KScript::Boolean)( l.value()->intValue() & r.value()->intValue() ) ) );
203
bool KSEval_t_shiftright( KSParseNode* node, KSContext& context )
205
EVAL_OPS( context, l, r, false );
207
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
208
!KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
210
context.exception()->addLine( node->getLineNo() );
214
context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() >> r.value()->intValue() ) ) );
219
bool KSEval_t_shiftleft( KSParseNode* node, KSContext& context )
221
EVAL_OPS( context, l, r, false );
223
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) ||
224
!KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
226
context.exception()->addLine( node->getLineNo() );
230
context.setValue( new KSValue( (KScript::Long)( l.value()->intValue() << r.value()->intValue() ) ) );
235
bool KSEval_t_plus_sign( KSParseNode* node, KSContext& context )
238
if ( node->branch1() && !node->branch2() )
240
if ( !node->branch1()->eval( context ) )
242
if ( context.value()->cast( KSValue::IntType ) )
244
if ( context.value()->cast( KSValue::DoubleType ) )
247
QString tmp( i18n("Unary Operator + not defined for type %1") );
248
context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
253
EVAL_OPS( context, l, r, false );
255
if ( l.value()->type() == KSValue::TimeType )
257
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
259
QTime t = l.value()->timeValue();
260
t = t.addSecs( r.value()->intValue() );
261
FILL_VALUE( context, l, r );
262
context.value()->setValue( t );
265
else if ( l.value()->type() == KSValue::DateType )
267
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
269
QDate d = l.value()->dateValue();
270
d = d.addDays( r.value()->intValue() );
271
FILL_VALUE( context, l, r );
272
context.value()->setValue( d );
275
// If we have double and int, then always convert to double
276
else if ( l.value()->type() == KSValue::DoubleType )
278
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
283
if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
287
switch( l.value()->type() )
289
case KSValue::IntType:
291
KScript::Long result = r.value()->intValue() + l.value()->intValue();
292
FILL_VALUE( context, l, r );
293
context.value()->setValue( result );
297
case KSValue::DoubleType:
299
KScript::Double result = l.value()->doubleValue() + r.value()->doubleValue();
300
FILL_VALUE( context, l, r );
301
context.value()->setValue( result );
304
case KSValue::StringType:
306
QString result = l.value()->stringValue() + r.value()->stringValue();
307
FILL_VALUE( context, l, r );
308
context.value()->setValue( result );
312
case KSValue::ListType:
314
QValueList<KSValue::Ptr> result = l.value()->listValue() + r.value()->listValue();
315
FILL_VALUE( context, l, r );
316
context.value()->setValue( result );
320
case KSValue::MapType:
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 );
332
case KSValue::DateType:
333
case KSValue::TimeType:
337
QString tmp( i18n("Operator + not defined for type %1") );
338
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
346
bool KSEval_t_minus_sign( KSParseNode* node, KSContext& context )
349
if ( node->branch1() && !node->branch2() )
351
if ( !node->branch1()->eval( context ) )
353
if ( context.value()->type() == KSValue::IntType )
355
context.setValue( new KSValue( -( context.value()->intValue() ) ) );
358
if ( context.value()->type() == KSValue::DoubleType )
360
context.setValue( new KSValue( -( context.value()->doubleValue() ) ) );
364
QString tmp( i18n("Unary Operator - not defined for type %1") );
365
context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
369
EVAL_OPS( context, l, r, false );
371
if ( l.value()->type() == KSValue::TimeType )
373
if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) )
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 );
382
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
384
QTime t = l.value()->timeValue();
385
t = t.addSecs( -r.value()->intValue() );
386
FILL_VALUE( context, l, r );
387
context.value()->setValue( t );
390
else if ( l.value()->type() == KSValue::DateType )
392
if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) )
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 );
401
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
403
QDate d = l.value()->dateValue();
404
d = d.addDays( -r.value()->intValue() );
405
FILL_VALUE( context, l, r );
406
context.value()->setValue( d );
409
// If we have double and int, then always convert to double
410
else if ( l.value()->type() == KSValue::DoubleType )
412
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
417
if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
421
switch( l.value()->type() )
423
case KSValue::IntType:
425
KScript::Long result = l.value()->intValue() - r.value()->intValue();
426
FILL_VALUE( context, l, r );
427
context.value()->setValue( result );
430
case KSValue::DoubleType:
432
KScript::Double result = l.value()->doubleValue() - r.value()->doubleValue();
433
FILL_VALUE( context, l, r );
434
context.value()->setValue( result );
438
QString tmp( i18n("Operator - not defined for type %1") );
439
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
447
bool KSEval_t_asterik( KSParseNode* node, KSContext& context )
449
EVAL_OPS( context, l, r, false );
451
// If we have double and int, then always convert to double
452
if ( l.value()->type() == KSValue::DoubleType )
454
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
459
if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
463
switch( l.value()->type() )
465
case KSValue::IntType:
467
KScript::Long result = r.value()->intValue() * l.value()->intValue();
468
FILL_VALUE( context, l, r );
469
context.value()->setValue( result );
472
case KSValue::DoubleType:
474
KScript::Double result = r.value()->doubleValue() * l.value()->doubleValue();
475
FILL_VALUE( context, l, r );
476
context.value()->setValue( result );
480
QString tmp( i18n("Operator * not defined for type %1") );
481
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
489
bool KSEval_t_solidus( KSParseNode* node, KSContext& context )
491
EVAL_OPS( context, l, r, false );
493
// If we have double and int, then always convert to double
494
if ( l.value()->type() == KSValue::DoubleType )
496
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
501
if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
505
switch( l.value()->type() )
507
case KSValue::IntType:
509
// If the devision has a "rest" then we have to convert to doubles
510
if ( ( l.value()->intValue() % r.value()->intValue() ) == 0 )
512
KScript::Long result = l.value()->intValue() / r.value()->intValue();
513
FILL_VALUE( context, l, r );
514
context.value()->setValue( result );
518
KScript::Double result = (double)l.value()->intValue() / (double)r.value()->intValue();
519
FILL_VALUE( context, l, r );
520
context.value()->setValue( result );
524
case KSValue::DoubleType:
526
KScript::Double result = l.value()->doubleValue() / r.value()->doubleValue();
527
FILL_VALUE( context, l, r );
528
context.value()->setValue( result );
532
QString tmp( i18n("Operator / not defined for type %1") );
533
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
541
bool KSEval_t_percent_sign( KSParseNode* node, KSContext& context )
543
EVAL_OPS( context, l, r, false );
545
if ( !KSUtil::checkType( context, l.value(), KSValue::IntType, true ) )
547
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
550
KScript::Long result = l.value()->intValue() % r.value()->intValue();
551
FILL_VALUE( context, l, r );
552
context.value()->setValue( result );
556
bool KSEval_t_tilde( KSParseNode* , KSContext& ) { return false; }
558
bool KSEval_t_integer_literal( KSParseNode* node, KSContext& context )
560
context.setValue( new KSValue( node->getIntegerLiteral() ) );
564
bool KSEval_t_string_literal( KSParseNode* node, KSContext& context )
566
context.setValue( new KSValue( node->getStringLiteral() ) );
570
bool KSEval_t_character_literal( KSParseNode* node, KSContext& context )
572
context.setValue( new KSValue( node->getCharacterLiteral() ) );
576
bool KSEval_t_floating_pt_literal( KSParseNode* node, KSContext& context )
578
context.setValue( new KSValue( node->getFloatingPtLiteral() ) );
582
bool KSEval_t_boolean_literal( KSParseNode* node, KSContext& context )
584
context.setValue( new KSValue( node->getBooleanLiteral() ) );
588
bool KSEval_scoped_name( KSParseNode* node, KSContext& context )
590
KSValue* v = context.object( node->getIdent() );
593
context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) );
598
context.setValue( v );
604
bool KSEval_const_dcl( KSParseNode* node, KSContext& context )
606
ASSERT( node->branch1() );
609
if ( !node->branch1()->eval( l ) )
611
context.setException( l );
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() );
627
bool KSEval_t_pragma( KSParseNode*, KSContext& ) { return false; }
629
bool KSEval_class_dcl( KSParseNode* node, KSContext& context )
631
KSParseNode *left = node->branch1();
634
// All child nodes should know about the new KSScriptClass
635
context.setValue( new KSValue( new KSScriptClass( context.scope()->module(), left->getIdent(), node ) ) );
637
if ( !left->eval( context ) )
640
KSParseNode *right = node->branch2();
642
if ( !right->eval( context ) )
645
context.setValue( 0 );
650
bool KSEval_class_header( KSParseNode* node, KSContext& context )
652
ASSERT( context.value() && context.value()->type() == KSValue::ClassType );
654
// TODO: Avoid circles in super classes
656
// Is the symbol already used ?
657
KSValue* v = context.scope()->object( node->getIdent() );
660
QString tmp( i18n("The symbol %1 is defined twice") );
661
context.setException( new KSException( "SymbolDefinedTwice", tmp.arg( node->getIdent() ), node->getLineNo() ) );
665
context.scope()->addObject( node->getIdent(), context.shareValue() );
667
// Search super classes
668
KSContext l( context );
669
KSParseNode *left = node->branch1();
673
l.setValue( new KSValue( KSValue::ListType ) );
675
if ( !left->eval( l ) )
677
context.setException( l );
681
context.value()->classValue()->setSuperClasses( l.value()->listValue() );
686
bool KSEval_func_dcl( KSParseNode* node, KSContext& context )
688
// We want an additional namespace in the scope
690
KSSubScope scope( &nspace );
691
context.scope()->pushLocalScope( &scope );
693
// Fill parameters in our namespace
694
if ( node->branch1() )
695
if ( !node->branch1()->eval( context ) )
697
context.scope()->popLocalScope();
701
// Are parameters left ?
702
if ( !context.value()->listValue().isEmpty() )
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();
712
if ( node->branch2() )
713
res = node->branch2()->eval( context );
715
// Finish stack unwinding
716
context.clearReturnFlag();
718
// Remove the local scope
719
context.scope()->popLocalScope();
724
bool KSEval_func_lines( KSParseNode* node, KSContext& context )
726
if ( node->branch1() )
728
context.interpreter()->context().setException( 0 ); // ### reset -- HACK (Simon)
729
if ( !node->branch1()->eval( context ) )
731
if ( context.returnFlag() )
733
// if ( node->branch1()->getType() == t_return )
737
// We are not interested in the value of the evaluation
738
// since it is not a return value.
739
context.setValue( 0 );
741
// Did some destructor cause a exception ?
742
if ( context.interpreter()->context().exception() )
744
context.setException( context.interpreter()->context().exception() );
748
// The second branch can only hold a "func_lines" parsenode.
749
if ( node->branch2() )
750
if ( !node->branch2()->eval( context ) )
756
bool KSEval_assign_expr( KSParseNode* node, KSContext& context )
758
EVAL_OPS( context, l, r, true );
760
if ( l.value()->mode() != KSValue::LeftExpr )
762
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
766
// Special handling for strings
767
if ( l.value()->type() == KSValue::CharRefType )
769
if ( !r.value()->cast( KSValue::CharType ) )
771
QString tmp( i18n("From %1 to Char") );
772
context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
775
l.value()->charRefValue() = r.value()->charValue();
777
// Dont return the CharRef, so create a new value
778
context.setValue( new KSValue( r.value()->charValue() ) );
782
// Special handling for properties
783
if ( l.value()->type() == KSValue::PropertyType )
785
if ( ! l.value()->propertyValue()->set( context, r.shareValue() ) )
787
// Return the value we just assigned
788
context.setValue( r.shareValue() );
792
l.value()->suck( r.value() );
793
// Return the value we just assigned
794
context.setValue( l.shareValue() );
796
// Now it is a rightexpr. Dont allow to change it -> constant
797
// context.value()->setMode( KSValue::Constant );
802
bool KSEval_t_equal( KSParseNode* node, KSContext& context )
804
EVAL_OPS( context, l, r, false );
806
if ( !r.value()->cast( l.value()->type() ) )
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() ) );
813
KScript::Boolean result = ( r.value()->cmp( *l.value() ) );
814
FILL_VALUE( context, l, r );
815
context.value()->setValue( result );
819
bool KSEval_t_notequal( KSParseNode* node, KSContext& context )
821
EVAL_OPS( context, l, r, false );
823
if ( !r.value()->cast( l.value()->type() ) )
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() ) );
830
KScript::Boolean result = !( r.value()->cmp( *l.value() ) );
831
FILL_VALUE( context, l, r );
832
context.value()->setValue( result );
836
bool KSEval_t_less_or_equal( KSParseNode* node, KSContext& context )
838
EVAL_OPS( context, l, r, false );
840
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
843
switch( l.value()->type() )
845
case KSValue::IntType:
847
KScript::Boolean result = l.value()->intValue() <= r.value()->intValue();
848
FILL_VALUE( context, l, r );
849
context.value()->setValue( result );
852
case KSValue::DoubleType:
854
KScript::Boolean result = l.value()->doubleValue() <= r.value()->doubleValue();
855
FILL_VALUE( context, l, r );
856
context.value()->setValue( result );
859
case KSValue::CharType:
861
KScript::Boolean result = l.value()->charValue() <= r.value()->charValue();
862
FILL_VALUE( context, l, r );
863
context.value()->setValue( result );
866
case KSValue::StringType:
868
KScript::Boolean result = l.value()->stringValue() <= r.value()->stringValue();
869
FILL_VALUE( context, l, r );
870
context.value()->setValue( result );
874
QString tmp( i18n("Operator <= not defined for type %1") );
875
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
883
bool KSEval_t_greater_or_equal( KSParseNode* node, KSContext& context )
885
EVAL_OPS( context, l, r, false );
887
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
890
switch( l.value()->type() )
892
case KSValue::IntType:
894
KScript::Boolean result = l.value()->intValue() >= r.value()->intValue();
895
FILL_VALUE( context, l, r );
896
context.value()->setValue( result );
899
case KSValue::DoubleType:
901
KScript::Boolean result = l.value()->doubleValue() >= r.value()->doubleValue();
902
FILL_VALUE( context, l, r );
903
context.value()->setValue( result );
906
case KSValue::StringType:
908
KScript::Boolean result = l.value()->stringValue() >= r.value()->stringValue();
909
FILL_VALUE( context, l, r );
910
context.value()->setValue( result );
913
case KSValue::CharType:
915
KScript::Boolean result = l.value()->charValue() >= r.value()->charValue();
916
FILL_VALUE( context, l, r );
917
context.value()->setValue( result );
921
QString tmp( i18n("Operator >= not defined for type %1") );
922
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
930
bool KSEval_t_array( KSParseNode* node, KSContext& context )
932
EVAL_OPS( context, l, r, false );
934
if ( !r.value()->cast( KSValue::IntType ) )
936
QString tmp( i18n("From %1 to Integer in array index") );
937
context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
941
int index = r.value()->intValue();
945
QString tmp( i18n("Negative array index %1"));
946
context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
950
// is it a string ? -> special handling
951
if ( l.value()->type() == KSValue::StringType )
953
int len = l.value()->stringValue().length();
955
if ( index >= len && !context.leftExpr() )
957
QString tmp( i18n("Too large index %1"));
958
context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
963
if ( !context.leftExpr() )
965
const QString& str = l.value()->stringValue();
966
context.setValue( new KSValue( str[ index ] ) );
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 );
976
if ( !l.value()->cast( KSValue::ListType ) )
978
QString tmp( i18n("From %1 to List") );
979
context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
983
int len = l.value()->listValue().count();
986
if ( !context.leftExpr() )
988
QString tmp( i18n("Too large index %1"));
989
context.setException( new KSException( "IndexOutOfRange", tmp.arg( index ), node->getLineNo() ) );
994
// Fill the list with empty values
995
for( int i = 0; i <= index - len; ++i )
996
l.value()->listValue().append( new KSValue() );
1000
context.setValue( l.value()->listValue()[ index ] );
1001
context.value()->setMode( l.value()->mode() );
1006
bool KSEval_t_dict( KSParseNode* node, KSContext& context )
1008
EVAL_OPS( context, l, r, false );
1010
if ( !r.value()->cast( KSValue::StringType ) )
1012
QString tmp( i18n("From %1 to String in dict") );
1013
context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
1017
if ( !l.value()->cast( KSValue::MapType ) )
1019
QString tmp( i18n("From %1 to Map") );
1020
context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1024
QMap<QString,KSValue::Ptr>::Iterator it = l.value()->mapValue().find( r.value()->stringValue() );
1025
// Unknown element ?
1026
if ( it == l.value()->mapValue().end() )
1028
// No left expr needed-> return <none>
1029
if ( !context.leftExpr() )
1031
context.setValue( new KSValue() );
1035
// we got Left expr -> insert empty element
1036
else if ( l.value()->mode() == KSValue::LeftExpr )
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 );
1044
// we can not provide a left expression
1047
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression"), node->getLineNo() ) );
1052
context.setValue( it.data() );
1053
context.value()->setMode( l.value()->mode() );
1058
bool KSEval_func_params( KSParseNode* node, KSContext& context )
1060
// process a parameter
1061
if ( node->branch1() )
1062
if ( !node->branch1()->eval( context ) )
1065
// process more parameters
1066
if ( node->branch2() )
1067
if ( !node->branch2()->eval( context ) )
1073
bool KSEval_func_param_in( KSParseNode* node, KSContext& context )
1077
// No more arguments ?
1078
if ( context.value()->listValue().isEmpty() )
1080
// Do we have a default Argument ?
1081
if ( node->branch1() )
1083
KSContext d( context );
1084
if ( !node->branch1()->eval( d ) )
1086
if ( d.value()->mode() == KSValue::Temp )
1089
v = new KSValue( *d.value() );
1093
QString tmp( i18n("Argument for parameters %1 missing") );
1094
context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1100
// Put the arguments as parameter in our namespace
1101
KSValue* arg = *(context.value()->listValue().begin());
1102
if ( arg->mode() == KSValue::Temp )
1108
v = new KSValue( *arg );
1110
// Remove the argument from the list
1111
context.value()->listValue().remove( context.value()->listValue().begin() );
1114
v->setMode( KSValue::LeftExpr );
1115
context.scope()->addObject( node->getIdent(), v );
1120
bool KSEval_func_param_out( KSParseNode* node, KSContext& context )
1122
// No more arguments ?
1123
if ( context.value()->listValue().isEmpty() )
1125
QString tmp( i18n("Argument for parameters %1 missing") );
1126
context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1130
KSValue* arg = *(context.value()->listValue().begin());
1132
// Is the argument not a leftexpr ?
1133
if ( arg->mode() != KSValue::LeftExpr )
1135
QString tmp( i18n("LeftExpr needed for parameter %1") );
1136
context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
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();
1144
// Put the arguments as parameter in our namespace
1146
context.scope()->addObject( node->getIdent(), arg );
1148
// Remove the argument from the list
1149
context.value()->listValue().remove( context.value()->listValue().begin() );
1154
bool KSEval_func_param_inout( KSParseNode* node, KSContext& context )
1156
// No more arguments ?
1157
if ( context.value()->listValue().isEmpty() )
1159
QString tmp( i18n("Argument for parameters %1 missing") );
1160
context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1164
KSValue* arg = *(context.value()->listValue().begin());
1166
// Is the argument not a leftexpr ?
1167
if ( arg->mode() != KSValue::LeftExpr )
1169
QString tmp( i18n("LeftExpr needed for parameter %1") );
1170
context.setException( new KSException( "NoLeftExpr", tmp.arg( node->getIdent() ), node->getLineNo() ) );
1174
// Put the arguments as parameter in our namespace
1176
context.scope()->addObject( node->getIdent(), arg );
1178
// Remove the argument from the list
1179
context.value()->listValue().remove( context.value()->listValue().begin() );
1184
bool KSEval_t_func_call( KSParseNode* node, KSContext& context )
1186
// Get the function object
1187
KSParseNode *left = node->branch1();
1191
KSContext l( context );
1192
if ( !left->eval( l ) )
1194
context.setException( l );
1198
if ( !l.value()->cast( KSValue::FunctionType ) && !l.value()->cast( KSValue::ClassType ) &&
1199
!l.value()->cast( KSValue::MethodType ) && !l.value()->cast( KSValue::StructClassType ) )
1201
QString tmp( i18n("From %1 to Function") );
1202
context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1206
// Create a list of parameters
1207
context.setValue( new KSValue( KSValue::ListType ) );
1209
KSParseNode *right = node->branch2();
1211
if ( !right->eval( context ) )
1214
// Remove our namespaces
1215
KSSubScope* scope = context.scope()->popLocalScope();
1216
KSModule* module = context.scope()->popModule();
1219
if ( l.value()->cast( KSValue::FunctionType ) )
1221
context.scope()->pushModule( l.value()->functionValue()->module() );
1222
// Call the function
1223
b = l.value()->functionValue()->call( context );
1224
context.scope()->popModule();
1226
else if ( l.value()->cast( KSValue::ClassType ) )
1228
context.scope()->pushModule( l.value()->classValue()->module() );
1230
b = l.value()->classValue()->constructor( node, context );
1231
context.scope()->popModule();
1233
else if ( l.value()->cast( KSValue::StructClassType ) )
1235
context.scope()->pushModule( l.value()->structClassValue()->module() );
1236
// Call struct constructor
1237
b = l.value()->structClassValue()->constructor( context );
1238
context.scope()->popModule();
1240
else if ( l.value()->cast( KSValue::MethodType ) )
1242
context.scope()->pushModule( l.value()->methodValue()->module() );
1244
b = l.value()->methodValue()->call( context );
1245
context.scope()->popModule();
1250
// Resume namespaces
1251
context.scope()->pushLocalScope( scope );
1252
context.scope()->pushModule( module );
1257
// Lets have at least a <none> as return value
1258
if ( !context.value() )
1259
context.setValue( KSValue::null() );
1264
bool KSEval_member_expr( KSParseNode* node, KSContext& context )
1266
KSParseNode *left = node->branch1();
1269
// This resets leftExpr to FALSE
1270
KSContext l( context );
1271
// Try to find the object
1272
if ( !left->eval( l ) )
1274
context.setException( l );
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")
1284
if ( l.value()->type() == KSValue::FunctionType || l.value()->type() == KSValue::MethodType )
1286
// Copy l.value to func
1287
KSContext func( context );
1288
func.setValue( new KSValue( *l.value() ) );
1290
// Create a list of parameters
1291
l.setValue( new KSValue( KSValue::ListType ) );
1293
// Remove our namespaces
1294
KSSubScope* scope = l.scope()->popLocalScope();
1295
KSModule* module = l.scope()->popModule();
1298
if ( func.value()->type() == KSValue::FunctionType )
1300
l.scope()->pushModule( l.value()->functionValue()->module() );
1301
// Call the function
1302
b = func.value()->functionValue()->call( l );
1303
l.scope()->popModule();
1305
else if ( func.value()->type() == KSValue::MethodType )
1307
l.scope()->pushModule( l.value()->methodValue()->module() );
1309
b = func.value()->methodValue()->call( l );
1310
l.scope()->popModule();
1315
// Resume namespaces
1316
l.scope()->pushLocalScope( scope );
1317
l.scope()->pushModule( module );
1321
context.setException( l.exception() );
1325
// Lets have at least a <none> as return value
1327
l.setValue( KSValue::null() );
1329
/** End of Syntax trick ;-) **/
1331
// Special handling for modules
1332
if ( l.value()->cast( KSValue::ModuleType ) )
1334
KSValue::Ptr v = l.value()->moduleValue()->member( context, node->getIdent() );
1337
context.exception()->addLine( node->getLineNo() );
1341
context.setValue( v );
1345
// Special handling for classess
1346
else if ( l.value()->cast( KSValue::ClassType ) )
1348
KSValue::Ptr v = l.value()->classValue()->member( context, node->getIdent() );
1351
context.exception()->addLine( node->getLineNo() );
1355
context.setValue( v );
1359
// Special handling for struct classes
1360
else if ( l.value()->cast( KSValue::StructClassType ) )
1362
KSValue::Ptr v = l.value()->structClassValue()->member( context, node->getIdent() );
1365
context.exception()->addLine( node->getLineNo() );
1369
context.setValue( v );
1376
if ( l.value()->cast( KSValue::ObjectType ) )
1378
v = l.value()->objectValue()->member( context, node->getIdent() );
1379
module = l.value()->objectValue()->module();
1381
else if ( l.value()->cast( KSValue::StructType ) )
1383
v = l.value()->structValue()->member( context, node->getIdent() );
1384
module = l.value()->structValue()->module();
1386
else if ( l.value()->cast( KSValue::ProxyType ) )
1388
v = l.value()->proxyValue()->member( context, node->getIdent() );
1389
module = context.scope()->module();
1391
else if ( l.value()->cast( KSValue::QObjectType ) )
1393
v = l.value()->qobjectValue()->member( context, node->getIdent() );
1394
module = context.scope()->module();
1396
// Special handling for all kind of built in data types
1399
KSValue* v = context.object( node->getIdent() );
1402
context.setException( new KSException( "UnknownName", node->getIdent(), node->getLineNo() ) );
1405
if ( v->type() != KSValue::FunctionType )
1407
KSUtil::castingError( context, v, KSValue::FunctionType );
1411
context.setValue( new KSValue( new KSMethod( context.scope()->module(), l.shareValue(), v ) ) );
1417
QString tmp( "From %1 to Object" );
1418
context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1424
context.exception()->addLine( node->getLineNo() );
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() ) ) );
1434
context.setValue( v );
1439
bool KSEval_t_array_const( KSParseNode* node, KSContext& context )
1441
context.setValue( new KSValue( KSValue::ListType ) );
1443
KSParseNode *right = node->branch1();
1447
if ( !right->eval( context ) )
1453
bool KSEval_t_array_element( KSParseNode* node, KSContext& context )
1455
KSParseNode *left = node->branch1();
1459
KSContext l( context );
1460
if ( !left->eval( l ) )
1462
context.setException( l );
1466
if ( l.value()->mode() == KSValue::Temp )
1469
context.value()->listValue().append( KSValue::Ptr( l.value() ) );
1473
KSValue::Ptr v( new KSValue );
1474
v->suck( l.value() );
1475
context.value()->listValue().append( v );
1478
KSParseNode *right = node->branch2();
1482
if ( !right->eval( context ) )
1488
bool KSEval_t_dict_const( KSParseNode* node, KSContext& context )
1490
context.setValue( new KSValue( KSValue::MapType ) );
1492
KSParseNode *right = node->branch1();
1496
if ( !right->eval( context ) )
1502
bool KSEval_t_dict_element( KSParseNode* node, KSContext& context )
1504
EVAL_OPS( context, l, r, false );
1506
if ( !l.value()->cast( KSValue::StringType ) )
1508
QString tmp( i18n("From %1 to String") );
1509
context.setException( new KSException( "CastingError", tmp.arg( r.value()->typeName() ), node->getLineNo() ) );
1513
if ( r.value()->mode() == KSValue::Temp )
1516
context.value()->mapValue().insert( l.value()->stringValue(), KSValue::Ptr( r.value() ) );
1520
KSValue::Ptr v( new KSValue );
1521
v->suck( r.value() );
1522
context.value()->mapValue().insert( l.value()->stringValue(), v );
1525
KSParseNode *next = node->branch3();
1529
if ( !next->eval( context ) )
1535
bool KSEval_t_new( KSParseNode*, KSContext& ) { return false; }
1536
bool KSEval_t_delete( KSParseNode*, KSContext& ) { return false; }
1538
bool KSEval_t_while( KSParseNode* node, KSContext& context )
1542
EVAL_LEFT_OP( context, l );
1544
if ( !l.value()->implicitCast( KSValue::BoolType ) )
1546
QString tmp( i18n("From %1 to Boolean") );
1547
context.setException( new KSException( "CastingError", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1551
// Head of the while loop
1552
if ( !l.value()->boolValue() )
1555
// Tail of the while loop
1556
EVAL_RIGHT_OP( context, r );
1563
bool KSEval_t_do( KSParseNode* node, KSContext& context )
1568
if ( !node->branch1()->eval( context ) )
1572
if ( !node->branch2()->eval( context ) )
1575
if ( !context.value()->cast( KSValue::BoolType ) )
1577
KSUtil::castingError( context, context.value(), KSValue::BoolType );
1581
// Head of the while loop
1582
if ( !context.value()->boolValue() )
1591
bool KSEval_t_for( KSParseNode* node, KSContext& context )
1593
// Evaluate the start code
1594
if ( !node->branch1()->eval( context ) )
1599
// Evaluate the condition
1600
if ( !node->branch2()->eval( context ) )
1603
if ( !context.value()->cast( KSValue::BoolType ) )
1605
KSUtil::castingError( context, context.value(), KSValue::BoolType );
1609
// Condition failed ?
1610
if ( !context.value()->boolValue() )
1613
// Evaluate the body
1614
if ( !node->branch4()->eval( context ) )
1617
// Evaluate the iterator
1618
if ( !node->branch3()->eval( context ) )
1627
bool KSEval_t_if( KSParseNode* node, KSContext& context )
1629
// Evaluate the condition
1630
if ( !node->branch1()->eval( context ) )
1633
if ( !context.value()->cast( KSValue::BoolType ) )
1635
KSUtil::castingError( context, context.value(), KSValue::BoolType );
1639
// Condition failed ?
1640
if ( !context.value()->boolValue() )
1642
if ( node->branch3() )
1643
return node->branch3()->eval( context );
1647
return node->branch2()->eval( context );
1650
bool KSEval_t_incr( KSParseNode* node, KSContext& context )
1652
// Evaluate the expression
1653
if ( !node->branch1()->eval( context ) )
1656
if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
1659
if ( context.value()->mode() != KSValue::LeftExpr )
1661
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
1666
if ( node->branch2() )
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 );
1675
context.value()->setValue( context.value()->intValue() + 1 );
1680
bool KSEval_t_decr( KSParseNode* node, KSContext& context )
1682
// Evaluate the expression
1683
if ( !node->branch1()->eval( context ) )
1686
if ( !KSUtil::checkType( context, context.value(), KSValue::IntType, true ) )
1689
if ( context.value()->mode() != KSValue::LeftExpr )
1691
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
1696
if ( node->branch2() )
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 );
1705
context.value()->setValue( context.value()->intValue() - 1 );
1710
bool KSEval_t_less( KSParseNode* node, KSContext& context )
1712
EVAL_OPS( context, l, r, false );
1714
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
1717
switch( l.value()->type() )
1719
case KSValue::IntType:
1721
KScript::Boolean result = l.value()->intValue() < r.value()->intValue();
1722
FILL_VALUE( context, l, r );
1723
context.value()->setValue( result );
1726
case KSValue::DoubleType:
1728
KScript::Boolean result = l.value()->doubleValue() < r.value()->doubleValue();
1729
FILL_VALUE( context, l, r );
1730
context.value()->setValue( result );
1733
case KSValue::StringType:
1735
KScript::Boolean result = l.value()->stringValue() < r.value()->stringValue();
1736
FILL_VALUE( context, l, r );
1737
context.value()->setValue( result );
1740
case KSValue::CharType:
1742
KScript::Boolean result = l.value()->charValue() < r.value()->charValue();
1743
FILL_VALUE( context, l, r );
1744
context.value()->setValue( result );
1748
QString tmp( i18n("Operator < not defined for type %1") );
1749
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1757
bool KSEval_t_greater( KSParseNode* node, KSContext& context )
1759
EVAL_OPS( context, l, r, false );
1761
if ( !KSUtil::checkType( context, r.value(), l.value()->type(), true ) )
1764
switch( l.value()->type() )
1766
case KSValue::IntType:
1768
KScript::Boolean result = l.value()->intValue() > r.value()->intValue();
1769
FILL_VALUE( context, l, r );
1770
context.value()->setValue( result );
1773
case KSValue::DoubleType:
1775
KScript::Boolean result = l.value()->doubleValue() > r.value()->doubleValue();
1776
FILL_VALUE( context, l, r );
1777
context.value()->setValue( result );
1780
case KSValue::StringType:
1782
KScript::Boolean result = l.value()->stringValue() > r.value()->stringValue();
1783
FILL_VALUE( context, l, r );
1784
context.value()->setValue( result );
1787
case KSValue::CharType:
1789
KScript::Boolean result = l.value()->charValue() > r.value()->charValue();
1790
FILL_VALUE( context, l, r );
1791
context.value()->setValue( result );
1795
QString tmp( i18n("Operator > not defined for type %1") );
1796
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
1805
bool KSEval_t_foreach( KSParseNode* node, KSContext& context )
1807
// Evaluate the list/map
1808
if ( !node->branch1()->eval( context ) )
1811
// Is the array a LeftExpr, Temp or Constant
1812
KSValue::Mode mode = context.value()->mode();
1814
// Little hack to test wether we are in list or map mode
1815
if ( node->branch3() )
1817
if ( !context.value()->cast( KSValue::MapType ) )
1819
KSUtil::castingError( context, context.value(), KSValue::MapType );
1824
context.scope()->localScope()->pushNamespace( &nspace );
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 )
1830
// Get the element of the map in the local scope
1832
KSValue* v = it.data();
1833
// Same mode as the array
1835
context.scope()->addObject( node->getStringLiteral(), v );
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 );
1842
// Evaluate the body
1843
KSContext ctx( context );
1844
if ( !node->branch2()->eval( ctx ) )
1846
context.setException( ctx );
1847
context.scope()->localScope()->popNamespace();
1852
context.scope()->localScope()->popNamespace();
1856
if ( !context.value()->cast( KSValue::ListType ) )
1858
KSUtil::castingError( context, context.value(), KSValue::ListType );
1863
context.scope()->localScope()->pushNamespace( &nspace );
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 )
1869
// Get the element of the array in our local variable
1872
// Same mode as the array
1874
context.scope()->addObject( node->getIdent(), v );
1876
// Evaluate the body
1877
KSContext ctx( context );
1878
if ( !node->branch2()->eval( ctx ) )
1880
context.setException( ctx );
1881
context.scope()->localScope()->popNamespace();
1886
context.scope()->localScope()->popNamespace();
1892
bool KSEval_t_match( KSParseNode* node , KSContext& context )
1894
if ( !node->branch1()->eval( context ) )
1897
if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) )
1900
KRegExp* exp = context.interpreter()->regexp();
1901
exp->compile( node->getIdent().latin1() );
1903
qDebug("Matching %s against %s",context.value()->stringValue().latin1(), node->getIdent().latin1() );
1905
context.setValue( new KSValue( exp->match( context.value()->stringValue().latin1() ) ) );
1910
bool KSEval_t_subst( KSParseNode* node, KSContext& context )
1912
KSContext l( context, TRUE );
1913
if ( !node->branch1()->eval( l ) )
1916
if ( l.value()->mode() != KSValue::LeftExpr )
1918
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in substitute"), node->getLineNo() ) );
1922
if ( !KSUtil::checkType( l, l.value(), KSValue::StringType, TRUE ) )
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() );
1932
qDebug("Matching %s against %s",l.value()->stringValue().latin1(), node->getIdent().latin1() );
1934
if ( !exp->match( l.value()->stringValue().latin1() ) )
1936
context.setValue( new KSValue( FALSE ) );
1941
int len = subst.length();
1945
if ( subst[i] == '\\' && i + 1 < len && subst[i+1].isDigit() )
1947
const char* grp = exp->group( subst[i+1].latin1() - '0' );
1953
subst.replace( i, 2, repl );
1954
len += repl.length() + 1;
1960
QString& str = l.value()->stringValue();
1961
str.replace( exp->groupStart( 0 ), exp->groupEnd( 0 ) - exp->groupStart( 0 ), subst );
1964
context.setValue( new KSValue( TRUE ) );
1968
bool KSEval_t_not( KSParseNode* node, KSContext& context )
1970
if ( !node->branch1()->eval( context ) )
1973
if ( !context.value()->cast( KSValue::BoolType ) )
1975
QString tmp( i18n("Unary Operator ! not defined for type %1") );
1976
context.setException( new KSException( "UnknownOperation", tmp.arg( context.value()->typeName() ), node->getLineNo() ) );
1980
context.setValue( new KSValue( !( context.value()->boolValue() ) ) );
1984
bool KSEval_func_call_params( KSParseNode* node, KSContext& context )
1987
KSParseNode *left = node->branch1();
1991
KSContext l( context );
1992
if ( !left->eval( l ) )
1994
context.setException( l );
1998
context.value()->listValue().append( l.shareValue() );
2000
// More parameters ?
2001
KSParseNode *right = node->branch2();
2003
if ( !right->eval( context ) )
2009
bool KSEval_t_return( KSParseNode* node, KSContext& context )
2011
// Get return value if available
2012
KSParseNode *left = node->branch1();
2015
if ( !left->eval( context ) )
2017
context.setException( context );
2021
// We may not return a LeftExpr here => make a copy
2022
if ( context.value()->mode() == KSValue::LeftExpr )
2024
KSValue* v = new KSValue( *context.value() );
2025
context.setValue( v );
2031
// TODO: return the none object here -> faster
2032
context.setValue( new KSValue() );
2035
context.setReturnFlag();
2040
bool KSEval_destructor_dcl( KSParseNode* node, KSContext& context )
2042
// We want an additional namespace in the scope
2044
KSSubScope scope( &nspace );
2045
context.scope()->pushLocalScope( &scope );
2047
// Fill parameters in our namespace
2048
if ( node->branch1() )
2049
if ( !node->branch1()->eval( context ) )
2051
context.scope()->popLocalScope();
2055
// Are parameters left ?
2056
if ( !context.value()->listValue().isEmpty() )
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();
2064
// Call the function
2065
if ( node->branch2() )
2066
if ( !node->branch2()->eval( context ) )
2068
context.scope()->popLocalScope();
2072
context.scope()->popLocalScope();
2076
bool KSEval_signal_dcl( KSParseNode* node, KSContext& context )
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() );
2083
// Fill in default arguments if needed
2085
if ( node->branch1() )
2086
if ( !node->branch1()->eval( context ) )
2089
// Are parameters left ?
2090
if ( context.value()->listValue().count() != (uint)context.tmpInt )
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() ) );
2098
if ( !v->objectValue()->emitSignal( node->getIdent(), context ) )
2104
bool KSEval_signal_params( KSParseNode* node, KSContext& context )
2106
// process a parameter
2107
if ( node->branch1() )
2108
if ( !node->branch1()->eval( context ) )
2111
// process more parameters
2112
if ( node->branch2() )
2113
if ( !node->branch2()->eval( context ) )
2119
bool KSEval_signal_param( KSParseNode* node, KSContext& context )
2123
QValueList<KSValue::Ptr>::Iterator it = context.value()->listValue().at( context.tmpInt );
2125
// No more arguments ?
2126
if ( it == context.value()->listValue().end() )
2128
// Do we have a default Argument ?
2129
if ( node->branch1() )
2131
KSContext d( context );
2132
if ( !node->branch1()->eval( d ) )
2134
if ( d.value()->mode() == KSValue::Temp )
2140
v = new KSValue( *d.value() );
2142
context.value()->listValue().append( v );
2146
QString tmp( i18n("Argument for parameters %1 missing") );
2147
context.setException( new KSException( "ToFewArguments", tmp.arg( node->getIdent() ), node->getLineNo() ) );
2157
bool KSEval_t_emit( KSParseNode* node, KSContext& context )
2159
KSParseNode *left = node->branch1();
2162
return left->eval( context );
2165
bool KSEval_import( KSParseNode* node, KSContext& context )
2167
// KSNamespace space;
2168
// TODO: Find module in searchpath
2170
KSContext d( context );
2171
// This function puts a KSModule in d.value()
2172
if ( !context.interpreter()->runModule( d, node->getIdent() ) )
2174
context.setException( d );
2178
// Register the imported module in the scope
2179
context.scope()->addObject( node->getIdent(), d.shareValue() );
2184
bool KSEval_t_struct( KSParseNode* node, KSContext& context )
2188
// A struct in a class ?
2189
if ( context.value() && context.value()->type() == KSValue::ClassType )
2191
p = new KSStructClass( context.scope()->module(), node->getIdent() );
2192
KSValue::Ptr v = new KSValue( p );
2194
context.value()->classValue()->nameSpace()->insert( node->getIdent(), v );
2196
KSParseNode *left = node->branch1();
2200
KSContext d( context );
2201
// All children should know about the new KSStructClass
2203
if ( !left->eval( d ) )
2205
context.setException( d );
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() );
2215
KSParseNode *left = node->branch1();
2217
if ( !left->eval( context ) )
2220
context.setValue( 0 );
2226
bool KSEval_t_struct_members( KSParseNode* node, KSContext& context )
2228
ASSERT( context.value() && context.value()->type() == KSValue::StructClassType );
2230
context.value()->structClassValue()->addVariable( node->getIdent() );
2232
// process more members if available
2233
if ( node->branch1() )
2234
if ( !node->branch1()->eval( context ) )
2240
extern bool KSEval_t_qualified_names( KSParseNode* node, KSContext& context )
2242
ASSERT( context.value() && context.value()->type() == KSValue::ListType );
2244
KSParseNode *left = node->branch1();
2248
KSContext l( context );
2249
if ( !left->eval( l ) )
2251
context.setException( l );
2255
context.value()->listValue().append( l.shareValue() );
2257
KSParseNode *right = node->branch2();
2261
if ( !right->eval( context ) )
2267
extern bool KSEval_t_scope( KSParseNode* node, KSContext& context )
2269
KSParseNode *left = node->branch1();
2270
// a construction like "{ }" ?
2275
context.scope()->localScope()->pushNamespace( &nspace );
2277
bool res = left->eval( context );
2279
context.scope()->localScope()->popNamespace();
2284
extern bool KSEval_t_try( KSParseNode* node, KSContext& context )
2287
context.scope()->localScope()->pushNamespace( &nspace );
2289
// Execute the questionable code
2290
KSParseNode *left = node->branch1();
2292
// No error -> Return
2293
if ( left->eval( context ) )
2295
context.scope()->localScope()->popNamespace();
2299
// We got an error. First resume the namespace. This
2300
// will do automatically a stack unwinding
2301
context.scope()->localScope()->popNamespace();
2303
// Execute the catch clauses
2304
KSParseNode *right = node->branch2();
2306
return right->eval( context );
2309
extern bool KSEval_t_catch( KSParseNode* node, KSContext& context )
2311
KSContext d( context );
2313
// Find the type to which we want to compare
2314
KSParseNode *left = node->branch1();
2316
if ( !left->eval( d ) )
2318
context.setException( d );
2322
// Exception of the correct type ?
2323
ASSERT( context.exception() );
2324
if ( context.exception()->type()->cmp( *d.value() ) )
2326
// Get infos about the exception
2327
KSValue* value = context.exception()->value();
2330
// Add variables to the namespace
2332
nspace.insert( node->getIdent(), new KSValue( *value ) );
2333
context.scope()->localScope()->pushNamespace( &nspace );
2335
// Clear the exception since we catched it
2336
context.setException( 0 );
2338
// Evaluate the catch code
2339
KSParseNode *right = node->branch2();
2342
/* bool res = */ right->eval( context );
2345
context.scope()->localScope()->popNamespace();
2350
// Could not catch. Try next if available
2351
KSParseNode* more = node->branch4();
2353
return more->eval( context );
2355
// We could not catch :-(
2359
extern bool KSEval_t_catch_default( KSParseNode* node, KSContext& context )
2361
KSContext d( context );
2363
// Find out na,me of the variable that
2365
KSParseNode *left = node->branch1();
2367
QString name1 = left->getIdent();
2369
// Clear the exception
2370
KSValue* type = context.exception()->type();
2372
KSValue* value = context.exception()->value();
2374
context.setException( 0 );
2376
// Add variables to the namespace
2378
nspace.insert( name1, new KSValue( *type ) );
2379
nspace.insert( node->getIdent(), new KSValue( *value ) );
2380
context.scope()->localScope()->pushNamespace( &nspace );
2382
// Evaluate the catch code
2383
KSParseNode *right = node->branch2();
2385
bool res = right->eval( context );
2387
context.scope()->localScope()->popNamespace();
2392
extern bool KSEval_t_raise( KSParseNode* node, KSContext& context )
2394
EVAL_OPS( context, l, r, false );
2396
// Raise the exception
2397
context.setException( new KSException( l.shareValue(), r.shareValue(), node->getLineNo() ) );
2402
extern bool KSEval_t_cell( KSParseNode* node, KSContext& context )
2404
return context.interpreter()->processExtension( context, node );
2407
extern bool KSEval_t_range( KSParseNode* node, KSContext& context )
2409
return context.interpreter()->processExtension( context, node );
2412
extern bool KSEval_from( KSParseNode* node, KSContext& context )
2414
// Get the list of symbols which have to be imported.
2415
QStringList lst = QStringList::split( "/", node->getStringLiteral() );
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() ) )
2421
context.setException( d );
2425
// Register the imported module in the scope
2426
context.scope()->addObject( node->getIdent(), d.shareValue() );
2428
// Import all symbols ?
2429
// Syntax: "from mymodule import *;"
2430
if ( lst.isEmpty() )
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() );
2438
// Syntax: "from mymodule import sym1, sym2;"
2441
// Import from this module
2442
KSModule* m = d.value()->moduleValue();
2444
// Iterate over all symbols that we should import
2445
QStringList::ConstIterator sit = lst.begin();
2446
for( ; sit != lst.end(); ++sit )
2449
KSValue* v = m->object( *sit );
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() ) );
2459
// Add the symbol to the current namespace
2461
context.scope()->module()->addObject( *sit, v );
2468
bool KSEval_plus_assign( KSParseNode* node, KSContext& context )
2470
EVAL_OPS( context, l, r, true );
2472
if ( l.value()->mode() != KSValue::LeftExpr )
2474
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
2478
if ( l.value()->type() == KSValue::TimeType )
2480
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2482
QTime t = l.value()->timeValue();
2483
t = t.addSecs( r.value()->intValue() );
2484
l.value()->setValue( t );
2486
else if ( l.value()->type() == KSValue::DateType )
2488
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2490
QDate d = l.value()->dateValue();
2491
d = d.addDays( r.value()->intValue() );
2492
l.value()->setValue( d );
2494
else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
2497
switch( l.value()->type() )
2499
case KSValue::IntType:
2500
l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
2502
case KSValue::DoubleType:
2503
l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
2505
case KSValue::StringType:
2506
l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
2508
case KSValue::ListType:
2509
l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
2511
case KSValue::MapType:
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() );
2520
case KSValue::TimeType:
2521
case KSValue::DateType:
2525
QString tmp( i18n("Operator += not defined for type %1") );
2526
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
2530
l.value()->setMode( KSValue::LeftExpr );
2532
context.setValue( l.shareValue() );
2537
bool KSEval_minus_assign( KSParseNode* node, KSContext& context )
2539
EVAL_OPS( context, l, r, true );
2541
if ( l.value()->mode() != KSValue::LeftExpr )
2543
context.setException( new KSException( "NoLeftExpr", i18n("Expected a left expression in assignment"), node->getLineNo() ) );
2547
if ( l.value()->type() == KSValue::TimeType )
2549
if ( KSUtil::checkType( context, r.value(), KSValue::TimeType, false ) )
2551
QTime d = r.value()->timeValue();
2552
int diff = d.secsTo( l.value()->timeValue() );
2553
l.value()->setValue( (KScript::Long)diff );
2557
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2559
QTime t = l.value()->timeValue();
2560
t = t.addSecs( -r.value()->intValue() );
2561
l.value()->setValue( t );
2564
else if ( l.value()->type() == KSValue::DateType )
2566
if ( KSUtil::checkType( context, r.value(), KSValue::DateType, false ) )
2568
QDate d = r.value()->dateValue();
2569
int diff = d.daysTo( l.value()->dateValue() );
2570
l.value()->setValue( (KScript::Long)diff );
2574
if ( !KSUtil::checkType( context, r.value(), KSValue::IntType, true ) )
2576
QDate d = l.value()->dateValue();
2577
d = d.addDays( -r.value()->intValue() );
2578
l.value()->setValue( d );
2581
else if ( !KSUtil::checkType( context, l.value(), r.value()->type(), true ) )
2585
switch( l.value()->type() )
2587
case KSValue::IntType:
2588
l.value()->setValue( r.value()->intValue() + l.value()->intValue() );
2590
case KSValue::DoubleType:
2591
l.value()->setValue( r.value()->doubleValue() + l.value()->doubleValue() );
2593
case KSValue::StringType:
2594
l.value()->setValue( l.value()->stringValue() + r.value()->stringValue() );
2596
case KSValue::ListType:
2597
l.value()->setValue( l.value()->listValue() + r.value()->listValue() );
2599
case KSValue::MapType:
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() );
2608
case KSValue::TimeType:
2609
case KSValue::DateType:
2613
QString tmp( i18n("Operator += not defined for type %1") );
2614
context.setException( new KSException( "UnknownOperation", tmp.arg( l.value()->typeName() ), node->getLineNo() ) );
2619
l.value()->setMode( KSValue::LeftExpr );
2621
context.setValue( l.shareValue() );
2626
bool KSEval_bool_or( KSParseNode* node, KSContext& context )
2628
EVAL_OPS( context, l, r, false );
2630
if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
2631
!KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
2633
context.exception()->addLine( node->getLineNo() );
2637
context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() || r.value()->boolValue() ) ) );
2642
bool KSEval_bool_and( KSParseNode* node, KSContext& context )
2644
EVAL_OPS( context, l, r, false );
2646
if ( !KSUtil::checkType( context, l.value(), KSValue::BoolType, true ) ||
2647
!KSUtil::checkType( context, r.value(), KSValue::BoolType, true ) )
2649
context.exception()->addLine( node->getLineNo() );
2653
context.setValue( new KSValue( (KScript::Boolean)( l.value()->boolValue() && r.value()->boolValue() ) ) );
2658
bool KSEval_t_regexp_group( KSParseNode* node, KSContext& context )
2660
KRegExp* exp = context.interpreter()->regexp();
2661
const char* grp = exp->group( node->getIntegerLiteral() );
2663
context.setValue( new KSValue( QString( grp ) ) );
2665
context.setValue( new KSValue( QString( "" ) ) );
2670
bool KSEval_t_input( KSParseNode*, KSContext& context )
2672
context.setValue( new KSValue( context.interpreter()->readInput() ) );
2677
bool KSEval_t_line( KSParseNode* /*node*/, KSContext& context )
2679
context.setValue( context.interpreter()->lastInputLine() );
2684
bool KSEval_t_match_line( KSParseNode* node, KSContext& context )
2686
KSValue::Ptr line = context.interpreter()->lastInputLine();
2687
if ( !KSUtil::checkType( context, line, KSValue::StringType, TRUE ) )
2690
KRegExp* exp = context.interpreter()->regexp();
2691
exp->compile( node->getIdent().latin1() );
2693
context.setValue( new KSValue( exp->match( line->stringValue().latin1() ) ) );
2698
bool KSEval_t_file_op( KSParseNode* node, KSContext& context )
2700
if ( !node->branch1()->eval( context ) )
2703
if ( !KSUtil::checkType( context, context.value(), KSValue::StringType, TRUE ) )
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() ) );