]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexEScript.cxx
49411588aa50b8eb423d2148cd3e854456a67f10
   1 // Scintilla source code edit control 
   2 /** @file LexESCRIPT.cxx 
   5 // Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com) 
  17 #include "StyleContext.h" 
  19 #include "Scintilla.h" 
  24 static inline bool IsAWordChar(const int ch
) { 
  25         return (ch 
< 0x80) && (isalnum(ch
) || ch 
== '.' || ch 
== '_'); 
  28 static inline bool IsAWordStart(const int ch
) { 
  29         return (ch 
< 0x80) && (isalnum(ch
) || ch 
== '_'); 
  34 static void ColouriseESCRIPTDoc(unsigned int startPos
, int length
, int initStyle
, WordList 
*keywordlists
[], 
  37         WordList 
&keywords 
= *keywordlists
[0]; 
  38         WordList 
&keywords2 
= *keywordlists
[1]; 
  39         WordList 
&keywords3 
= *keywordlists
[2]; 
  41         // Do not leak onto next line 
  42         /*if (initStyle == SCE_ESCRIPT_STRINGEOL) 
  43                 initStyle = SCE_ESCRIPT_DEFAULT;*/ 
  45         StyleContext 
sc(startPos
, length
, initStyle
, styler
); 
  47         bool caseSensitive 
