]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexMatlab.cxx
f75d15c7ab99379b7185898a8a9f13afe7a94b72
[wxWidgets.git] / contrib / src / stc / scintilla / src / LexMatlab.cxx
1 // Scintilla source code edit control
2 /** @file LexMatlab.cxx
3 ** Lexer for Matlab.
4 ** Written by José Fonseca
5 **/
6 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14
15 #include "Platform.h"
16
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "KeyWords.h"
21 #include "Scintilla.h"
22 #include "SciLexer.h"
23
24 static bool IsMatlabComment(Accessor &styler, int pos, int len) {
25 return len > 0 && (styler[pos] == '%' || styler[pos] == '!') ;
26 }
27
28 static inline bool IsAWordChar(const int ch) {
29 return (ch < 0x80) && (isalnum(ch) || ch == '_');
30 }
31
32 static inline bool IsAWordStart(const int ch) {
33 return (ch < 0x80) && (isalnum(ch) || ch == '_');
34 }
35
36 static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
37 WordList *keywordlists[], Accessor &styler) {
38
39 WordList &keywords = *keywordlists[0];
40
41 styler.StartAt(startPos);
42
43 bool transpose = false;
44
45 StyleContext sc(startPos, length, initStyle, styler);
46
47 for (; sc.More(); sc.Forward()) {
48
49 if (sc.state == SCE_MATLAB_OPERATOR) {
50 if (sc.chPrev == '.') {
51 if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
52 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
53 transpose = false;
54 } else if (sc.ch == '\'') {
55 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
56 transpose = true;
57 } else {
58 sc.SetState(SCE_MATLAB_DEFAULT);
59 }
60 } else {
61 sc.SetState(SCE_MATLAB_DEFAULT);
62 }
63 } else if (sc.state == SCE_MATLAB_KEYWORD) {
64 if (!isalnum(sc.ch) && sc.ch != '_') {
65 char s[100];
66 sc.GetCurrentLowered(s, sizeof(s));
67 if (keywords.InList(s)) {
68 sc.SetState(SCE_MATLAB_DEFAULT);
69 transpose = false;
70 } else {
71 sc.ChangeState(SCE_MATLAB_IDENTIFIER);
72 sc.SetState(SCE_MATLAB_DEFAULT);
73 transpose = true;
74 }
75 }
76 } else if (sc.state == SCE_MATLAB_NUMBER) {
77 if (!isdigit(sc.ch) && sc.ch != '.'
78 && !(sc.ch == 'e' || sc.ch == 'E')
79 && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
80 sc.SetState(SCE_MATLAB_DEFAULT);
81 transpose = true;
82 }
83 } else if (sc.state == SCE_MATLAB_STRING) {
84 // Matlab doubles quotes to preserve them, so just end this string
85 // state now as a following quote will start again
86 if (sc.ch == '\'') {
87 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
88 }
89 } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
90 if (sc.atLineEnd) {
91 sc.SetState(SCE_MATLAB_DEFAULT);
92 transpose = false;
93 }
94 }
95
96 if (sc.state == SCE_MATLAB_DEFAULT) {
97 if (sc.ch == '%') {
98 sc.SetState(SCE_MATLAB_COMMENT);
99 } else if (sc.ch == '!') {
100 sc.SetState(SCE_MATLAB_COMMAND);
101 } else if (sc.ch == '\'') {
102 if (transpose) {
103 sc.SetState(SCE_MATLAB_OPERATOR);
104 } else {
105 sc.SetState(SCE_MATLAB_STRING);
106 }
107 } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
108 sc.SetState(SCE_MATLAB_NUMBER);
109 } else if (isalpha(sc.ch)) {
110 sc.SetState(SCE_MATLAB_KEYWORD);
111 } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
112 if (sc.ch == ')' || sc.ch == ']') {
113 transpose = true;
114 } else {
115 transpose = false;
116 }
117 sc.SetState(SCE_MATLAB_OPERATOR);
118 } else {
119 transpose = false;
120 }
121 }
122 }
123 sc.Complete();
124 }
125
126 static void FoldMatlabDoc(unsigned int startPos, int length, int,
127 WordList *[], Accessor &styler) {
128 int endPos = startPos + length;
129
130 // Backtrack to previous line in case need to fix its fold status
131 int lineCurrent = styler.GetLine(startPos);
132 if (startPos > 0) {
133 if (lineCurrent > 0) {
134 lineCurrent--;
135 startPos = styler.LineStart(lineCurrent);
136 }
137 }
138 int spaceFlags = 0;
139 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsMatlabComment);
140 char chNext = styler[startPos];
141 for (int i = startPos; i < endPos; i++) {
142 char ch = chNext;
143 chNext = styler.SafeGetCharAt(i + 1);
144
145 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
146 int lev = indentCurrent;
147 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsMatlabComment);
148 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
149 // Only non whitespace lines can be headers
150 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
151 lev |= SC_FOLDLEVELHEADERFLAG;
152 } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
153 // Line after is blank so check the next - maybe should continue further?
154 int spaceFlags2 = 0;
155 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsMatlabComment);
156 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
157 lev |= SC_FOLDLEVELHEADERFLAG;
158 }
159 }
160 }
161 indentCurrent = indentNext;
162 styler.SetLevel(lineCurrent, lev);
163 lineCurrent++;
164 }
165 }
166 }
167
168 LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc);