OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexBasic.cxx
diff --git a/ext/scintilla/src/LexBasic.cxx b/ext/scintilla/src/LexBasic.cxx
new file mode 100644 (file)
index 0000000..9a52186
--- /dev/null
@@ -0,0 +1,373 @@
+// Scintilla source code edit control\r
+/** @file LexBasic.cxx\r
+ ** Lexer for BlitzBasic and PureBasic.\r
+ **/\r
+// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>\r
+// The License.txt file describes the conditions under which this software may be distributed.\r
+\r
+// This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics\r
+// and derivatives. Once they diverge enough, might want to split it into multiple\r
+// lexers for more code clearity.\r
+//\r
+// Mail me (elias <at> users <dot> sf <dot> net) for any bugs.\r
+\r
+// Folding only works for simple things like functions or types.\r
+\r
+// You may want to have a look at my ctags lexer as well, if you additionally to coloring\r
+// and folding need to extract things like label tags in your editor.\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <stdarg.h>\r
+\r
+#include "Platform.h"\r
+\r
+#include "PropSet.h"\r
+#include "Accessor.h"\r
+#include "StyleContext.h"\r
+#include "KeyWords.h"\r
+#include "Scintilla.h"\r
+#include "SciLexer.h"\r
+\r
+#ifdef SCI_NAMESPACE\r
+using namespace Scintilla;\r
+#endif\r
+\r
+/* Bits:\r
+ * 1  - whitespace\r
+ * 2  - operator\r
+ * 4  - identifier\r
+ * 8  - decimal digit\r
+ * 16 - hex digit\r
+ * 32 - bin digit\r
+ */\r
+static int character_classification[128] =\r
+{\r
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,\r
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\r
+    1,  2,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  10, 2,\r
+    60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2,  2,  2,  2,  2,  2,\r
+    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\r
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  4,\r
+    2,  20, 20, 20, 20, 20, 20, 4,  4,  4,  4,  4,  4,  4,  4,  4,\r
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2,  2,  2,  0\r
+};\r
+\r
+static bool IsSpace(int c) {\r
+       return c < 128 && (character_classification[c] & 1);\r
+}\r
+\r
+static bool IsOperator(int c) {\r
+       return c < 128 && (character_classification[c] & 2);\r
+}\r
+\r
+static bool IsIdentifier(int c) {\r
+       return c < 128 && (character_classification[c] & 4);\r
+}\r
+\r
+static bool IsDigit(int c) {\r
+       return c < 128 && (character_classification[c] & 8);\r
+}\r
+\r
+static bool IsHexDigit(int c) {\r
+       return c < 128 && (character_classification[c] & 16);\r
+}\r
+\r
+static bool IsBinDigit(int c) {\r
+       return c < 128 && (character_classification[c] & 32);\r
+}\r
+\r
+static int LowerCase(int c)\r
+{\r
+       if (c >= 'A' && c <= 'Z')\r
+               return 'a' + c - 'A';\r
+       return c;\r
+}\r
+\r
+static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,\r
+                           WordList *keywordlists[], Accessor &styler, char comment_char) {\r
+       bool wasfirst = true, isfirst = true; // true if first token in a line\r
+       styler.StartAt(startPos);\r
+\r
+       StyleContext sc(startPos, length, initStyle, styler);\r
+\r
+       // Can't use sc.More() here else we miss the last character\r
+       for (; ; sc.Forward()) {\r
+               if (sc.state == SCE_B_IDENTIFIER) {\r
+                       if (!IsIdentifier(sc.ch)) {\r
+                               // Labels\r
+                               if (wasfirst && sc.Match(':')) {\r
+                                       sc.ChangeState(SCE_B_LABEL);\r
+                                       sc.ForwardSetState(SCE_B_DEFAULT);\r
+                               } else {\r
+                                       char s[100];\r
+                                       int kstates[4] = {\r
+                                               SCE_B_KEYWORD,\r
+                                               SCE_B_KEYWORD2,\r
+                                               SCE_B_KEYWORD3,\r
+                                               SCE_B_KEYWORD4,\r
+                                       };\r
+                                       sc.GetCurrentLowered(s, sizeof(s));\r
+                                       for (int i = 0; i < 4; i++) {\r
+                                               if (keywordlists[i]->InList(s)) {\r
+                                                       sc.ChangeState(kstates[i]);\r
+                                               }\r
+                                       }\r
+                                       // Types, must set them as operator else they will be\r
+                                       // matched as number/constant\r
+                                       if (sc.Match('.') || sc.Match('$') || sc.Match('%') ||\r
+                                               sc.Match('#')) {\r
+                                               sc.SetState(SCE_B_OPERATOR);\r
+                                       } else {\r
+                                               sc.SetState(SCE_B_DEFAULT);\r
+                                       }\r
+                               }\r
+                       }\r
+               } else if (sc.state == SCE_B_OPERATOR) {\r
+                       if (!IsOperator(sc.ch) || sc.Match('#'))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_LABEL) {\r
+                       if (!IsIdentifier(sc.ch))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_CONSTANT) {\r
+                       if (!IsIdentifier(sc.ch))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_NUMBER) {\r
+                       if (!IsDigit(sc.ch))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_HEXNUMBER) {\r
+                       if (!IsHexDigit(sc.ch))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_BINNUMBER) {\r
+                       if (!IsBinDigit(sc.ch))\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+               } else if (sc.state == SCE_B_STRING) {\r
+                       if (sc.ch == '"') {\r
+                               sc.ForwardSetState(SCE_B_DEFAULT);\r
+                       }\r
+                       if (sc.atLineEnd) {\r
+                               sc.ChangeState(SCE_B_ERROR);\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+                       }\r
+               } else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) {\r
+                       if (sc.atLineEnd) {\r
+                               sc.SetState(SCE_B_DEFAULT);\r
+                       }\r
+               }\r
+\r
+               if (sc.atLineStart)\r
+                       isfirst = true;\r
+\r
+               if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {\r
+                       if (isfirst && sc.Match('.')) {\r
+                               sc.SetState(SCE_B_LABEL);\r
+                       } else if (isfirst && sc.Match('#')) {\r
+                               wasfirst = isfirst;\r
+                               sc.SetState(SCE_B_IDENTIFIER);\r
+                       } else if (sc.Match(comment_char)) {\r
+                               // Hack to make deprecated QBASIC '$Include show\r
+                               // up in freebasic with SCE_B_PREPROCESSOR.\r
+                               if (comment_char == '\'' && sc.Match(comment_char, '$'))\r
+                                       sc.SetState(SCE_B_PREPROCESSOR);\r
+                               else\r
+                                       sc.SetState(SCE_B_COMMENT);\r
+                       } else if (sc.Match('"')) {\r
+                               sc.SetState(SCE_B_STRING);\r
+                       } else if (IsDigit(sc.ch)) {\r
+                               sc.SetState(SCE_B_NUMBER);\r
+                       } else if (sc.Match('$')) {\r
+                               sc.SetState(SCE_B_HEXNUMBER);\r
+                       } else if (sc.Match('%')) {\r
+                               sc.SetState(SCE_B_BINNUMBER);\r
+                       } else if (sc.Match('#')) {\r
+                               sc.SetState(SCE_B_CONSTANT);\r
+                       } else if (IsOperator(sc.ch)) {\r
+                               sc.SetState(SCE_B_OPERATOR);\r
+                       } else if (IsIdentifier(sc.ch)) {\r
+                               wasfirst = isfirst;\r
+                               sc.SetState(SCE_B_IDENTIFIER);\r
+                       } else if (!IsSpace(sc.ch)) {\r
+                               sc.SetState(SCE_B_ERROR);\r
+                       }\r
+               }\r
+\r
+               if (!IsSpace(sc.ch))\r
+                       isfirst = false;\r
+\r
+               if (!sc.More())\r
+                       break;\r
+       }\r
+       sc.Complete();\r
+}\r
+\r
+static int CheckBlitzFoldPoint(char const *token, int &level) {\r
+       if (!strcmp(token, "function") ||\r
+               !strcmp(token, "type")) {\r
+               level |= SC_FOLDLEVELHEADERFLAG;\r
+               return 1;\r
+       }\r
+       if (!strcmp(token, "end function") ||\r
+               !strcmp(token, "end type")) {\r
+               return -1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int CheckPureFoldPoint(char const *token, int &level) {\r
+       if (!strcmp(token, "procedure") ||\r
+               !strcmp(token, "enumeration") ||\r
+               !strcmp(token, "interface") ||\r
+               !strcmp(token, "structure")) {\r
+               level |= SC_FOLDLEVELHEADERFLAG;\r
+               return 1;\r
+       }\r
+       if (!strcmp(token, "endprocedure") ||\r
+               !strcmp(token, "endenumeration") ||\r
+               !strcmp(token, "endinterface") ||\r
+               !strcmp(token, "endstructure")) {\r
+               return -1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static int CheckFreeFoldPoint(char const *token, int &level) {\r
+       if (!strcmp(token, "function") ||\r
+               !strcmp(token, "sub") ||\r
+               !strcmp(token, "type")) {\r
+               level |= SC_FOLDLEVELHEADERFLAG;\r
+               return 1;\r
+       }\r
+       if (!strcmp(token, "end function") ||\r
+               !strcmp(token, "end sub") ||\r
+               !strcmp(token, "end type")) {\r
+               return -1;\r
+       }\r
+       return 0;\r
+}\r
+\r
+static void FoldBasicDoc(unsigned int startPos, int length,\r
+       Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {\r
+       int line = styler.GetLine(startPos);\r
+       int level = styler.LevelAt(line);\r
+       int go = 0, done = 0;\r
+       int endPos = startPos + length;\r
+       char word[256];\r
+       int wordlen = 0;\r
+       int i;\r
+        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;\r
+       // Scan for tokens at the start of the line (they may include\r
+       // whitespace, for tokens like "End Function"\r
+       for (i = startPos; i < endPos; i++) {\r
+               int c = styler.SafeGetCharAt(i);\r
+               if (!done && !go) {\r
+                       if (wordlen) { // are we scanning a token already?\r
+                               word[wordlen] = static_cast<char>(LowerCase(c));\r
+                               if (!IsIdentifier(c)) { // done with token\r
+                                       word[wordlen] = '\0';\r
+                                       go = CheckFoldPoint(word, level);\r
+                                       if (!go) {\r
+                                               // Treat any whitespace as single blank, for\r
+                                               // things like "End   Function".\r
+                                               if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {\r
+                                                       word[wordlen] = ' ';\r
+                                                       if (wordlen < 255)\r
+                                                               wordlen++;\r
+                                               }\r
+                                               else // done with this line\r
+                                                       done = 1;\r
+                                       }\r
+                               } else if (wordlen < 255) {\r
+                                       wordlen++;\r
+                               }\r
+                       } else { // start scanning at first non-whitespace character\r
+                               if (!IsSpace(c)) {\r
+                                       if (IsIdentifier(c)) {\r
+                                               word[0] = static_cast<char>(LowerCase(c));\r
+                                               wordlen = 1;\r
+                                       } else // done with this line\r
+                                               done = 1;\r
+                               }\r
+                       }\r
+               }\r
+               if (c == '\n') { // line end\r
+                       if (!done && wordlen == 0 && foldCompact) // line was only space\r
+                               level |= SC_FOLDLEVELWHITEFLAG;\r
+                       if (level != styler.LevelAt(line))\r
+                               styler.SetLevel(line, level);\r
+                       level += go;\r
+                       line++;\r
+                       // reset state\r
+                       wordlen = 0;\r
+                       level &= ~SC_FOLDLEVELHEADERFLAG;\r
+                       level &= ~SC_FOLDLEVELWHITEFLAG;\r
+                       go = 0;\r
+                       done = 0;\r
+               }\r
+       }\r
+}\r
+\r
+static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,\r
+                           WordList *keywordlists[], Accessor &styler) {\r
+       ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');\r
+}\r
+\r
+static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,\r
+                           WordList *keywordlists[], Accessor &styler) {\r
+       ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');\r
+}\r
+\r
+static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,\r
+                           WordList *keywordlists[], Accessor &styler) {\r
+       ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');\r
+}\r
+\r
+static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,\r
+       WordList *[], Accessor &styler) {\r
+       FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);\r
+}\r
+\r
+static void FoldPureBasicDoc(unsigned int startPos, int length, int,\r
+       WordList *[], Accessor &styler) {\r
+       FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);\r
+}\r
+\r
+static void FoldFreeBasicDoc(unsigned int startPos, int length, int,\r
+       WordList *[], Accessor &styler) {\r
+       FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);\r
+}\r
+\r
+static const char * const blitzbasicWordListDesc[] = {\r
+       "BlitzBasic Keywords",\r
+       "user1",\r
+       "user2",\r
+       "user3",\r
+       0\r
+};\r
+\r
+static const char * const purebasicWordListDesc[] = {\r
+       "PureBasic Keywords",\r
+       "PureBasic PreProcessor Keywords",\r
+       "user defined 1",\r
+       "user defined 2",\r
+       0\r
+};\r
+\r
+static const char * const freebasicWordListDesc[] = {\r
+       "FreeBasic Keywords",\r
+       "FreeBasic PreProcessor Keywords",\r
+       "user defined 1",\r
+       "user defined 2",\r
+       0\r
+};\r
+\r
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",\r
+       FoldBlitzBasicDoc, blitzbasicWordListDesc);\r
+\r
+LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",\r
+       FoldPureBasicDoc, purebasicWordListDesc);\r
+\r
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",\r
+       FoldFreeBasicDoc, freebasicWordListDesc);\r
+\r