]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexPB.cxx
775b5587257d750d34c214e05f6e1332b6b8f0d1
1 // Scintilla source code edit control
3 // Lexer for PowerBasic by Roland Walter, roland@rowalt.de (for PowerBasic see www.powerbasic.com)
6 // 17.10.2003 Toggling of subs/functions now until next sub/function - this gives better results
7 // 29.10.2003 1. Bug: Toggling didn't work for subs/functions added in editor
8 // 2. Own colors for PB constants and Inline Assembler SCE_B_CONSTANT and SCE_B_ASM
9 // 3. Several smaller syntax coloring improvements and speed optimizations
11 // Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
12 // The License.txt file describes the conditions under which this software may be distributed.
24 #include "StyleContext.h"
26 #include "Scintilla.h"
29 static inline bool IsTypeCharacter(const int ch
)
31 return ch
== '%' || ch
== '&' || ch
== '@' || ch
== '!' || ch
== '#' || ch
== '$' || ch
== '?';
34 static inline bool IsAWordChar(const int ch
)
36 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' || ch
== '_');
39 static inline bool IsAWordStart(const int ch
)
41 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
44 bool MatchUpperCase(Accessor
&styler
, int pos
, const char *s
) //Same as styler.Match() but uppercase comparison (a-z,A-Z and space only)
47 for (int i
=0; *s
; i
++)
49 ch
=styler
.SafeGetCharAt(pos
+i
);
50 if (ch
> 0x60) ch
-= '\x20';
51 if (*s
!= ch
) return false;
57 static void ColourisePBDoc(unsigned int startPos
, int length
, int initStyle
,WordList
*keywordlists
[],Accessor
&styler
) {
59 WordList
&keywords
= *keywordlists
[0];
61 styler
.StartAt(startPos
);
63 StyleContext
sc(startPos
, length
, initStyle
, styler
);
65 for (; sc
.More(); sc
.Forward()) {
70 sc
.SetState(SCE_B_DEFAULT
);
75 if (!IsAWordChar(sc
.ch
))
77 if (!IsTypeCharacter(sc
.ch
))
80 sc
.GetCurrentLowered(s
, sizeof(s
));
81 if (keywords
.InList(s
))
83 if (strcmp(s
, "rem") == 0)
85 sc
.ChangeState(SCE_B_COMMENT
);
86 if (sc
.atLineEnd
) {sc
.SetState(SCE_B_DEFAULT
);}
88 else if (strcmp(s
, "asm") == 0)
90 sc
.ChangeState(SCE_B_ASM
);
91 if (sc
.atLineEnd
) {sc
.SetState(SCE_B_DEFAULT
);}
95 sc
.SetState(SCE_B_DEFAULT
);
100 sc
.ChangeState(SCE_B_IDENTIFIER
);
101 sc
.SetState(SCE_B_DEFAULT
);
109 if (!IsAWordChar(sc
.ch
)) {sc
.SetState(SCE_B_DEFAULT
);}
114 if (sc
.ch
== '\"'){sc
.ForwardSetState(SCE_B_DEFAULT
);}
119 if (!IsAWordChar(sc
.ch
)) {sc
.SetState(SCE_B_DEFAULT
);}
124 if (sc
.atLineEnd
) {sc
.SetState(SCE_B_DEFAULT
);}
129 if (sc
.atLineEnd
) {sc
.SetState(SCE_B_DEFAULT
);}
132 } //switch (sc.state)
134 // Determine if a new state should be entered:
135 if (sc
.state
== SCE_B_DEFAULT
)
137 if (sc
.ch
== '\'') {sc
.SetState(SCE_B_COMMENT
);}
138 else if (sc
.ch
== '\"') {sc
.SetState(SCE_B_STRING
);}
139 else if (sc
.ch
== '&' && tolower(sc
.chNext
) == 'h') {sc
.SetState(SCE_B_NUMBER
);}
140 else if (sc
.ch
== '&' && tolower(sc
.chNext
) == 'b') {sc
.SetState(SCE_B_NUMBER
);}
141 else if (sc
.ch
== '&' && tolower(sc
.chNext
) == 'o') {sc
.SetState(SCE_B_NUMBER
);}
142 else if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {sc
.SetState(SCE_B_NUMBER
);}
143 else if (IsAWordStart(sc
.ch
)) {sc
.SetState(SCE_B_KEYWORD
);}
144 else if (sc
.ch
== '%') {sc
.SetState(SCE_B_CONSTANT
);}
145 else if (sc
.ch
== '$') {sc
.SetState(SCE_B_CONSTANT
);}
146 else if (sc
.ch
== '#') {sc
.SetState(SCE_B_KEYWORD
);}
147 else if (sc
.ch
== '!') {sc
.SetState(SCE_B_ASM
);}
148 else if (isoperator(static_cast<char>(sc
.ch
)) || (sc
.ch
== '\\')) {sc
.SetState(SCE_B_OPERATOR
);}
150 } //for (; sc.More(); sc.Forward())
154 //The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted,
155 //nothing more. I had worked with this kind of toggling for several years when I used the great good old
156 //GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops
157 //and so on too I found this is more disturbing then helping (for me). So if You think in another way
158 //you can (or must) write Your own toggling routine ;-)
159 static void FoldPBDoc(unsigned int startPos
, int length
, int, WordList
*[], Accessor
&styler
)
161 // No folding enabled, no reason to continue...
162 if( styler
.GetPropertyInt("fold") == 0 )
165 unsigned int endPos
= startPos
+ length
;
166 int lineCurrent
= styler
.GetLine(startPos
);
167 int levelCurrent
= SC_FOLDLEVELBASE
;
169 levelCurrent
= styler
.LevelAt(lineCurrent
-1) >> 16;
170 int levelNext
= levelCurrent
;
171 char chNext
= styler
[startPos
];
174 for (unsigned int i
= startPos
; i
< endPos
; i
++)
177 chNext
= styler
.SafeGetCharAt(i
+ 1);
179 if (fNewLine
) //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only)
185 case ' ': //Most lines start with space - so check this first
187 int levelUse
= levelCurrent
;
188 int lev
= levelUse
| levelNext
<< 16;
189 styler
.SetLevel(lineCurrent
, lev
);
199 if( MatchUpperCase(styler
,i
,"FUNCTION") )
201 styler
.SetLevel(lineCurrent
, (SC_FOLDLEVELBASE
<< 16) | SC_FOLDLEVELHEADERFLAG
);
202 levelNext
=SC_FOLDLEVELBASE
+1;
204 else if( MatchUpperCase(styler
,i
,"SUB") )
206 styler
.SetLevel(lineCurrent
, (SC_FOLDLEVELBASE
<< 16) | SC_FOLDLEVELHEADERFLAG
);
207 levelNext
=SC_FOLDLEVELBASE
+1;
209 else if( MatchUpperCase(styler
,i
,"CALLBACK FUNCTION") )
211 styler
.SetLevel(lineCurrent
, (SC_FOLDLEVELBASE
<< 16) | SC_FOLDLEVELHEADERFLAG
);
212 levelNext
=SC_FOLDLEVELBASE
+1;
214 else if( MatchUpperCase(styler
,i
,"STATIC FUNCTION") )
216 styler
.SetLevel(lineCurrent
, (SC_FOLDLEVELBASE
<< 16) | SC_FOLDLEVELHEADERFLAG
);
217 levelNext
=SC_FOLDLEVELBASE
+1;
219 else if( MatchUpperCase(styler
,i
,"STATIC SUB") )
221 styler
.SetLevel(lineCurrent
, (SC_FOLDLEVELBASE
<< 16) | SC_FOLDLEVELHEADERFLAG
);
222 levelNext
=SC_FOLDLEVELBASE
+1;
228 int levelUse
= levelCurrent
;
229 int lev
= levelUse
| levelNext
<< 16;
230 styler
.SetLevel(lineCurrent
, lev
);
241 levelCurrent
= levelNext
;
250 levelCurrent
= levelNext
;
256 } //for (unsigned int i = startPos; i < endPos; i++)
259 static const char * const pbWordListDesc
[] = {
264 LexerModule
lmPB(SCLEX_POWERBASIC
, ColourisePBDoc
, "powerbasic", FoldPBDoc
, pbWordListDesc
);