mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-10-31 11:34:05 +01:00 
			
		
		
		
	git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@742 f5eea248-9336-0410-98b8-ebc06183d4e3
		
			
				
	
	
		
			744 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			744 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //	-*- coding: utf-8 -*-
 | |
| //	Scintilla source code edit control
 | |
| /**
 | |
|  *	@file LexModula.cxx
 | |
|  *	@author Dariusz "DKnoto" Knociński
 | |
|  *	@date 2011/02/03
 | |
|  *	@brief Lexer for Modula-2/3 documents.
 | |
|  */
 | |
| //	The License.txt file describes the conditions under which this software may
 | |
| //	be distributed.
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdarg.h>
 | |
| #include <assert.h>
 | |
| #include <ctype.h>
 | |
| 
 | |
| #include "ILexer.h"
 | |
| #include "Scintilla.h"
 | |
| #include "SciLexer.h"
 | |
| 
 | |
| #include "PropSetSimple.h"
 | |
| #include "WordList.h"
 | |
| #include "LexAccessor.h"
 | |
| #include "Accessor.h"
 | |
| #include "StyleContext.h"
 | |
| #include "CharacterSet.h"
 | |
| #include "LexerModule.h"
 | |
| 
 | |
| #ifdef SCI_NAMESPACE
 | |
| using namespace Scintilla;
 | |
| #endif
 | |
| 
 | |
| #ifdef DEBUG_LEX_MODULA
 | |
| #define DEBUG_STATE( p, c )\
 | |
| 		fprintf( stderr, "Unknown state: currentPos = %d, char = '%c'\n", p, c );
 | |
| #else
 | |
| #define DEBUG_STATE( p, c )
 | |
| #endif
 | |
| 
 | |
