00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026
00027 #include <koscript_parser.h>
00028 #include <koscript_util.h>
00029 #include <koscript_func.h>
00030 #include <koscript_synext.h>
00031
00032 #include "kspread_functions.h"
00033 #include "kspread_util.h"
00034
00035
00036 bool kspreadfunc_and( KSContext& context );
00037 bool kspreadfunc_false( KSContext& context );
00038 bool kspreadfunc_if( KSContext& context );
00039 bool kspreadfunc_nand( KSContext& context );
00040 bool kspreadfunc_nor( KSContext& context );
00041 bool kspreadfunc_not( KSContext& context );
00042 bool kspreadfunc_or( KSContext& context );
00043 bool kspreadfunc_true( KSContext& context );
00044 bool kspreadfunc_xor( KSContext& context );
00045
00046
00047 void KSpreadRegisterLogicFunctions()
00048 {
00049 KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00050
00051 repo->registerFunction( "AND", kspreadfunc_and );
00052 repo->registerFunction( "FALSE", kspreadfunc_false );
00053 repo->registerFunction( "IF", kspreadfunc_if );
00054 repo->registerFunction( "NAND", kspreadfunc_nand );
00055 repo->registerFunction( "NOR", kspreadfunc_nor );
00056 repo->registerFunction( "NOT", kspreadfunc_not );
00057 repo->registerFunction( "OR", kspreadfunc_or );
00058 repo->registerFunction( "TRUE", kspreadfunc_true );
00059 repo->registerFunction( "XOR", kspreadfunc_xor );
00060 }
00061
00062
00063 bool kspreadfunc_false( KSContext & context )
00064 {
00065 context.setValue( new KSValue( FALSE ) );
00066 return true;
00067 }
00068
00069
00070 bool kspreadfunc_true( KSContext & context )
00071 {
00072 context.setValue( new KSValue( TRUE ) );
00073 return true;
00074 }
00075
00076
00077 bool kspreadfunc_not( KSContext& context )
00078 {
00079 QValueList<KSValue::Ptr>& args = context.value()->listValue();
00080
00081 if ( !KSUtil::checkArgumentsCount( context, 1, "NOT", true ) || !KSUtil::checkArgumentsCount( context, 1, "not", true ) )
00082 return false;
00083
00084 if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
00085 return false;
00086
00087 bool toto = !args[0]->boolValue();
00088 context.setValue( new KSValue(toto));
00089 return true;
00090 }
00091
00092 bool kspreadfunc_or_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00093 {
00094 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00095 QValueList<KSValue::Ptr>::Iterator end = args.end();
00096
00097 for( ; it != end; ++it )
00098 {
00099 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00100 {
00101 if ( !kspreadfunc_or_helper( context, (*it)->listValue(), first ) )
00102 return false;
00103 }
00104 else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00105 first = (first || (*it)->boolValue());
00106 else
00107 return false;
00108 }
00109
00110 return true;
00111 }
00112
00113
00114 bool kspreadfunc_or( KSContext& context )
00115 {
00116 bool first = false;
00117 bool b = kspreadfunc_or_helper( context, context.value()->listValue(), first );
00118
00119 if ( b )
00120 context.setValue( new KSValue( first ) );
00121
00122 return b;
00123 }
00124
00125
00126 bool kspreadfunc_nor( KSContext& context )
00127 {
00128 bool first = false;
00129 bool b = kspreadfunc_or_helper( context, context.value()->listValue(), first );
00130
00131 if ( b )
00132 context.setValue( new KSValue( !first ) );
00133
00134 return b;
00135 }
00136
00137
00138 bool kspreadfunc_and_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00139 {
00140 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00141 QValueList<KSValue::Ptr>::Iterator end = args.end();
00142
00143 for( ; it != end; ++it )
00144 {
00145 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00146 {
00147 if ( !kspreadfunc_and_helper( context, (*it)->listValue(), first ) )
00148 return false;
00149 }
00150 else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00151 first = first && (*it)->boolValue();
00152 else
00153 return false;
00154 }
00155
00156 return true;
00157 }
00158
00159
00160 bool kspreadfunc_and( KSContext& context )
00161 {
00162 bool first = true;
00163 bool b = kspreadfunc_and_helper( context, context.value()->listValue(), first );
00164
00165 if ( b )
00166 context.setValue( new KSValue( first ) );
00167
00168 return b;
00169 }
00170
00171
00172 bool kspreadfunc_nand( KSContext& context )
00173 {
00174 bool first = true;
00175 bool b = kspreadfunc_and_helper( context, context.value()->listValue(), first );
00176
00177 if ( b )
00178 context.setValue( new KSValue( !first ) );
00179
00180 return b;
00181 }
00182
00183 static bool kspreadfunc_xor_helper( KSContext& context, QValueList<KSValue::Ptr>& args, bool& first )
00184 {
00185 QValueList<KSValue::Ptr>::Iterator it = args.begin();
00186 QValueList<KSValue::Ptr>::Iterator end = args.end();
00187
00188 for( ; it != end; ++it )
00189 {
00190 if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00191 {
00192 if ( !kspreadfunc_xor_helper( context, (*it)->listValue(), first ) )
00193 return false;
00194 }
00195 else if ( KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00196 first = first ^ (*it)->boolValue();
00197 else
00198 return false;
00199 }
00200
00201 return true;
00202 }
00203
00204
00205 bool kspreadfunc_xor( KSContext& context )
00206 {
00207 bool first = false;
00208 bool b = kspreadfunc_xor_helper( context, context.value()->listValue(), first );
00209
00210 if ( b )
00211 context.setValue( new KSValue( first ) );
00212
00213 return b;
00214 }
00215
00216
00217 bool kspreadfunc_if( KSContext& context )
00218 {
00219 QValueList<KSValue::Ptr>& args = context.value()->listValue();
00220
00221 if ( !KSUtil::checkArgumentsCount( context, 3, "if", true ) || !KSUtil::checkArgumentsCount( context, 3, "IF", true ))
00222 return false;
00223
00224 if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
00225 return false;
00226
00227 if ( args[0]->boolValue() == true )
00228 context.setValue( new KSValue( *(args[1]) ) );
00229 else
00230 context.setValue( new KSValue( *(args[2]) ) );
00231
00232 return true;
00233 }