= styler
.GetPropertyInt("escript.case.sensitive", 0) != 0; 
  49         for (; sc
.More(); sc
.Forward()) { 
  51                 /*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) { 
  52                         // Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line 
  53                         sc.SetState(SCE_ESCRIPT_STRING); 
  56                 // Handle line continuation generically. 
  58                         if (sc
.chNext 
== '\n' || sc
.chNext 
== '\r') { 
  60                                 if (sc
.ch 
== '\r' && sc
.chNext 
== '\n') { 
  67                 // Determine if the current state should terminate. 
  68                 if (sc
.state 
== SCE_ESCRIPT_OPERATOR 
|| sc
.state 
== SCE_ESCRIPT_BRACE
) { 
  69                         sc
.SetState(SCE_ESCRIPT_DEFAULT
); 
  70                 } else if (sc
.state 
== SCE_ESCRIPT_NUMBER
) { 
  71                         if (!IsADigit(sc
.ch
) || sc
.ch 
!= '.') { 
  72                                 sc
.SetState(SCE_ESCRIPT_DEFAULT
); 
  74                 } else if (sc
.state 
== SCE_ESCRIPT_IDENTIFIER
) { 
  75                         if (!IsAWordChar(sc
.ch
) || (sc
.ch 
== '.')) { 
  78                                         sc
.GetCurrent(s
, sizeof(s
)); 
  80                                         sc
.GetCurrentLowered(s
, sizeof(s
)); 
  83 //                              sc.GetCurrentLowered(s, sizeof(s)); 
  85                                 if (keywords
.InList(s
)) { 
  86                                         sc
.ChangeState(SCE_ESCRIPT_WORD
); 
  87                                 } else if (keywords2
.InList(s
)) { 
  88                                         sc
.ChangeState(SCE_ESCRIPT_WORD2
); 
  89                                 } else if (keywords3
.InList(s
)) { 
  90                                         sc
.ChangeState(SCE_ESCRIPT_WORD3
); 
  91                                         // sc.state = SCE_ESCRIPT_IDENTIFIER; 
  93                                 sc
.SetState(SCE_ESCRIPT_DEFAULT
); 
  95                 } else if (sc
.state 
== SCE_ESCRIPT_COMMENT
) { 
  96                         if (sc
.Match('*', '/')) { 
  98                                 sc
.ForwardSetState(SCE_ESCRIPT_DEFAULT
); 
 100                 } else if (sc
.state 
== SCE_ESCRIPT_COMMENTDOC
) { 
 101                         if (sc
.Match('*', '/')) { 
 103                                 sc
.ForwardSetState(SCE_ESCRIPT_DEFAULT
); 
 105                 } else if (sc
.state 
== SCE_ESCRIPT_COMMENTLINE
) { 
 107                                 sc
.SetState(SCE_ESCRIPT_DEFAULT
); 
 109                 } else if (sc
.state 
== SCE_ESCRIPT_STRING
) { 
 111                                 if (sc
.chNext 
== '\"' || sc
.chNext 
== '\\') { 
 114                         } else if (sc
.ch 
== '\"') { 
 115                                 sc
.ForwardSetState(SCE_ESCRIPT_DEFAULT
); 
 119                 // Determine if a new state should be entered. 
 120                 if (sc
.state 
== SCE_ESCRIPT_DEFAULT
) { 
 121                         if (IsADigit(sc
.ch
) || (sc
.ch 
== '.' && IsADigit(sc
.chNext
))) { 
 122                                 sc
.SetState(SCE_ESCRIPT_NUMBER
); 
 123                         } else if (IsAWordStart(sc
.ch
) || (sc
.ch 
== '#')) { 
 124                                 sc
.SetState(SCE_ESCRIPT_IDENTIFIER
); 
 125                         } else if (sc
.Match('/', '*')) { 
 126                                 sc
.SetState(SCE_ESCRIPT_COMMENT
); 
 127                                 sc
.Forward();   // Eat the * so it isn't used for the end of the comment 
 128                         } else if (sc
.Match('/', '/')) { 
 129                                 sc
.SetState(SCE_ESCRIPT_COMMENTLINE
); 
 130                         } else if (sc
.ch 
== '\"') { 
 131                                 sc
.SetState(SCE_ESCRIPT_STRING
); 
 132                                 //} else if (isoperator(static_cast<char>(sc.ch))) { 
 133                         } else if (sc
.ch 
== '+' || sc
.ch 
== '-' || sc
.ch 
== '*' || sc
.ch 
== '/' || sc
.ch 
== '=' || sc
.ch 
== '<' || sc
.ch 
== '>' || sc
.ch 
== '&' || sc
.ch 
== '|' || sc
.ch 
== '!' || sc
.ch 
== '?' || sc
.ch 
== ':') { 
 134                                 sc
.SetState(SCE_ESCRIPT_OPERATOR
); 
 135                         } else if (sc
.ch 
== '{' || sc
.ch 
== '}') { 
 136                                 sc
.SetState(SCE_ESCRIPT_BRACE
); 
 145 static int classifyFoldPointESCRIPT(const char* s
, const char* prevWord
) { 
 147         if (strcmp(prevWord
, "end") == 0) return lev
; 
 148         if ((strcmp(prevWord
, "else") == 0 && strcmp(s
, "if") == 0) || strcmp(s
, "elseif") == 0) 
 151         if (strcmp(s
, "for") == 0 || strcmp(s
, "foreach") == 0 
 152             || strcmp(s
, "program") == 0 || strcmp(s
, "function") == 0 
 153             || strcmp(s
, "while") == 0 || strcmp(s
, "case") == 0 
 154             || strcmp(s
, "if") == 0 ) { 
 156         } else if ( strcmp(s
, "endfor") == 0 || strcmp(s
, "endforeach") == 0 
 157             || strcmp(s
, "endprogram") == 0 || strcmp(s
, "endfunction") == 0 
 158             || strcmp(s
, "endwhile") == 0 || strcmp(s
, "endcase") == 0 
 159             || strcmp(s
, "endif") == 0 ) { 
 167 static bool IsStreamCommentStyle(int style
) { 
 168         return style 
== SCE_ESCRIPT_COMMENT 
|| 
 169                style 
== SCE_ESCRIPT_COMMENTDOC 
|| 
 170                style 
== SCE_ESCRIPT_COMMENTLINE
; 
 173 static void FoldESCRIPTDoc(unsigned int startPos
, int length
, int initStyle
, WordList 
*[], Accessor 
&styler
) { 
 174         //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0; 
 175         // Do not know how to fold the comment at the moment. 
 176         bool foldCompact 
= styler
.GetPropertyInt("fold.compact", 1) != 0; 
 177         bool foldComment 
= true; 
 178         unsigned int endPos 
= startPos 
+ length
; 
 179         int visibleChars 
= 0; 
 180         int lineCurrent 
= styler
.GetLine(startPos
); 
 181         int levelPrev 
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
; 
 182         int levelCurrent 
= levelPrev
; 
 183         char chNext 
= styler
[startPos
]; 
 184         int styleNext 
= styler
.StyleAt(startPos
); 
 185         int style 
= initStyle
; 
 188         char prevWord
[32] = ""; 
 190         for (unsigned int i 
= startPos
; i 
< endPos
; i
++) { 
 192                 chNext 
= styler
.SafeGetCharAt(i 
+ 1); 
 193                 int stylePrev 
= style
; 
 195                 styleNext 
= styler
.StyleAt(i 
+ 1); 
 196                 bool atEOL 
= (ch 
== '\r' && chNext 
!= '\n') || (ch 
== '\n'); 
 199                 if (foldComment 
&& IsStreamCommentStyle(style
)) { 
 200                         if (!IsStreamCommentStyle(stylePrev
)) { 
 202                         } else if (!IsStreamCommentStyle(styleNext
) && !atEOL
) { 
 203                                 // Comments don't end at end of line and the next character may be unstyled. 
 208                 if (foldComment 
&& (style 
== SCE_ESCRIPT_COMMENTLINE
)) { 
 209                         if ((ch 
== '/') && (chNext 
== '/')) { 
 210                                 char chNext2 
= styler
.SafeGetCharAt(i 
+ 2); 
 211                                 if (chNext2 
== '{') { 
 213                                 } else if (chNext2 
== '}') { 
 219                 if (stylePrev 
== SCE_ESCRIPT_DEFAULT 
&& style 
== SCE_ESCRIPT_WORD3
) 
 221                         // Store last word start point. 
 225                 if (style 
== SCE_ESCRIPT_WORD3
) { 
 226                         if(iswordchar(ch
) && !iswordchar(chNext
)) { 
 229                                 for(j 
= 0; ( j 
< 31 ) && ( j 
< i
-lastStart
+1 ); j
++) { 
 230                                         s
[j
] = static_cast<char>(tolower(styler
[lastStart 
+ j
])); 
 233                                 levelCurrent 
+= classifyFoldPointESCRIPT(s
, prevWord
); 
 239                         if (visibleChars 
== 0 && foldCompact
) 
 240                                 lev 
|= SC_FOLDLEVELWHITEFLAG
; 
 241                         if ((levelCurrent 
> levelPrev
) && (visibleChars 
> 0)) 
 242                                 lev 
|= SC_FOLDLEVELHEADERFLAG
; 
 243                         if (lev 
!= styler
.LevelAt(lineCurrent
)) { 
 244                                 styler
.SetLevel(lineCurrent
, lev
); 
 247                         levelPrev 
= levelCurrent
; 
 249                         strcpy(prevWord
, ""); 
 252                 if (!isspacechar(ch
)) 
 256         // Fill in the real level of the next line, keeping the current flags as they will be filled in later 
 257         int flagsNext 
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
; 
 258         styler
.SetLevel(lineCurrent
, levelPrev 
| flagsNext
); 
 263 static const char * const ESCRIPTWordLists
[] = { 
 264         "Primary keywords and identifiers", 
 265         "Intrinsic functions", 
 266         "Extended and user defined functions", 
 270 LexerModule 
lmESCRIPT(SCLEX_ESCRIPT
, ColouriseESCRIPTDoc
, "escript", FoldESCRIPTDoc
, ESCRIPTWordLists
);