| static inline bool IsDigitOfBase( unsigned ch, unsigned base ) {
 | |
| 	if( ch < '0' || ch > 'f' ) return false;
 | |
| 	if( base <= 10 ) {
 | |
| 		if( ch >= ( '0' + base ) ) return false;
 | |
| 	} else {
 | |
| 		if( ch > '9' ) {
 | |
| 			unsigned nb = base - 10;
 | |
| 			if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {
 | |
| 				if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
 | |
| 	int i;
 | |
| 	char s[3];
 | |
| 
 | |
| 	s[0] = sc.ch;
 | |
| 	s[1] = sc.chNext;
 | |
| 	s[2] = 0;
 | |
| 	for( i = 0; i < op.len; i++ ) {
 | |
| 		if( ( strlen( op.words[i] ) == 2 ) &&
 | |
| 			( s[0] == op.words[i][0] && s[1] == op.words[i][1] ) ) {
 | |
| 			return 2;
 | |
| 		}
 | |
| 	}
 | |
| 	s[1] = 0;
 | |
| 	for( i = 0; i < op.len; i++ ) {
 | |
| 		if( ( strlen( op.words[i] ) == 1 ) &&
 | |
| 			( s[0] == op.words[i][0] ) ) {
 | |
| 			return 1;
 | |
| 		}
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static inline bool IsEOL( Accessor &styler, unsigned curPos ) {
 | |
| 	unsigned ch = styler.SafeGetCharAt( curPos );
 | |
| 	if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
 | |
| 		( ch == '\n' ) ) {
 | |
| 		return true;
 | |
| 	}
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| static inline bool checkStatement(
 | |
| 	Accessor &styler,
 | |
| 	int &curPos,
 | |
| 	const char *stt, bool spaceAfter = true ) {
 | |
| 	int len = strlen( stt );
 | |
| 	int i;
 | |
| 	for( i = 0; i < len; i++ ) {
 | |
| 		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 	if( spaceAfter ) {
 | |
| 		if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 	curPos += ( len - 1 );
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| static inline bool checkEndSemicolon(
 | |
| 	Accessor &styler,
 | |
| 	int &curPos, int endPos )
 | |
| {
 | |
| 	const char *stt = "END";
 | |
| 	int len = strlen( stt );
 | |
| 	int i;
 | |
| 	for( i = 0; i < len; i++ ) {
 | |
| 		if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 	while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
 | |
| 		i++;
 | |
| 		if( ( curPos + i ) >= endPos ) return false;
 | |
| 	}
 | |
| 	if( styler.SafeGetCharAt( curPos + i ) != ';' ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 	curPos += ( i - 1 );
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| static inline bool checkKeyIdentOper(
 | |
| 
 | |
| 	Accessor &styler,
 | |
| 	int &curPos, int endPos,
 | |
| 	const char *stt, const char etk ) {
 | |
| 	int newPos = curPos;
 | |
| 	if( ! checkStatement( styler, newPos, stt ) )
 | |
| 		return false;
 | |
| 	newPos++;
 | |
| 	if( newPos >= endPos )
 | |
| 		return false;
 | |
| 	if( ! isspace( styler.SafeGetCharAt( newPos ) ) )
 | |
| 		return false;
 | |
| 	newPos++;
 | |
| 	if( newPos >= endPos )
 | |
| 		return false;
 | |
| 	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
 | |
| 		newPos++;
 | |
| 		if( newPos >= endPos )
 | |
| 			return false;
 | |
| 	}
 | |
| 	if( ! isalpha( styler.SafeGetCharAt( newPos ) ) )
 | |
| 		return false;
 | |
| 	newPos++;
 | |
| 	if( newPos >= endPos )
 | |
| 		return false;
 | |
| 	char ch;
 | |
| 	ch = styler.SafeGetCharAt( newPos );
 | |
| 	while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {
 | |
| 		newPos++;
 | |
| 		if( newPos >= endPos ) return false;
 | |
| 		ch = styler.SafeGetCharAt( newPos );
 | |
| 	}
 | |
| 	while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
 | |
| 		newPos++;
 | |
| 		if( newPos >= endPos ) return false;
 | |
| 	}
 | |
| 	if( styler.SafeGetCharAt( newPos ) != etk )
 | |
| 		return false;
 | |
| 	curPos = newPos;
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| static void FoldModulaDoc( unsigned int startPos,
 | |
| 						 int length,
 | |
| 						 int , WordList *[],
 | |
| 						 Accessor &styler)
 | |
| {
 | |
| 	int curLine = styler.GetLine(startPos);
 | |
| 	int curLevel = SC_FOLDLEVELBASE;
 | |
| 	int endPos = startPos + length;
 | |
| 	if( curLine > 0 )
 | |
| 		curLevel = styler.LevelAt( curLine - 1 ) >> 16;
 | |
| 	int curPos = startPos;
 | |
| 	int style = styler.StyleAt( curPos );
 | |
| 	int visChars = 0;
 | |
| 	int nextLevel = curLevel;
 | |
| 
 | |
| 	while( curPos < endPos ) {
 | |
| 		if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;
 | |
| 
 | |
| 		switch( style ) {
 | |
| 		case SCE_MODULA_COMMENT:
 | |
| 			if( checkStatement( styler, curPos, "(*" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "*)" ) )
 | |
| 				nextLevel--;
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_DOXYCOMM:
 | |
| 			if( checkStatement( styler, curPos, "(**", false ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "*)" ) )
 | |
| 				nextLevel--;
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_KEYWORD:
 | |
| 			if( checkStatement( styler, curPos, "IF" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "BEGIN" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "TRY" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "LOOP" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "FOR" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "WHILE" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "REPEAT" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "UNTIL" ) )
 | |
| 				nextLevel--;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "WITH" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "CASE" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "TYPECASE" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkStatement( styler, curPos, "LOCK" ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) )
 | |
| 				nextLevel++;
 | |
| 			else
 | |
| 			if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) {
 | |
| 				int cln = curLine;
 | |
| 				int clv_old = curLevel;
 | |
| 				int pos;
 | |
| 				char ch;
 | |
| 				int clv_new;
 | |
| 				while( cln > 0 ) {
 | |
| 					clv_new = styler.LevelAt( cln - 1 ) >> 16;
 | |
| 					if( clv_new < clv_old ) {
 | |
| 						nextLevel--;
 | |
| 						pos = styler.LineStart( cln );
 | |
| 						while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) {
 | |
| 							if( ch == 'P' ) {
 | |
| 								if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD )	{
 | |
| 									if( checkKeyIdentOper( styler, pos, endPos,
 | |
| 														"PROCEDURE", '(' ) ) {
 | |
| 										break;
 | |
| 									}
 | |
| 								}
 | |
| 							}
 | |
| 							pos++;
 | |
| 						}
 | |
| 						clv_old = clv_new;
 | |
| 					}
 | |
| 					cln--;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) )
 | |
| 				nextLevel--;
 | |
| 			else
 | |
| 			if( checkEndSemicolon( styler, curPos, endPos ) )
 | |
| 				nextLevel--;
 | |
| 			else {
 | |
| 				while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )
 | |
| 					curPos++;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		default:
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {
 | |
| 			int efectiveLevel = curLevel | nextLevel << 16;
 | |
| 			if( visChars == 0 )
 | |
| 				efectiveLevel |= SC_FOLDLEVELWHITEFLAG;
 | |
| 			if( curLevel < nextLevel )
 | |
| 				efectiveLevel |= SC_FOLDLEVELHEADERFLAG;
 | |
| 			if( efectiveLevel != styler.LevelAt(curLine) ) {
 | |
| 				styler.SetLevel(curLine, efectiveLevel );
 | |
| 			}
 | |
| 			curLine++;
 | |
| 			curLevel = nextLevel;
 | |
| 			if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {
 | |
| 				styler.SetLevel( curLine, ( curLevel | curLevel << 16)
 | |
| 								| SC_FOLDLEVELWHITEFLAG);
 | |
| 			}
 | |
| 			visChars = 0;
 | |
| 		}
 | |
| 		curPos++;
 | |
| 		style = styler.StyleAt( curPos );
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static inline bool skipWhiteSpaces( StyleContext & sc ) {
 | |
| 	while( isspace( sc.ch ) ) {
 | |
| 		sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 		if( sc.More() )
 | |
| 			sc.Forward();
 | |
| 		else
 | |
| 			return false;
 | |
| 	}
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| static void ColouriseModulaDoc(	unsigned int startPos,
 | |
| 									int length,
 | |
| 									int initStyle,
 | |
| 									WordList *wl[],
 | |
| 									Accessor &styler ) {
 | |
| 	WordList& keyWords		= *wl[0];
 | |
| 	WordList& reservedWords	= *wl[1];
 | |
| 	WordList& operators 	= *wl[2];
 | |
| 	WordList& pragmaWords 	= *wl[3];
 | |
| 	WordList& escapeCodes	= *wl[4];
 | |
| 	WordList& doxyKeys		= *wl[5];
 | |
| 
 | |
| 	const int BUFLEN = 128;
 | |
| 
 | |
| 	char	buf[BUFLEN];
 | |
| 	int		i, kl;
 | |
| 
 | |
| 	int  charPos = 0;
 | |
| 
 | |
| 	StyleContext sc( startPos, length, initStyle, styler );
 | |
| 
 | |
| 	while( sc.More() ) 	{
 | |
| 		switch( sc.state )	{
 | |
| 		case SCE_MODULA_DEFAULT:
 | |
| 			if( ! skipWhiteSpaces( sc ) ) break;
 | |
| 
 | |
| 			if( sc.ch == '(' && sc.chNext == '*' ) {
 | |
| 				if( sc.GetRelative(2) == '*' ) {
 | |
| 					sc.SetState( SCE_MODULA_DOXYCOMM );
 | |
| 					sc.Forward();
 | |
| 				} else {
 | |
| 					sc.SetState( SCE_MODULA_COMMENT );
 | |
| 				}
 | |
| 				sc.Forward();
 | |
| 			}
 | |
| 			else
 | |
| 			if( isalpha( sc.ch ) ) {
 | |
| 				if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
 | |
| 					for( i = 0; i < BUFLEN - 1; i++ ) {
 | |
| 						buf[i] = sc.GetRelative(i);
 | |
| 						if( !isalpha( buf[i] ) && !(buf[i] == '_') )
 | |
| 							break;
 | |
| 					}
 | |
| 					kl = i;
 | |
| 					buf[kl] = 0;
 | |
| 
 | |
| 					if( keyWords.InList( buf ) ) {
 | |
| 						sc.SetState( SCE_MODULA_KEYWORD );
 | |
| 						sc.Forward( kl );
 | |
| 						sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 						continue;
 | |
| 					}
 | |
| 					else
 | |
| 					if( reservedWords.InList( buf ) ) {
 | |
| 						sc.SetState( SCE_MODULA_RESERVED );
 | |
| 						sc.Forward( kl );
 | |
| 						sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 						continue;
 | |
| 					} else {
 | |
| 						/** check procedure identifier */
 | |
| 					}
 | |
| 				} else {
 | |
| 					for( i = 0; i < BUFLEN - 1; i++ ) {
 | |
| 						buf[i] = sc.GetRelative(i);
 | |
| 						if( !isalpha( buf[i] ) &&
 | |
| 							!isdigit( buf[i] ) &&
 | |
| 							!(buf[i] == '_') )
 | |
| 							break;
 | |
| 					}
 | |
| 					kl = i;
 | |
| 					buf[kl] = 0;
 | |
| 
 | |
| 					sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 					sc.Forward( kl );
 | |
| 					continue;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			if( isdigit( sc.ch ) ) {
 | |
| 				sc.SetState( SCE_MODULA_NUMBER );
 | |
| 				continue;
 | |
| 			}
 | |
| 			else
 | |
| 			if( sc.ch == '\"' ) {
 | |
| 				sc.SetState( SCE_MODULA_STRING );
 | |
| 			}
 | |
| 			else
 | |
| 			if( sc.ch == '\'' ) {
 | |
| 				charPos = sc.currentPos;
 | |
| 				sc.SetState( SCE_MODULA_CHAR );
 | |
| 			}
 | |
| 			else
 | |
| 			if( sc.ch == '<' && sc.chNext == '*' ) {
 | |
| 				sc.SetState( SCE_MODULA_PRAGMA );
 | |
| 				sc.Forward();
 | |
| 			} else {
 | |
| 				unsigned len = IsOperator( sc, operators );
 | |
| 				if( len > 0 ) {
 | |
| 					sc.SetState( SCE_MODULA_OPERATOR );
 | |
| 					sc.Forward( len );
 | |
| 					sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 					continue;
 | |
| 				} else {
 | |
| 					DEBUG_STATE( sc.currentPos, sc.ch );
 | |
| 				}
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_COMMENT:
 | |
| 			if( sc.ch == '*' && sc.chNext == ')' ) {
 | |
| 				sc.Forward( 2 );
 | |
| 				sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_DOXYCOMM:
 | |
| 			switch( sc.ch ) {
 | |
| 			case '*':
 | |
| 				if( sc.chNext == ')' ) {
 | |
| 					sc.Forward( 2 );
 | |
| 					sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 					continue;
 | |
| 				}
 | |
| 				break;
 | |
| 
 | |
| 			case '@':
 | |
| 				if( islower( sc.chNext ) ) {
 | |
| 					for( i = 0; i < BUFLEN - 1; i++ ) {
 | |
| 						buf[i] = sc.GetRelative(i+1);
 | |
| 						if( isspace( buf[i] ) ) break;
 | |
| 					}
 | |
| 					buf[i] = 0;
 | |
| 					kl = i;
 | |
| 
 | |
| 					if( doxyKeys.InList( buf ) ) {
 | |
| 						sc.SetState( SCE_MODULA_DOXYKEY );
 | |
| 						sc.Forward( kl + 1 );
 | |
| 						sc.SetState( SCE_MODULA_DOXYCOMM );
 | |
| 					}
 | |
| 				}
 | |
| 				break;
 | |
| 
 | |
| 			default:
 | |
| 				break;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_NUMBER:
 | |
| 			{
 | |
| 				buf[0] = sc.ch;
 | |
| 				for( i = 1; i < BUFLEN - 1; i++ ) {
 | |
| 					buf[i] = sc.GetRelative(i);
 | |
| 					if( ! isdigit( buf[i] ) )
 | |
| 						break;
 | |
| 				}
 | |
| 				kl = i;
 | |
| 				buf[kl] = 0;
 | |
| 
 | |
| 				switch( sc.GetRelative(kl) ) {
 | |
| 				case '_':
 | |
| 					{
 | |
| 						int base = atoi( buf );
 | |
| 						if( base < 2 || base > 16 ) {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						} else {
 | |
| 							int imax;
 | |
| 
 | |
| 							kl++;
 | |
| 							for( i = 0; i < BUFLEN - 1; i++ ) {
 | |
| 								buf[i] = sc.GetRelative(kl+i);
 | |
| 								if( ! IsDigitOfBase( buf[i], 16 ) ) {
 | |
| 									break;
 | |
| 								}
 | |
| 							}
 | |
| 							imax = i;
 | |
| 							for( i = 0; i < imax; i++ ) {
 | |
| 								if( ! IsDigitOfBase( buf[i], base ) ) {
 | |
| 									sc.SetState( SCE_MODULA_BADSTR );
 | |
| 									break;
 | |
| 								}
 | |
| 							}
 | |
| 							kl += imax;
 | |
| 						}
 | |
| 						sc.SetState( SCE_MODULA_BASENUM );
 | |
| 						for( i = 0; i < kl; i++ ) {
 | |
| 							sc.Forward();
 | |
| 						}
 | |
| 						sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 						continue;
 | |
| 					}
 | |
| 					break;
 | |
| 
 | |
| 				case '.':
 | |
| 					if( sc.GetRelative(kl+1) == '.' ) {
 | |
| 						kl--;
 | |
| 						for( i = 0; i < kl; i++ ) {
 | |
| 							sc.Forward();
 | |
| 						}
 | |
| 						sc.Forward();
 | |
| 						sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 						continue;
 | |
| 					} else {
 | |
| 						bool doNext = false;
 | |
| 
 | |
| 						kl++;
 | |
| 
 | |
| 						buf[0] = sc.GetRelative(kl);
 | |
| 						if( isdigit( buf[0] ) ) {
 | |
| 							for( i = 0;; i++ ) {
 | |
| 								if( !isdigit(sc.GetRelative(kl+i)) )
 | |
| 									break;
 | |
| 							}
 | |
| 							kl += i;
 | |
| 							buf[0] = sc.GetRelative(kl);
 | |
| 
 | |
| 							switch( buf[0] )
 | |
| 							{
 | |
| 							case 'E':
 | |
| 							case 'e':
 | |
| 							case 'D':
 | |
| 							case 'd':
 | |
| 							case 'X':
 | |
| 							case 'x':
 | |
| 								kl++;
 | |
| 								buf[0] = sc.GetRelative(kl);
 | |
| 								if( buf[0] == '-' || buf[0] == '+' ) {
 | |
| 									kl++;
 | |
| 								}
 | |
| 								buf[0] = sc.GetRelative(kl);
 | |
| 								if( isdigit( buf[0] ) ) {
 | |
| 									for( i = 0;; i++ ) {
 | |
| 										if( !isdigit(sc.GetRelative(kl+i)) ) {
 | |
| 											buf[0] = sc.GetRelative(kl+i);
 | |
| 											break;
 | |
| 										}
 | |
| 									}
 | |
| 									kl += i;
 | |
| 									doNext = true;
 | |
| 								} else {
 | |
| 									sc.SetState( SCE_MODULA_BADSTR );
 | |
| 								}
 | |
| 								break;
 | |
| 
 | |
| 							default:
 | |
| 								doNext = true;
 | |
| 								break;
 | |
| 							}
 | |
| 						} else {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						}
 | |
| 
 | |
| 						if( doNext ) {
 | |
| 							if( ! isspace( buf[0] ) &&
 | |
| 								buf[0] != ')' &&
 | |
| 								buf[0] != '>' &&
 | |
| 								buf[0] != '<' &&
 | |
| 								buf[0] != '=' &&
 | |
| 								buf[0] != '#' &&
 | |
| 								buf[0] != '+' &&
 | |
| 								buf[0] != '-' &&
 | |
| 								buf[0] != '*' &&
 | |
| 								buf[0] != '/' &&
 | |
| 								buf[0] != ',' &&
 | |
| 								buf[0] != ';'
 | |
| 								) {
 | |
| 								sc.SetState( SCE_MODULA_BADSTR );
 | |
| 							} else {
 | |
| 								kl--;
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 					sc.SetState( SCE_MODULA_FLOAT );
 | |
| 					for( i = 0; i < kl; i++ ) {
 | |
| 						sc.Forward();
 | |
| 					}
 | |
| 					sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 					continue;
 | |
| 					break;
 | |
| 
 | |
| 				default:
 | |
| 					for( i = 0; i < kl; i++ ) {
 | |
| 						sc.Forward();
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_STRING:
 | |
| 			if( sc.ch == '\"' ) {
 | |
| 				sc.Forward();
 | |
| 				sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 				continue;
 | |
| 			} else {
 | |
| 				if( sc.ch == '\\' ) {
 | |
| 					i = 1;
 | |
| 					if( IsDigitOfBase( sc.chNext, 8 ) ) {
 | |
| 						for( i = 1; i < BUFLEN - 1; i++ ) {
 | |
| 							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
 | |
| 								break;
 | |
| 						}
 | |
| 						if( i == 3 ) {
 | |
| 							sc.SetState( SCE_MODULA_STRSPEC );
 | |
| 						} else {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						}
 | |
| 					} else {
 | |
| 						buf[0] = sc.chNext;
 | |
| 						buf[1] = 0;
 | |
| 
 | |
| 						if( escapeCodes.InList( buf ) ) {
 | |
| 							sc.SetState( SCE_MODULA_STRSPEC );
 | |
| 						} else {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						}
 | |
| 					}
 | |
| 					sc.Forward(i+1);
 | |
| 					sc.SetState( SCE_MODULA_STRING );
 | |
| 					continue;
 | |
| 				}
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_CHAR:
 | |
| 			if( sc.ch == '\'' ) {
 | |
| 				sc.Forward();
 | |
| 				sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 				continue;
 | |
| 			}
 | |
| 			else
 | |
| 			if( ( sc.currentPos - charPos ) == 1 ) {
 | |
| 				if( sc.ch == '\\' ) {
 | |
| 					i = 1;
 | |
| 					if( IsDigitOfBase( sc.chNext, 8 ) ) {
 | |
| 						for( i = 1; i < BUFLEN - 1; i++ ) {
 | |
| 							if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
 | |
| 								break;
 | |
| 						}
 | |
| 						if( i == 3 ) {
 | |
| 							sc.SetState( SCE_MODULA_CHARSPEC );
 | |
| 						} else {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						}
 | |
| 					} else {
 | |
| 						buf[0] = sc.chNext;
 | |
| 						buf[1] = 0;
 | |
| 
 | |
| 						if( escapeCodes.InList( buf ) ) {
 | |
| 							sc.SetState( SCE_MODULA_CHARSPEC );
 | |
| 						} else {
 | |
| 							sc.SetState( SCE_MODULA_BADSTR );
 | |
| 						}
 | |
| 					}
 | |
| 					sc.Forward(i+1);
 | |
| 					sc.SetState( SCE_MODULA_CHAR );
 | |
| 					continue;
 | |
| 				}
 | |
| 			} else {
 | |
| 				sc.SetState( SCE_MODULA_BADSTR );
 | |
| 				sc.Forward();
 | |
| 				sc.SetState( SCE_MODULA_CHAR );
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		case SCE_MODULA_PRAGMA:
 | |
| 			if( sc.ch == '*' && sc.chNext == '>' ) {
 | |
| 				sc.Forward();
 | |
| 				sc.Forward();
 | |
| 				sc.SetState( SCE_MODULA_DEFAULT );
 | |
| 				continue;
 | |
| 			}
 | |
| 			else
 | |
| 			if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
 | |
| 				buf[0] = sc.ch;
 | |
| 				buf[1] = sc.chNext;
 | |
| 				for( i = 2; i < BUFLEN - 1; i++ ) {
 | |
| 					buf[i] = sc.GetRelative(i);
 | |
| 					if( !isupper( buf[i] ) )
 | |
| 						break;
 | |
| 				}
 | |
| 				kl = i;
 | |
| 				buf[kl] = 0;
 | |
| 				if( pragmaWords.InList( buf ) ) {
 | |
| 					sc.SetState( SCE_MODULA_PRGKEY );
 | |
| 					sc.Forward( kl );
 | |
| 					sc.SetState( SCE_MODULA_PRAGMA );
 | |
| 					continue;
 | |
| 				}
 | |
| 			}
 | |
| 			break;
 | |
| 
 | |
| 		default:
 | |
| 			break;
 | |
| 		}
 | |
| 		sc.Forward();
 | |
| 	}
 | |
| 	sc.Complete();
 | |
| }
 | |
| 
 | |
| static const char *const modulaWordListDesc[] =
 | |
| {
 | |
| 	"Keywords",
 | |
| 	"ReservedKeywords",
 | |
| 	"Operators",
 | |
| 	"PragmaKeyswords",
 | |
| 	"EscapeCodes",
 | |
| 	"DoxygeneKeywords",
 | |
| 	0
 | |
| };
 | |
| 
 | |
| LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc,
 | |
| 					  modulaWordListDesc);
 |