QTextCursor ScCodeEditor::regionAroundCursor(const QTextCursor & cursor)
{
    int cursorPosition = cursor.position();

    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while (it.isValid()) {
        nextBracketPair(it, bracketPair);
        if (bracketPair.first.isValid() && bracketPair.first.position() < cursorPosition)
        {
            if ( bracketPair.second.isValid() && bracketPair.second.position() >= cursorPosition
                 && bracketPairDefinesRegion(bracketPair) )
            {
                QTextCursor regionCursor(QPlainTextEdit::document());
                regionCursor.setPosition(bracketPair.first.position() + 1);
                regionCursor.setPosition(bracketPair.second.position(), QTextCursor::KeepAnchor);
                return regionCursor;
            }
        } else {
            break;
        }

        it = bracketPair.second;
    }

    return QTextCursor();
}
Exemple #2
0
inline static bool tokenIsFirstAndOnlyInBlock( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    bool result = it->positionInBlock == 0;
    result = result && static_cast<TextBlockData*>(it.block().userData())->tokens.size() == 1;
    return result;
}
Exemple #3
0
bool 
PreProcessor::elif_directive()
{
	assert(tokenit.is(_PP_ELIF));
	tokenit.next();

	if (ifBlockEnables.empty()) {
		ERROR("'if' directive is not found");
		return false;
	}

	bool if_is_enable = ifBlockEnables.back();
	if (if_is_enable) {
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	} else {
		AST *ast = expression();
		if (!ast) {
			return false;
		}
		if (eval(ast)) {
			ifBlockEnables.pop_back();
			ifBlockEnables.push_back(true);
		} else {
			TokenIterator tag = tokenit;
			skipUntilElseOrEnd();
			tag.erase(tokenit-tag);
		}
	}
	return true;
}
void ScCodeEditor::gotoPreviousRegion()
{
    QTextCursor cursor = textCursor();
    int cursorPosition = cursor.position();

    BracketPair prevBracketPair;
    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while(it.isValid()) {
        nextBracketPair(it, bracketPair);
        if ( !bracketPair.second.isValid()
             || bracketPair.second.position() >= cursorPosition - 1 )
        {
            break;
        }
        if (bracketPairDefinesRegion(bracketPair)) {
            prevBracketPair = bracketPair;
        }
        it = bracketPair.second;
    }

    if ( prevBracketPair.first.isValid() && prevBracketPair.second.isValid() )
    {
        setTextCursor( cursorAt(prevBracketPair.second, 1) );
        return;
    }

    cursor.movePosition(QTextCursor::Start);
    setTextCursor(cursor);
}
Exemple #5
0
static bool bracketPairDefinesRegion( const BracketPair & bracketPair )
{
    Q_ASSERT(bracketPair.first.isValid());
    Q_ASSERT(bracketPair.second.isValid());

    if ( bracketPair.first->character != '(' || bracketPair.second->character != ')' )
        return false;

    if (!tokenIsFirstAndOnlyInBlock(bracketPair.second) || !tokenIsFirstAndOnlyInBlock(bracketPair.second))
        return false;

    // check whether this is an Event
    TokenIterator it = bracketPair.first.next();
    if (it.isValid()) {
        if (it->type == Token::SymbolArg)
            return false;
        else {
            ++it;
            if (it.isValid() && it->character == ':')
                return false;
        }
    }

    return true;
}
Exemple #6
0
void
PreProcessor::applyMacro(const String &ident, const ref<MacroDef> &macro)
{
	assert(tokenit.is(_IDENT));
	
	DBG("apply macro: %s", ident.c_str());
	if (macro->params.empty()) {
		tokenit.erase(1);//erase identifier
		tokenit.insert(macro->tokens);
	} else {
		TokenIterator tag = tokenit;
		tokenit.next();
		//get caller params
		if (tokenit.is(_LPAREN)) {
			tokenit.next();
			List<List<Token> > caller_params;
			if (!parseFunctionParams(caller_params)) {
				ERROR("failed to parse function macro");
				return;
			}
			if (macro->params.size() != caller_params.size()) {
				ERROR("macro %s requres %d parameters", 
					  ident.c_str(), macro->params.size());
				return;
			}
			tag.erase(tokenit-tag);//erase function call tokens

			//replace macro params
			List<Token> replace_tokens = replaceMacroParams(macro->tokens, caller_params);
			tokenit.insert(replace_tokens);
			//tokenit.next();
		}
	}
}
Exemple #7
0
bool 
PreProcessor::else_directive()
{
	assert(tokenit.is(_PP_ELSE));
	tokenit.next();
	if (!tokenit.is(_PP_END)) {
		//TODO: warning
	} 
	tokenit.skipUntil({_PP_END}, true);
	tokenit.next();

	if (ifBlockEnables.empty()) {
		ERROR("'if' directive is not found (before 'else')");
		return false;
	}
	bool if_is_enable = ifBlockEnables.back();
	if (if_is_enable) {
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	} else {
		ifBlockEnables.pop_back();
		ifBlockEnables.push_back(true);
	}

	return true;
}
QTextCursor ScCodeEditor::cursorAt(const TokenIterator it, int offset)
{
    Q_ASSERT(it.isValid());

    QTextCursor textCursor(textDocument());
    textCursor.setPosition(it.position() + offset);

    return textCursor;
}
inline static bool tokenMaybeRegionEnd( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    if (it->character != ')')
        return false;
    TokenIterator next_it = it.next();
    return (!next_it.isValid() ||
            next_it.block() != it.block() ||
            next_it->character == ';');
}
void ScCodeEditor::matchBracket( const TokenIterator & bracket, BracketPair & match )
{
    Q_ASSERT(bracket.isValid());

    switch(bracket->type) {
    case Token::OpeningBracket:
        match.first = bracket;
        match.second = nextClosingBracket(bracket.next());
        break;
    case Token::ClosingBracket:
        match.second = bracket;
        match.first = previousOpeningBracket(bracket.previous());
        break;
    default:
        match.first = TokenIterator();
        match.second = TokenIterator();
    }
}
void ScCodeEditor::gotoNextBlock()
{
    QTextCursor cursor = textCursor();

    TokenIterator tokenIt = TokenIterator::rightOf( cursor.block(), cursor.positionInBlock() );
    if (tokenIt.type() == Token::OpeningBracket
            && tokenIt.block() == cursor.block()
            && tokenIt->positionInBlock == cursor.positionInBlock())
        ++tokenIt;

    tokenIt = nextClosingBracket( tokenIt );

    if (tokenIt.isValid())
        setTextCursor( cursorAt(tokenIt, 1) );
    else {
        cursor.movePosition( QTextCursor::End );
        setTextCursor( cursor );
    }
}
void ScCodeEditor::gotoPreviousBlock()
{
    QTextCursor cursor = textCursor();

    TokenIterator tokenIt = TokenIterator::leftOf(cursor.block(), cursor.positionInBlock());
    if (tokenIt.type() == Token::ClosingBracket
            && tokenIt.block() == cursor.block()
            && tokenIt->positionInBlock == cursor.positionInBlock() - 1)
        --tokenIt;


    tokenIt = previousOpeningBracket( tokenIt );

    if (tokenIt.isValid())
        setTextCursor( cursorAt(tokenIt) );
    else {
        cursor.movePosition( QTextCursor::Start );
        setTextCursor( cursor );
    }
}
Exemple #13
0
bool 
PreProcessor::if_directive()
{
	assert(tokenit.is(_PP_IF));
	tokenit.next();

	AST *ast = expression();
	if (!ast) {
		return false;
	}

	if (eval(ast)) {
		ifBlockEnables.push_back(true);
	} else {
		ifBlockEnables.push_back(false);
		TokenIterator tag = tokenit;
		skipUntilElseOrEnd();
		tag.erase(tokenit-tag);
	}
	return true;
}
Exemple #14
0
/*******************************************************************
* Function Name: readToken
* Description: tokenize words
********************************************************************/
Ini::Token Ini::readToken( TokenIterator &cursor, string &word )
{
	if( (*cursor)[0] == '[' )
	{
		word = lowerCase( cursor->substr(1, cursor->size() - 2) );
		cursor++ ;
		return group_TK ;
	}
	word = lowerCase( *cursor );
	cursor ++ ;

	if( *cursor == ":" )
	{
                // hh:mm:ss:mmm is a special case
		if ( isNumber( word ) ) {
			bool leave = false;
                        
                        while ( !leave ) {
				if ( *cursor == ":" ) {
		                        word += *cursor ;
					cursor++ ;
                                } else {
                                	leave = true;
                                }
                                
				if ( isNumber( *cursor ) ) {
		                        word += *cursor ;
					cursor++ ;
                                } else {
                                	leave = true;
                                }
                        }
			return id_TK ;
		} else {
			cursor ++ ;
			return def_TK ;
		}
	} else
		return id_TK ;
}
static bool bracketPairDefinesRegion( const BracketPair & bracketPair )
{
    Q_ASSERT(bracketPair.first.isValid());
    Q_ASSERT(bracketPair.second.isValid());

    if (!tokenMaybeRegionStart(bracketPair.first) || !tokenMaybeRegionEnd(bracketPair.second))
        return false;

    // check whether this is an Event
    TokenIterator it = bracketPair.first.next();
    if (it.isValid()) {
        if (it->type == Token::SymbolArg)
            return false;
        else {
            ++it;
            if (it.isValid() && it->character == ':')
                return false;
        }
    }

    return true;
}
void ScCodeEditor::gotoNextRegion()
{
    QTextCursor cursor = textCursor();
    int cursorPosition = cursor.position();

    BracketPair bracketPair;
    TokenIterator it = TokenIterator::rightOf( textDocument()->begin(), 0 );
    while (it.isValid()) {
        nextBracketPair(it, bracketPair);
        if ( bracketPair.first.isValid() && bracketPair.second.isValid()
             && bracketPair.first.position() > cursorPosition
             && bracketPairDefinesRegion(bracketPair))
        {
            setTextCursor( cursorAt(bracketPair.first) );
            return;
        }
        it = bracketPair.second;
    }

    cursor.movePosition(QTextCursor::End);
    setTextCursor(cursor);
}
Exemple #17
0
ParsingResult parseToken(Token token, TokenIterator& begin, TokenIterator& end, const TokenAction& action = TokenAction())
{
	if (begin >= end)
	{
		return make_pair(false, SemanticAction());
	}
	if (begin->name() != token.name())
	{
		return make_pair(false, SemanticAction());
	}
	const Token& theToken = *begin;
	++begin;
	if (action)
	{
		return make_pair(true, bind(action, theToken));
	}
	return make_pair(true, SemanticAction());
}
Exemple #18
0
List<Token> 
PreProcessor::replaceMacroParams(const List<Token> &mtokens, const List<List<Token>> &caller_params)
{
	//FIXME: nested macro
	//i.e. FUNC(x, FUNC(x,y))

	List<Token> replace = mtokens;
	TokenIterator it;
	it.setTokens(&replace);
	while (!it.eof()) {
		if (it.is(_PP_MACRO_PARAM)) {
			int index = it.val()->toInt();
			const List<Token> &param = caller_params.at(index);
			it.erase(1);
			it.insert(param);
		}
		it.next();
	}
	return replace;
}
QTextCursor ScCodeEditor::selectionForPosition( int position )
{
    QTextBlock block( textDocument()->findBlock(position) );
    if (!block.isValid())
        return QTextCursor();

    int positionInBlock = position - block.position();

    TokenIterator it = TokenIterator( block, positionInBlock );
    if (it.type() == Token::Unknown) {
        // Token is invalid, or Token::Unknown (i.e. punctuations).
        // Prefer token at previous position.
        TokenIterator alternativeIt = TokenIterator( block, positionInBlock - 1 );
        if (alternativeIt.isValid())
            it = alternativeIt;
    }

    if (it.isValid()) {
        switch (it->type) {
        case Token::OpeningBracket:
        case Token::ClosingBracket:
        {
            BracketPair match;
            matchBracket(it, match);
            if (match.first.isValid() && match.second.isValid()) {
                int start = match.first.position();
                int end = match.second.position() + 1;
                QTextCursor selection(textDocument());
                if (it == match.second) {
                    selection.setPosition(start);
                    selection.setPosition(end, QTextCursor::KeepAnchor);
                } else {
                    selection.setPosition(end);
                    selection.setPosition(start, QTextCursor::KeepAnchor);
                }
                return selection;
            }
            break;
        }

        default:
            QTextCursor selection( textDocument() );
            selection.setPosition( it.position() );
            selection.setPosition( selection.position() + it->length, QTextCursor::KeepAnchor );
            return selection;
        }
    }

    return QTextCursor();
}
// taking nested brackets into account
TokenIterator ScCodeEditor::previousOpeningBracket(TokenIterator it)
{
    int level = 0;
    while (it.isValid()) {
        switch (it->type) {
        case Token::OpeningBracket:
            if (level == 0)
                return it;
            --level;
            break;

        case Token::ClosingBracket:
            ++level;

        default:
            break;
        }
        --it;
    }
    return it;
}
void ScCodeEditor::keyPressEvent( QKeyEvent *e )
{
    hideMouseCursor(e);

    QTextCursor cursor( textCursor() );
    bool cursorMoved = true;

    if (e == QKeySequence::MoveToNextWord)
        moveToNextToken( cursor, QTextCursor::MoveAnchor );
    else if (e == QKeySequence::MoveToPreviousWord)
        moveToPreviousToken( cursor, QTextCursor::MoveAnchor );
    else if (e == QKeySequence::SelectNextWord)
        moveToNextToken( cursor, QTextCursor::KeepAnchor );
    else if (e == QKeySequence::SelectPreviousWord)
        moveToPreviousToken( cursor, QTextCursor::KeepAnchor );
    else
        cursorMoved = false;

    if (cursorMoved) {
        setTextCursor( cursor );
        return;
    }

    switch (e->key()) {
    case Qt::Key_Home:
    {
        Qt::KeyboardModifiers mods(e->modifiers());
        if (mods && mods != Qt::ShiftModifier) {
            GenericCodeEditor::keyPressEvent(e);
            return;
        }

        QTextCursor::MoveMode mode =
            mods & Qt::ShiftModifier ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;

        QTextCursor c(textCursor());
        QTextBlock b(c.block());

        int pos = indentedStartOfLine(b);
        pos += b.position();

        if (c.position() == pos)
            c.movePosition(QTextCursor::StartOfLine, mode);
        else
            c.setPosition(pos, mode);

        setTextCursor(c);

        return;
    }

    case Qt::Key_Backtab:
    {
        QTextCursor cursor = textCursor();
        insertSpaceToNextTabStop( cursor );
        ensureCursorVisible();
        return;
    }
    case Qt::Key_Backspace:
        if (mInsertMatchingTokens && !overwriteMode() && e->modifiers() == 0)
            if (removeMatchingTokens())
                break;
        GenericCodeEditor::keyPressEvent(e);
        break;
    case Qt::Key_Enter:
    case Qt::Key_Return:
    {
        QTextBlock cursorBlock = cursor.block();
        int cursorPosInBlock = cursor.position() - cursorBlock.position();
        TokenIterator nextToken = TokenIterator::rightOf(cursorBlock, cursorPosInBlock);
        if ( nextToken.block() == cursorBlock && nextToken.type() == Token::ClosingBracket )
        {
            cursor.beginEditBlock();
            cursor.insertBlock();
            cursor.insertBlock();
            cursor.endEditBlock();
            cursor.movePosition( QTextCursor::PreviousBlock, QTextCursor::KeepAnchor );
            indent(cursor, JoinEditBlock);
            cursor.movePosition( QTextCursor::EndOfBlock );
        }
        else {
            cursor.beginEditBlock();
            cursor.insertBlock();
            cursor.endEditBlock();
            indent(cursor, JoinEditBlock);
        }
        cursor.setVerticalMovementX(-1);
        setTextCursor(cursor);
        break;
    }
    default:
        if (!overwriteMode() && insertMatchingTokens(e->text()))
            break;
        GenericCodeEditor::keyPressEvent(e);
    }

    mAutoCompleter->keyPress(e);
}
inline static bool tokenMaybeRegionStart( const TokenIterator & it )
{
    Q_ASSERT(it.isValid());
    return ( it->character == '(' && it->positionInBlock == 0 );
}