00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "expression.h"
00024 #include "parser/sqlparser.h"
00025 #include "parser/parser_p.h"
00026
00027 #include <ctype.h>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031
00032 #include <qdatetime.h>
00033
00034 KEXI_DB_EXPORT QString KexiDB::exprClassName(int c)
00035 {
00036 if (c==KexiDBExpr_Unary)
00037 return "Unary";
00038 else if (c==KexiDBExpr_Arithm)
00039 return "Arithm";
00040 else if (c==KexiDBExpr_Logical)
00041 return "Logical";
00042 else if (c==KexiDBExpr_Relational)
00043 return "Relational";
00044 else if (c==KexiDBExpr_SpecialBinary)
00045 return "SpecialBinary";
00046 else if (c==KexiDBExpr_Const)
00047 return "Const";
00048 else if (c==KexiDBExpr_Variable)
00049 return "Variable";
00050 else if (c==KexiDBExpr_Function)
00051 return "Function";
00052 else if (c==KexiDBExpr_Aggregation)
00053 return "Aggregation";
00054 else if (c==KexiDBExpr_TableList)
00055 return "TableList";
00056
00057 return "Unknown";
00058 }
00059
00060 using namespace KexiDB;
00061
00062
00063
00064 BaseExpr::BaseExpr(int token)
00065 : m_cl(KexiDBExpr_Unknown)
00066 , m_par(0)
00067 , m_token(token)
00068 {
00069
00070 }
00071
00072 BaseExpr::~BaseExpr()
00073 {
00074 }
00075
00076 Field::Type BaseExpr::type()
00077 {
00078 return Field::InvalidType;
00079 }
00080
00081 QString BaseExpr::debugString()
00082 {
00083 return QString("BaseExpr(%1,type=%1)").arg(m_token).arg(Driver::defaultSQLTypeName(type()));
00084 }
00085
00086 bool BaseExpr::validate(ParseInfo& )
00087 {
00088 return true;
00089 }
00090
00091 extern const char * const tname(int offset);
00092 #define safe_tname(token) ((token>=254 && token<=__LAST_TOKEN) ? tname(token-254) : "")
00093
00094 QString BaseExpr::tokenToDebugString(int token)
00095 {
00096 if (token < 254) {
00097 if (isprint(token))
00098 return QString(QChar(uchar(token)));
00099 else
00100 return QString::number(token);
00101 }
00102 return QString(safe_tname(token));
00103 }
00104
00105 QString BaseExpr::tokenToString()
00106 {
00107 if (m_token < 255 && isprint(m_token))
00108 return tokenToDebugString();
00109 return QString::null;
00110 }
00111
00112 NArgExpr* BaseExpr::toNArg() { return dynamic_cast<NArgExpr*>(this); }
00113 UnaryExpr* BaseExpr::toUnary() { return dynamic_cast<UnaryExpr*>(this); }
00114 BinaryExpr* BaseExpr::toBinary() { return dynamic_cast<BinaryExpr*>(this); }
00115 ConstExpr* BaseExpr::toConst() { return dynamic_cast<ConstExpr*>(this); }
00116 VariableExpr* BaseExpr::toVariable() { return dynamic_cast<VariableExpr*>(this); }
00117 FunctionExpr* BaseExpr::toFunction() { return dynamic_cast<FunctionExpr*>(this); }
00118
00119
00120
00121 NArgExpr::NArgExpr(int aClass, int token)
00122 : BaseExpr(token)
00123 {
00124 m_cl = aClass;
00125 list.setAutoDelete(TRUE);
00126 }
00127
00128 NArgExpr::~NArgExpr()
00129 {
00130 }
00131
00132 QString NArgExpr::debugString()
00133 {
00134 QString s = QString("NArgExpr(")
00135 + "class=" + exprClassName(m_cl);
00136 for ( BaseExpr::ListIterator it(list); it.current(); ++it ) {
00137 s+=", ";
00138 s+=it.current()->debugString();
00139 }
00140 s+=")";
00141 return s;
00142 }
00143
00144 QString NArgExpr::toString()
00145 {
00146 QString s;
00147 s.reserve(256);
00148 for ( BaseExpr::ListIterator it(list); it.current(); ++it ) {
00149 if (!s.isEmpty())
00150 s+=", ";
00151 s+=it.current()->toString();
00152 }
00153 return s;
00154 }
00155
00156 BaseExpr* NArgExpr::arg(int nr)
00157 {
00158 return list.at(nr);
00159 }
00160
00161 void NArgExpr::add(BaseExpr *expr)
00162 {
00163 list.append(expr);
00164 expr->setParent(this);
00165 }
00166
00167 void NArgExpr::prepend(BaseExpr *expr)
00168 {
00169 list.prepend(expr);
00170 expr->setParent(this);
00171 }
00172
00173 int NArgExpr::args()
00174 {
00175 return list.count();
00176 }
00177
00178 bool NArgExpr::validate(ParseInfo& parseInfo)
00179 {
00180 if (!BaseExpr::validate(parseInfo))
00181 return false;
00182
00183 for (BaseExpr::ListIterator it(list); it.current(); ++it) {
00184 if (!it.current()->validate(parseInfo))
00185 return false;
00186 }
00187 return true;
00188 }
00189
00190
00191 UnaryExpr::UnaryExpr(int token, BaseExpr *arg)
00192 : BaseExpr(token)
00193 , m_arg(arg)
00194 {
00195 m_cl = KexiDBExpr_Unary;
00196
00197 if (m_arg)
00198 m_arg->setParent(this);
00199 }
00200
00201 UnaryExpr::~UnaryExpr()
00202 {
00203 delete m_arg;
00204 }
00205
00206 QString UnaryExpr::debugString()
00207 {
00208 return "UnaryExpr('"
00209 + tokenToDebugString() + "', "
00210 + (m_arg ? m_arg->debugString() : QString("<NONE>"))
00211 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00212 }
00213
00214 QString UnaryExpr::toString()
00215 {
00216 if (m_token=='(')
00217 return "(" + (m_arg ? m_arg->toString() : "<NULL>") + ")";
00218 if (m_token < 255 && isprint(m_token))
00219 return tokenToDebugString() + (m_arg ? m_arg->toString() : "<NULL>");
00220 if (m_token==NOT)
00221 return "NOT " + (m_arg ? m_arg->toString() : "<NULL>");
00222 if (m_token==SQL_IS_NULL)
00223 return (m_arg ? m_arg->toString() : "<NULL>") + " IS NULL";
00224 if (m_token==SQL_IS_NOT_NULL)
00225 return (m_arg ? m_arg->toString() : "<NULL>") + " IS NOT NULL";
00226 return QString("{INVALID_OPERATOR#%1} ").arg(m_token) + (m_arg ? m_arg->toString() : "<NULL>");
00227 }
00228
00229 Field::Type UnaryExpr::type()
00230 {
00231
00232
00233 switch (m_token) {
00234 case SQL_IS_NULL:
00235 case SQL_IS_NOT_NULL:
00236 return Field::Boolean;
00237 }
00238 const Field::Type t = m_arg->type();
00239 if (t==Field::Null)
00240 return Field::Null;
00241 if (m_token==NOT)
00242 return Field::Boolean;
00243
00244 return t;
00245 }
00246
00247 bool UnaryExpr::validate(ParseInfo& parseInfo)
00248 {
00249 if (!BaseExpr::validate(parseInfo))
00250 return false;
00251
00252 if (!m_arg->validate(parseInfo))
00253 return false;
00254
00255 return true;
00256 #if 0
00257 BaseExpr *n = l.at(0);
00258
00259 n->check();
00260
00261
00262
00263
00264
00265 if (is(NOT) && n->nodeTypeIs(TYP_BOOL)) {
00266 node_type=new NConstType(TYP_BOOL);
00267 }
00268 else if (is('#') && n->nodeTypeIs(TYP_STR)) {
00269 node_type=new NConstType(TYP_INT);
00270 }
00271 else if ((is('+') || is('-')) && n->nodeTypeIs(TYP_INT)) {
00272 node_type=new NConstType(TYP_INT);
00273 }
00274 else {
00275 ERR("Niepoprawny argument typu '%s' dla operatora '%s'",
00276 n->nodeTypeName(),is(NOT)?QString("not"):QChar(typ()));
00277 }
00278 #endif
00279 }
00280
00281
00282 BinaryExpr::BinaryExpr(int aClass, BaseExpr *left_expr, int token, BaseExpr *right_expr)
00283 : BaseExpr(token)
00284 , m_larg(left_expr)
00285 , m_rarg(right_expr)
00286 {
00287 m_cl = aClass;
00288
00289 if (m_larg)
00290 m_larg->setParent(this);
00291 if (m_rarg)
00292 m_rarg->setParent(this);
00293 }
00294
00295 BinaryExpr::~BinaryExpr()
00296 {
00297 delete m_larg;
00298 delete m_rarg;
00299 }
00300
00301 bool BinaryExpr::validate(ParseInfo& parseInfo)
00302 {
00303 if (!BaseExpr::validate(parseInfo))
00304 return false;
00305
00306 if (!m_larg->validate(parseInfo))
00307 return false;
00308 if (!m_rarg->validate(parseInfo))
00309 return false;
00310
00311 return true;
00312 }
00313
00314 Field::Type BinaryExpr::type()
00315 {
00316 const Field::Type lt = m_larg->type(), rt = m_rarg->type();
00317 if (lt==Field::Null || rt == Field::Null) {
00318 if (m_token!=OR)
00319 return Field::Null;
00320 }
00321
00322 switch (m_token) {
00323 case AND:
00324 case OR:
00325 case XOR:
00326 case SIMILAR_TO:
00327 return Field::Boolean;
00328 }
00329
00330 if (Field::isFPNumericType(lt) && Field::isIntegerType(rt))
00331 return lt;
00332
00333
00334
00335 return left()->type();
00336 }
00337
00338 QString BinaryExpr::debugString()
00339 {
00340 return QString("BinaryExpr(")
00341 + "class=" + exprClassName(m_cl)
00342 + "," + (m_larg ? m_larg->debugString() : QString("<NONE>"))
00343 + ",'" + tokenToDebugString() + "',"
00344 + (m_rarg ? m_rarg->debugString() : QString("<NONE>"))
00345 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00346 }
00347
00348 QString BinaryExpr::tokenToString()
00349 {
00350 if (m_token < 255 && isprint(m_token))
00351 return tokenToDebugString();
00352
00353 switch (m_token) {
00354 case BITWISE_SHIFT_RIGHT: return ">>";
00355 case BITWISE_SHIFT_LEFT: return "<<";
00356
00357 case NOT_EQUAL: return "<>";
00358 case NOT_EQUAL2: return "!=";
00359 case LESS_OR_EQUAL: return "<=";
00360 case GREATER_OR_EQUAL: return ">=";
00361 case LIKE: return "LIKE";
00362 case SQL_IN: return "IN";
00363
00364 case SIMILAR_TO: return "SIMILAR TO";
00365 case NOT_SIMILAR_TO: return "NOT SIMILAR TO";
00366 case OR: return "OR";
00367 case AND: return "AND";
00368 case XOR: return "XOR";
00369
00370 case CONCATENATION: return "||";
00371
00372
00373 default:;
00374 }
00375 return QString("{INVALID_BINARY_OPERATOR#%1} ").arg(m_token);
00376 }
00377
00378 QString BinaryExpr::toString()
00379 {
00380 #define INFIX(a) \
00381 (m_larg ? m_larg->toString() : "<NULL>") + " " + a + " " + (m_rarg ? m_rarg->toString() : "<NULL>")
00382
00383 return INFIX(tokenToString());
00384 }
00385
00386
00387 ConstExpr::ConstExpr( int token, const QVariant& val)
00388 : BaseExpr( token )
00389 , value(val)
00390 {
00391 m_cl = KexiDBExpr_Const;
00392 }
00393
00394 ConstExpr::~ConstExpr()
00395 {
00396 }
00397
00398 Field::Type ConstExpr::type()
00399 {
00400 if (m_token==SQL_NULL)
00401 return Field::Null;
00402 else if (m_token==INTEGER_CONST) {
00403
00404
00405 if (value.type() == QVariant::Int || value.type() == QVariant::UInt) {
00406 Q_LLONG v = value.toInt();
00407 if (v <= 0xff && v > -0x80)
00408 return Field::Byte;
00409 if (v <= 0xffff && v > -0x8000)
00410 return Field::ShortInteger;
00411 return Field::Integer;
00412 }
00413 return Field::BigInteger;
00414 }
00415 else if (m_token==CHARACTER_STRING_LITERAL) {
00416
00417 if (value.toString().length() > Field::defaultTextLength())
00418 return Field::LongText;
00419 else
00420 return Field::Text;
00421 }
00422 else if (m_token==REAL_CONST)
00423 return Field::Double;
00424 else if (m_token==DATE_CONST)
00425 return Field::Date;
00426 else if (m_token==DATETIME_CONST)
00427 return Field::DateTime;
00428 else if (m_token==TIME_CONST)
00429 return Field::Time;
00430
00431 return Field::InvalidType;
00432 }
00433
00434 QString ConstExpr::debugString()
00435 {
00436 return QString("ConstExpr('") + tokenToDebugString() +"'," + toString()
00437 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00438 }
00439
00440 QString ConstExpr::toString()
00441 {
00442 if (m_token==SQL_NULL)
00443 return "NULL";
00444 else if (m_token==CHARACTER_STRING_LITERAL)
00445
00446 return "'" + value.toString() + "'";
00447 else if (m_token==REAL_CONST)
00448 return QString::number(value.toPoint().x())+"."+QString::number(value.toPoint().y());
00449 else if (m_token==DATE_CONST)
00450 return "'" + value.toDate().toString(Qt::ISODate) + "'";
00451 else if (m_token==DATETIME_CONST)
00452 return "'" + value.toDateTime().date().toString(Qt::ISODate) + " " + value.toDateTime().time().toString(Qt::ISODate) + "'";
00453 else if (m_token==TIME_CONST)
00454 return "'" + value.toTime().toString(Qt::ISODate) + "'";
00455
00456 return value.toString();
00457 }
00458
00459 bool ConstExpr::validate(ParseInfo& parseInfo)
00460 {
00461 if (!BaseExpr::validate(parseInfo))
00462 return false;
00463
00464 return type()!=Field::InvalidType;
00465 }
00466
00467
00468 VariableExpr::VariableExpr( const QString& _name)
00469 : BaseExpr( 0 )
00470 , name(_name)
00471 , field(0)
00472 , tablePositionForField(-1)
00473 , tableForQueryAsterisk(0)
00474 {
00475 m_cl = KexiDBExpr_Variable;
00476 }
00477
00478 VariableExpr::~VariableExpr()
00479 {
00480 }
00481
00482 QString VariableExpr::debugString()
00483 {
00484 return QString("VariableExpr(") + name
00485 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00486 }
00487
00488 QString VariableExpr::toString()
00489 {
00490 return name;
00491 }
00492
00494 Field::Type VariableExpr::type()
00495 {
00496 if (field)
00497 return field->type();
00498
00499
00500 return Field::InvalidType;
00501 }
00502
00503 #define IMPL_ERROR(errmsg) parseInfo.errMsg = "Implementation error"; parseInfo.errDescr = errmsg
00504
00505 bool VariableExpr::validate(ParseInfo& parseInfo)
00506 {
00507 if (!BaseExpr::validate(parseInfo))
00508 return false;
00509 field = 0;
00510 tablePositionForField = -1;
00511 tableForQueryAsterisk = 0;
00512
00513
00514 KexiDBDbg << "checking variable name: " << name << endl;
00515 int dotPos = name.find('.');
00516 QString tableName, fieldName;
00517
00518 if (dotPos>0) {
00519 tableName = name.left(dotPos);
00520 fieldName = name.mid(dotPos+1);
00521 }
00522 if (tableName.isEmpty()) {
00523 fieldName = name;
00524 if (fieldName=="*") {
00525
00526 return true;
00527 }
00528
00529
00530 Field *firstField = 0;
00531 for (TableSchema::ListIterator it(*parseInfo.querySchema->tables()); it.current(); ++it) {
00532 Field *f = it.current()->field(fieldName);
00533 if (f) {
00534 if (!firstField) {
00535 firstField = f;
00536 }
00537 else if (f->table()!=firstField->table()) {
00538
00539 parseInfo.errMsg = i18n("Ambiguous field name");
00540 parseInfo.errDescr = i18n("Both table \"%1\" and \"%2\" have defined \"%3\" field. "
00541 "Use \"<tableName>.%4\" notation to specify table name.")
00542 .arg(firstField->table()->name()).arg(f->table()->name())
00543 .arg(fieldName).arg(fieldName);
00544 return false;
00545 }
00546 }
00547 }
00548 if (!firstField) {
00549 parseInfo.errMsg = i18n("Field not found");
00550 parseInfo.errDescr = i18n("Table containing \"%1\" field not found").arg(fieldName);
00551 return false;
00552 }
00553
00554 field = firstField;
00555
00556 return true;
00557 }
00558
00559
00560 tableName = tableName.lower();
00561 TableSchema *ts = parseInfo.querySchema->table( tableName );
00562 if (ts) {
00563
00564 const QValueList<int> tPositions = parseInfo.querySchema->tablePositions(tableName);
00565 QValueList<int>::ConstIterator it = tPositions.constBegin();
00566 QCString tableAlias;
00567 bool covered = true;
00568 for (; it!=tPositions.constEnd() && covered; ++it) {
00569 tableAlias = parseInfo.querySchema->tableAlias(*it);
00570 if (tableAlias.isEmpty() || tableAlias.lower()==tableName.latin1())
00571 covered = false;
00572 KexiDBDbg << " --" << "covered by " << tableAlias << " alias" << endl;
00573 }
00574 if (covered) {
00575 parseInfo.errMsg = i18n("Could not access the table directly using its name");
00576 parseInfo.errDescr = i18n("Table \"%1\" is covered by aliases. Instead of \"%2\", "
00577 "you can write \"%3\"").arg(tableName)
00578 .arg(tableName+"."+fieldName).arg(tableAlias+"."+fieldName.latin1());
00579 return false;
00580 }
00581 }
00582
00583 int tablePosition = -1;
00584 if (!ts) {
00585 tablePosition = parseInfo.querySchema->tablePositionForAlias( tableName.latin1() );
00586 if (tablePosition>=0) {
00587 ts = parseInfo.querySchema->tables()->at(tablePosition);
00588 if (ts) {
00589
00590 }
00591 }
00592 }
00593
00594 if (!ts) {
00595 parseInfo.errMsg = i18n("Table not found");
00596 parseInfo.errDescr = i18n("Unknown table \"%1\"").arg(tableName);
00597 return false;
00598 }
00599
00600 QValueList<int> *positionsList = parseInfo.repeatedTablesAndAliases[ tableName ];
00601 if (!positionsList) {
00602 IMPL_ERROR(tableName + "." + fieldName + ", !positionsList ");
00603 return false;
00604 }
00605
00606
00607 if (fieldName=="*") {
00608 if (positionsList->count()>1) {
00609 parseInfo.errMsg = i18n("Ambiguous \"%1.*\" expression").arg(tableName);
00610 parseInfo.errDescr = i18n("More than one \"%1\" table or alias defined").arg(tableName);
00611 return false;
00612 }
00613 tableForQueryAsterisk = ts;
00614
00615 return true;
00616 }
00617
00618
00619 Field *realField = ts->field(fieldName);
00620 if (!realField) {
00621 parseInfo.errMsg = i18n("Field not found");
00622 parseInfo.errDescr = i18n("Table \"%1\" has no \"%2\" field")
00623 .arg(tableName).arg(fieldName);
00624 return false;
00625 }
00626
00627
00628
00629 int numberOfTheSameFields = 0;
00630 for (QValueList<int>::iterator it = positionsList->begin();
00631 it!=positionsList->end();++it)
00632 {
00633 TableSchema *otherTS = parseInfo.querySchema->tables()->at(*it);
00634 if (otherTS->field(fieldName))
00635 numberOfTheSameFields++;
00636 if (numberOfTheSameFields>1) {
00637 parseInfo.errMsg = i18n("Ambiguous \"%1.%2\" expression")
00638 .arg(tableName).arg(fieldName);
00639 parseInfo.errDescr = i18n("More than one \"%1\" table or alias defined containing \"%2\" field")
00640 .arg(tableName).arg(fieldName);
00641 return false;
00642 }
00643 }
00644 field = realField;
00645 tablePositionForField = tablePosition;
00646
00647
00648 return true;
00649 }
00650
00651
00652 static QValueList<QCString> FunctionExpr_builtIns;
00653 static const char* FunctionExpr_builtIns_[] =
00654 {"SUM", "MIN", "MAX", "AVG", "COUNT", "STD", "STDDEV", "VARIANCE", 0 };
00655
00656 QValueList<QCString> FunctionExpr::builtInAggregates()
00657 {
00658 if (FunctionExpr_builtIns.isEmpty()) {
00659 for (const char **p = FunctionExpr_builtIns_; *p; p++)
00660 FunctionExpr_builtIns << *p;
00661 }
00662 return FunctionExpr_builtIns;
00663 }
00664
00665 FunctionExpr::FunctionExpr( const QString& _name, NArgExpr* args_ )
00666 : BaseExpr( 0 )
00667 , name(_name)
00668 , args(args_)
00669 {
00670 if (isBuiltInAggregate(name.latin1()))
00671 m_cl = KexiDBExpr_Aggregation;
00672 else
00673 m_cl = KexiDBExpr_Function;
00674 args->setParent( this );
00675 }
00676
00677 FunctionExpr::~FunctionExpr()
00678 {
00679 delete args;
00680 }
00681
00682 QString FunctionExpr::debugString()
00683 {
00684 return QString("FunctionExpr(") + name + "," + args->debugString()
00685 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00686 }
00687
00688 QString FunctionExpr::toString()
00689 {
00690 return name + "(" + args->toString() + ")";
00691 }
00692
00693 Field::Type FunctionExpr::type()
00694 {
00695
00696 return Field::InvalidType;
00697 }
00698
00699 bool FunctionExpr::validate(ParseInfo& parseInfo)
00700 {
00701 if (!BaseExpr::validate(parseInfo))
00702 return false;
00703
00704 return args->validate(parseInfo);
00705 }
00706
00707 bool FunctionExpr::isBuiltInAggregate(const QCString& fname)
00708 {
00709 return builtInAggregates().find(fname.upper())!=FunctionExpr_builtIns.end();
00710 }
00711
00712 #if 0
00713
00714 ArithmeticExpr::ArithmeticExpr(BaseExpr *l_n, int typ, BaseExpr *r_n)
00715 : BinaryExpr(l_n,typ,r_n)
00716 {
00717 }
00718
00719 void ArithmeticExpr::check() {
00720 BinaryExpr::check();
00721
00722 BaseExpr *l_n = l.at(0);
00723 BaseExpr *r_n = l.at(1);
00724 ASSERT(l_n!=NULL);
00725 ASSERT(r_n!=NULL);
00726
00727 l_n->check();
00728 r_n->check();
00729
00730
00731
00732
00733 if (l_n->nodeTypeIs(TYP_INT) && r_n->nodeTypeIs(TYP_INT)) {
00734 node_type=new NConstType(TYP_INT);
00735 }
00736 else if (l_n->nodeTypeIs(TYP_STR) && r_n->nodeTypeIs(TYP_STR) && is('+')) {
00737 node_type=new NConstType(TYP_STR);
00738 }
00739 else {
00740 ERR("Niepoprawne argumenty typu '%s' i '%s' dla operatora '%s'",
00741 l_n->nodeTypeName(),
00742 r_n->nodeTypeName(),
00743 QChar(typ()));
00744 }
00745 debug("ArithmeticExpr::check() OK");
00746 }
00747
00748
00749 RelationalExpr::RelationalExpr(BaseExpr *l_n, int typ, BaseExpr *r_n)
00750 : BinaryExpr(l_n,typ,r_n)
00751 {
00752 }
00753
00754 void RelationalExpr::check()
00755 {
00756 BinaryExpr::check();
00757 BaseExpr *l_n = l.at(0);
00758 BaseExpr *r_n = l.at(1);
00759 ASSERT(l_n!=NULL);
00760 ASSERT(r_n!=NULL);
00761
00762 l_n->check();
00763 r_n->check();
00764
00765 char errop=0;
00766
00767
00768
00769
00770
00771
00772
00773
00774 if ((l_n->nodeTypeIs(TYP_INT) && r_n->nodeTypeIs(TYP_INT))
00775 ||(l_n->nodeTypeIs(TYP_STR) && r_n->nodeTypeIs(TYP_STR))) {
00776 switch (typ()) {
00777 case '=':
00778 case '<':
00779 case '>':
00780 case REL_ROZNE:
00781 case REL_MN_ROWNE:
00782 case REL_WIEK_ROWNE:
00783 break;
00784 default:
00785 errop=1;
00786 }
00787 }
00788
00789
00790
00791 else if ((l_n->nodeTypeIs(TYP_BOOL)
00792 || l_n->nodeTypeIs(TYP_DICT)
00793 || l_n->nodeTypeIs(TYP_CLASS)
00794 || l_n->nodeTypeIs(TYP_NIL))
00795 && r_n->nodeType()->like(l_n->nodeType())) {
00796 switch (typ()) {
00797 case '=':
00798 case REL_ROZNE:
00799 break;
00800 default:
00801 errop=1;
00802 }
00803 }
00804 else
00805 errop=1;
00806
00807 if (errop) {
00808 ERR("Niepoprawne argumenty typu '%s' i '%s' dla operatora relacyjnego '%s'",
00809 l_n->nodeTypeName(),
00810 r_n->nodeTypeName(),
00811 tname());
00812 }
00813 else {
00814 node_type=new NConstType(TYP_BOOL);
00815 }
00816 }
00817
00818
00819 LogicalExpr::LogicalExpr(BaseExpr *l_n, int typ, BaseExpr *r_n)
00820 : BinaryExpr(l_n,typ,r_n)
00821 {
00822 }
00823
00824 void LogicalExpr::check()
00825 {
00826 BinaryExpr::check();
00827 BaseExpr *l_n = l.at(0);
00828 BaseExpr *r_n = l.at(1);
00829 ASSERT(l_n!=NULL);
00830 ASSERT(r_n!=NULL);
00831
00832 l_n->check();
00833 r_n->check();
00834
00835
00836
00837 if (l_n->nodeTypeIs(TYP_BOOL)
00838 && r_n->nodeTypeIs(TYP_BOOL)) {
00839 node_type = l_n->nodeType();
00840 }
00841 else {
00842 ERR("Niepoprawne argumenty typu '%s' i '%s' dla operacji logicznej '%s'",
00843 l_n->nodeTypeName(),
00844 r_n->nodeTypeName(),
00845 QString(is(AND)?"and":"or"));
00846 }
00847 }
00848 #endif
00849
00850 #if 0
00851 NConstInt::NConstInt(int v)
00852 : BaseExpr(CONST_INT), val(v)
00853 {
00854 node_type = new NConstType(TYP_INT);
00855 }
00856
00857 const QString NConstInt::dump() {
00858 return QString(name()) + "(" + QString::number(val)+ ")";
00859 }
00860
00861 const QString NConstInt::name() { return "ConstInt"; }
00862
00863 int NConstInt::value() { return val; }
00864
00865 void NConstInt::check() {
00866 BaseExpr::check();
00867 }
00868
00869
00870
00871 NConstBool::NConstBool(const char v)
00872 : BaseExpr(CONST_BOOL), val(v)
00873 {
00874 node_type = new NConstType(TYP_BOOL);
00875 }
00876
00877 const QString NConstBool::dump() {
00878 return QString(name()) + "(" + QString::number(val) + ")";
00879 }
00880
00881 const QString NConstBool::name() { return "ConstBool"; }
00882
00883 const char NConstBool::value() { return val; }
00884
00885 void NConstBool::check() {
00886 BaseExpr::check();
00887 }
00888
00889
00890
00891 NConstStr::NConstStr(const char *v)
00892 : BaseExpr(CONST_STR), val(v)
00893 {
00894 node_type = new NConstType(TYP_STR);
00895 }
00896
00897 const QString NConstStr::dump() {
00898 return QString(name()) + "(" + val + ")";
00899 }
00900
00901 const QString NConstStr::name() {
00902 return "ConstStr"; }
00903
00904 const QString NConstStr::value() {
00905 return val; }
00906
00907 void NConstStr::check() {
00908 BaseExpr::check();
00909
00910 lab=generateUniqueLabel("const");
00911 gen.mlabel(lab);
00912 gen.mcode(MN_TEXT,val);
00913 }
00914
00915 #endif
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935