]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexCsound.cxx
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>
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.
18 #include "StyleContext.h"
20 #include "Scintilla.h"
24 using namespace Scintilla
;
27 static inline bool IsAWordChar(const int ch
) {
28 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' ||
29 ch
== '_' || ch
== '?');
32 static inline bool IsAWordStart(const int ch
) {
33 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_' || ch
== '.' ||
34 ch
== '%' || ch
== '@' || ch
== '$' || ch
== '?');
37 static inline bool IsCsoundOperator(char ch
) {
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
== ':')
50 static void ColouriseCsoundDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
53 WordList
&opcode
= *keywordlists
[0];
54 WordList
&headerStmt
= *keywordlists
[1];
55 WordList
&otherKeyword
= *keywordlists
[2];
57 // Do not leak onto next line
58 if (initStyle
== SCE_CSOUND_STRINGEOL
)
59 initStyle
= SCE_CSOUND_DEFAULT
;
61 StyleContext
sc(startPos
, length
, initStyle
, styler
);
63 for (; sc
.More(); sc
.Forward())
65 // Handle line continuation generically.
67 if (sc
.chNext
== '\n' || sc
.chNext
== '\r') {
69 if (sc
.ch
== '\r' && sc
.chNext
== '\n') {
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
);
81 }else if (sc
.state
== SCE_CSOUND_NUMBER
) {
82 if (!IsAWordChar(sc
.ch
)) {
83 sc
.SetState(SCE_CSOUND_DEFAULT
);
85 } else if (sc
.state
== SCE_CSOUND_IDENTIFIER
) {
86 if (!IsAWordChar(sc
.ch
) ) {
88 sc
.GetCurrent(s
, sizeof(s
));
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
);
107 sc
.SetState(SCE_CSOUND_DEFAULT
);
110 else if (sc
.state
== SCE_CSOUND_COMMENT
) {
112 sc
.SetState(SCE_CSOUND_DEFAULT
);
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
);
123 // Determine if a new state should be entered.
124 if (sc
.state
== SCE_CSOUND_DEFAULT
) {
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
);
149 static void FoldCsoundInstruments(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
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
];
158 int styleNext
= styler
.StyleAt(startPos
);
159 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
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
)) {
168 while ((j
< (sizeof(s
) - 1)) && (iswordchar(styler
[i
+ j
]))) {
169 s
[j
] = styler
[i
+ j
];
174 if (strcmp(s
, "instr") == 0)
176 if (strcmp(s
, "endin") == 0)
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
);
190 levelPrev
= levelCurrent
;
193 if (!isspacechar(ch
))
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
);
203 static const char * const csoundWordListDesc
[] = {
210 LexerModule
lmCsound(SCLEX_CSOUND
, ColouriseCsoundDoc
, "csound", FoldCsoundInstruments
, csoundWordListDesc
);