Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 211 lines (190 sloc) 6.471 kB
f858c4b @djs Import Scintilla 2.11
authored
1 // Scintilla source code edit control
2 /** @file LexCsound.cxx
3 ** Lexer for Csound (Orchestra & Score)
4 ** Written by Georg Ritter - <ritterfuture A T gmail D O T com>
5 **/
6 // Copyright 1998-2003 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 #include "Platform.h"
15
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "StyleContext.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
22
23 #ifdef SCI_NAMESPACE
24 using namespace Scintilla;
25 #endif
26
27 static inline bool IsAWordChar(const int ch) {
28 return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
29 ch == '_' || ch == '?');
30 }
31
32 static inline bool IsAWordStart(const int ch) {
33 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
34 ch == '%' || ch == '@' || ch == '$' || ch == '?');
35 }
36
37 static inline bool IsCsoundOperator(char ch) {
38 if (isalnum(ch))
39 return false;
40 // '.' left out as it is used to make up numbers
41 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
42 ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
43 ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
44 ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
45 ch == '%' || ch == ':')
46 return true;
47 return false;
48 }
49
50 static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
51 Accessor &styler) {
52
53 WordList &opcode = *keywordlists[0];
54 WordList &headerStmt = *keywordlists[1];
55 WordList &otherKeyword = *keywordlists[2];
56
57 // Do not leak onto next line
58 if (initStyle == SCE_CSOUND_STRINGEOL)
59 initStyle = SCE_CSOUND_DEFAULT;
60
61 StyleContext sc(startPos, length, initStyle, styler);
62
63 for (; sc.More(); sc.Forward())
64 {
65 // Handle line continuation generically.
66 if (sc.ch == '\\') {
67 if (sc.chNext == '\n' || sc.chNext == '\r') {
68 sc.Forward();
69 if (sc.ch == '\r' && sc.chNext == '\n') {
70 sc.Forward();
71 }
72 continue;
73 }
74 }
75
76 // Determine if the current state should terminate.
77 if (sc.state == SCE_CSOUND_OPERATOR) {
78 if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
79 sc.SetState(SCE_CSOUND_DEFAULT);
80 }
81 }else if (sc.state == SCE_CSOUND_NUMBER) {
82 if (!IsAWordChar(sc.ch)) {
83 sc.SetState(SCE_CSOUND_DEFAULT);
84 }
85 } else if (sc.state == SCE_CSOUND_IDENTIFIER) {
86 if (!IsAWordChar(sc.ch) ) {
87 char s[100];
88 sc.GetCurrent(s, sizeof(s));
89
90 if (opcode.InList(s)) {
91 sc.ChangeState(SCE_CSOUND_OPCODE);
92 } else if (headerStmt.InList(s)) {
93 sc.ChangeState(SCE_CSOUND_HEADERSTMT);
94 } else if (otherKeyword.InList(s)) {
95 sc.ChangeState(SCE_CSOUND_USERKEYWORD);
96 } else if (s[0] == 'p') {
97 sc.ChangeState(SCE_CSOUND_PARAM);
98 } else if (s[0] == 'a') {
99 sc.ChangeState(SCE_CSOUND_ARATE_VAR);
100 } else if (s[0] == 'k') {
101 sc.ChangeState(SCE_CSOUND_KRATE_VAR);
102 } else if (s[0] == 'i') { // covers both i-rate variables and i-statements
103 sc.ChangeState(SCE_CSOUND_IRATE_VAR);
104 } else if (s[0] == 'g') {
105 sc.ChangeState(SCE_CSOUND_GLOBAL_VAR);
106 }
107 sc.SetState(SCE_CSOUND_DEFAULT);
108 }
109 }
110 else if (sc.state == SCE_CSOUND_COMMENT ) {
111 if (sc.atLineEnd) {
112 sc.SetState(SCE_CSOUND_DEFAULT);
113 }
114 }
115 else if ((sc.state == SCE_CSOUND_ARATE_VAR) ||
116 (sc.state == SCE_CSOUND_KRATE_VAR) ||
117 (sc.state == SCE_CSOUND_IRATE_VAR)) {
118 if (!IsAWordChar(sc.ch)) {
119 sc.SetState(SCE_CSOUND_DEFAULT);
120 }
121 }
122
123 // Determine if a new state should be entered.
124 if (sc.state == SCE_CSOUND_DEFAULT) {
125 if (sc.ch == ';'){
126 sc.SetState(SCE_CSOUND_COMMENT);
127 } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
128 sc.SetState(SCE_CSOUND_NUMBER);
129 } else if (IsAWordStart(sc.ch)) {
130 sc.SetState(SCE_CSOUND_IDENTIFIER);
131 } else if (IsCsoundOperator(static_cast<char>(sc.ch))) {
132 sc.SetState(SCE_CSOUND_OPERATOR);
133 } else if (sc.ch == 'p') {
134 sc.SetState(SCE_CSOUND_PARAM);
135 } else if (sc.ch == 'a') {
136 sc.SetState(SCE_CSOUND_ARATE_VAR);
137 } else if (sc.ch == 'k') {
138 sc.SetState(SCE_CSOUND_KRATE_VAR);
139 } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements
140 sc.SetState(SCE_CSOUND_IRATE_VAR);
141 } else if (sc.ch == 'g') {
142 sc.SetState(SCE_CSOUND_GLOBAL_VAR);
143 }
144 }
145 }
146 sc.Complete();
147 }
148
149 static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
150 Accessor &styler) {
151 unsigned int lengthDoc = startPos + length;
152 int visibleChars = 0;
153 int lineCurrent = styler.GetLine(startPos);
154 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
155 int levelCurrent = levelPrev;
156 char chNext = styler[startPos];
157 int stylePrev = 0;
158 int styleNext = styler.StyleAt(startPos);
159 for (unsigned int i = startPos; i < lengthDoc; i++) {
160 char ch = chNext;
161 chNext = styler.SafeGetCharAt(i + 1);
162 int style = styleNext;
163 styleNext = styler.StyleAt(i + 1);
164 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
165 if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) {
166 char s[20];
167 unsigned int j = 0;
168 while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) {
169 s[j] = styler[i + j];
170 j++;
171 }
172 s[j] = '\0';
173
174 if (strcmp(s, "instr") == 0)
175 levelCurrent++;
176 if (strcmp(s, "endin") == 0)
177 levelCurrent--;
178 }
179
180 if (atEOL) {
181 int lev = levelPrev;
182 if (visibleChars == 0)
183 lev |= SC_FOLDLEVELWHITEFLAG;
184 if ((levelCurrent > levelPrev) && (visibleChars > 0))
185 lev |= SC_FOLDLEVELHEADERFLAG;
186 if (lev != styler.LevelAt(lineCurrent)) {
187 styler.SetLevel(lineCurrent, lev);
188 }
189 lineCurrent++;
190 levelPrev = levelCurrent;
191 visibleChars = 0;
192 }
193 if (!isspacechar(ch))
194 visibleChars++;
195 stylePrev = style;
196 }
197 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
198 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
199 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
200 }
201
202
203 static const char * const csoundWordListDesc[] = {
204 "Opcodes",
205 "Header Statements",
206 "User keywords",
207 0
208 };
209
210 LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc);
Something went wrong with that request. Please try again.