bool QSEngine::checkSyntax(const QString &code, int checkMode, bool deleteNodes) { return rep->evaluate(code, 0, true, checkMode); #if 0 Q_UNUSED(checkMode); Q_ASSERT(QSLexer::lexer()); #if defined (QT_THREAD_SUPPORT) && QT_VERSION >= 0x030300 QMutexLocker locker(qt_global_mutexpool ? qt_global_mutexpool->get(QSLexer::lexer()) : 0); #endif rep->errType = 0; rep->errLines.clear(); rep->errMsgs.clear(); QSLexer::lexer()->setCode(code, #ifdef QSDEBUGGER rep->sourceId() #else 0 #endif ); int parseError = qsyyparse(); QSNode *lastNode = QSProgramNode::last(); bool success = true; if (parseError) { rep->errType = QSErrParseError; int l = QSLexer::lexer()->lineNo(); rep->errLines.append(l); rep->errMsgs.append(QString::fromLatin1("Parse Error: ") + qs_format_error(QSLexer::lexer()->errorMessage())); success = false; } if (deleteNodes && lastNode && lastNode->deref()) delete lastNode; return success; #endif }
bool QSEngineImp::evaluate( const QString &code, const QSObject *thisV, bool onlyCheckSyntax, int checkMode, int lineZero ) { #if defined (QT_THREAD_SUPPORT) && QT_VERSION >= 0x030300 QMutex *mutex = qt_global_mutexpool ? qt_global_mutexpool->get(qApp) : 0; #endif QS_MUTEX_LOCK; QSProgramNode *progNode = 0; init(); #ifdef QSDEBUGGER incrSourceId(); if (debugger()) debugger()->setSourceId(sid); #endif if (recursion > 7) { qWarning( "QtScript: breaking out of recursion" ); QS_MUTEX_UNLOCK; return true; } assert(QSLexer::lexer()); { QSLexer::lexer()->setCode( code, #ifdef QSDEBUGGER sourceId(), #else 0, #endif lineZero ); int parseError = qsyyparse(); progNode = QSProgramNode::last(); if( parseError || QSLexer::lexer()->lexerState() == QSLexer::Bad ) { errType = QSErrParseError; int l = QSLexer::lexer()->lineNo(); errLines.append( l ); errMsgs.append( QString::fromLatin1("Parse Error: ") + qs_format_error( QSLexer::lexer()->errorMessage() ) ); /* TODO: either clear everything or keep previously parsed function definitions */ // QSNode::deleteAllNodes(); if (progNode && progNode->deref()) { delete progNode; } QS_MUTEX_UNLOCK; return false; } } QSCheckData sem( env(), env()->globalClass() ); if ( thisV ) { Q_ASSERT( thisV->isValid() ); // qDebug( "QSEngineImp::evaluate: entering %s", // thisV->typeName().latin1()); sem.enterClass( (QSClass*)thisV->objectType() ); env()->pushScope( *thisV ); } sem.setGlobalStatementsForbidden( checkMode & QSEngine::DisallowGlobal ); progNode->check( &sem ); if ( sem.hasError() ) { errType = sem.errorCode(); errLines = sem.errorLines(); errMsgs = sem.errorMessages(); if (progNode->deref()) delete progNode; QS_MUTEX_UNLOCK; return FALSE; } if (onlyCheckSyntax) { if (progNode->deref()) { delete progNode; } QS_MUTEX_UNLOCK; return true; } env()->clearException(); recursion++; assert(progNode); QS_MUTEX_UNLOCK; QSObject res = progNode->execute( env() ); QS_MUTEX_LOCK; recursion--; if ( env()->isExceptionMode( )) { QSObject err = env()->exception(); errType = 99; /* TODO */ errLines.append(QSErrorClass::errorLine(&err)); errMsgs.append(QSErrorClass::errorName(&err) + QString::fromLatin1(". ") + QSErrorClass::errorMessage(&err)); #ifdef QSDEBUGGER if (dbg) dbg->setSourceId(QSErrorClass::errorSourceId(&err)); #endif env()->clearException(); } else { errType = 0; errLines.clear(); errMsgs.clear(); // catch return value retVal = res; } if ( thisV ) { env()->popScope(); } if (progNode->deref()) { delete progNode; } QS_MUTEX_UNLOCK; return !errType; }
QSObject QSFuncRefClass::construct( const QSList &args ) const { // ### QString p = QString::fromLatin1(""); QString body; int argsSize = args.size(); if (argsSize == 0) { body = ""; } else if (argsSize == 1) { body = args[0].toString(); } else { p = args[0].toString(); for (int k = 1; k < argsSize - 1; k++) p += QString::fromLatin1(",") + args[k].toString(); body = args[argsSize-1].toString(); } QSLexer::lexer()->setCode( body, -1 ); if ( qsyyparse() ) { /* TODO: free nodes */ return env()->throwError( SyntaxError, QString::fromLatin1("Syntax error in function body") ); } QSFunctionScopeClass *scope = new QSFunctionScopeClass( env()->objectClass() ); QSFunctionBodyNode * bodyNode = QSProgramNode::last(); bodyNode->setScopeDefinition( scope ); scope->setFunctionBodyNode(bodyNode); QSMember mem( bodyNode ); // parse parameter list. throw syntax error on illegal identifiers int len = p.length(); const QChar *c = p.unicode(); int i = 0, params = 0; QString param; while (i < len) { while (*c == ' ' && i < len) c++, i++; if ( QSLexer::isIdentLetter( c->unicode() ) ) { // else error param = QString(c, 1); c++, i++; while (i < len && ( QSLexer::isIdentLetter( c->unicode() ) || QSLexer::isDecimalDigit( c->unicode() ) ) ) { param += QString(c, 1); c++, i++; } while (i < len && *c == ' ') c++, i++; if (i == len) { int index = scope->addVariableMember( param, AttributeNone ); Q_ASSERT( params==index ); params++; break; } else if (*c == ',') { int index = scope->addVariableMember( param, AttributeNone ); Q_ASSERT( params==index ); params++; c++, i++; continue; } // else error } return env()->throwError( SyntaxError, QString::fromLatin1("Syntax error in parameter list") ); } scope->setNumArguments( params ); return createReference( env()->currentScope(), mem ); }