]>
git.saurik.com Git - wxWidgets.git/blob - contrib/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 static inline bool IsAWordChar(const int ch
) {
25 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' ||
26 ch
== '_' || ch
== '?');
29 static inline bool IsAWordStart(const int ch
) {
30 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_' || ch
== '.' ||
31 ch
== '%' || ch
== '@' || ch
== '$' || ch
== '?');
34 static inline bool IsCsoundOperator(char ch
) {
37 // '.' left out as it is used to make up numbers
38 if (ch
== '*' || ch
== '/' || ch
== '-' || ch
== '+' ||
39 ch
== '(' || ch
== ')' || ch
== '=' || ch
== '^' ||
40 ch
== '[' || ch
== ']' || ch
== '<' || ch
== '&' ||
41 ch
== '>' || ch
== ',' || ch
== '|' || ch
== '~' ||
42 ch
== '%' || ch
== ':')
47 static void ColouriseCsoundDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
50 WordList
&opcode
= *keywordlists
[0];
51 WordList
&headerStmt
= *keywordlists
[1];
52 WordList
&otherKeyword
= *keywordlists
[2];
54 // Do not leak onto next line
55 if (initStyle
== SCE_CSOUND_STRINGEOL
)
56 initStyle
= SCE_CSOUND_DEFAULT
;
58 StyleContext
sc(startPos
, length
, initStyle
, styler
);
60 for (; sc
.More(); sc
.Forward())
62 // Handle line continuation generically.
64 if (sc
.chNext
== '\n' || sc
.chNext
== '\r') {
66 if (sc
.ch
== '\r' && sc
.chNext
== '\n') {
73 // Determine if the current state should terminate.
74 if (sc
.state
== SCE_CSOUND_OPERATOR
) {
75 if (!IsCsoundOperator(static_cast<char>(sc
.ch
))) {
76 sc
.SetState(SCE_CSOUND_DEFAULT
);
78 }else if (sc
.state
== SCE_CSOUND_NUMBER
) {
79 if (!IsAWordChar(sc
.ch
)) {
80 sc
.SetState(SCE_CSOUND_DEFAULT
);
82 } else if (sc
.state
== SCE_CSOUND_IDENTIFIER
) {
83 if (!IsAWordChar(sc
.ch
) ) {
85 sc
.GetCurrent(s
, sizeof(s
));
87 if (opcode
.InList(s
)) {
88 sc
.ChangeState(SCE_CSOUND_OPCODE
);
89 } else if (headerStmt
.InList(s
)) {
90 sc
.ChangeState(SCE_CSOUND_HEADERSTMT
);
91 } else if (otherKeyword
.InList(s
)) {
92 sc
.ChangeState(SCE_CSOUND_USERKEYWORD
);
93 } else if (s
[0] == 'p') {
94 sc
.ChangeState(SCE_CSOUND_PARAM
);
95 } else if (s
[0] == 'a') {
96 sc
.ChangeState(SCE_CSOUND_ARATE_VAR
);
97 } else if (s
[0] == 'k') {
98 sc
.ChangeState(SCE_CSOUND_KRATE_VAR
);
99 } else if (s
[0] == 'i') { // covers both i-rate variables and i-statements
100 sc
.ChangeState(SCE_CSOUND_IRATE_VAR
);
101 } else if (s
[0] == 'g') {
102 sc
.ChangeState(SCE_CSOUND_GLOBAL_VAR
);
104 sc
.SetState(SCE_CSOUND_DEFAULT
);
107 else if (sc
.state
== SCE_CSOUND_COMMENT
) {
109 sc
.SetState(SCE_CSOUND_DEFAULT
);
112 else if ((sc
.state
== SCE_CSOUND_ARATE_VAR
) ||
113 (sc
.state
== SCE_CSOUND_KRATE_VAR
) ||
114 (sc
.state
== SCE_CSOUND_IRATE_VAR
)) {
115 if (!IsAWordChar(sc
.ch
)) {
116 sc
.SetState(SCE_CSOUND_DEFAULT
);
120 // Determine if a new state should be entered.
121 if (sc
.state
== SCE_CSOUND_DEFAULT
) {
123 sc
.SetState(SCE_CSOUND_COMMENT
);
124 } else if (isdigit(sc
.ch
) || (sc
.ch
== '.' && isdigit(sc
.chNext
))) {
125 sc
.SetState(SCE_CSOUND_NUMBER
);
126 } else if (IsAWordStart(sc
.ch
)) {
127 sc
.SetState(SCE_CSOUND_IDENTIFIER
);
128 } else if (IsCsoundOperator(static_cast<char>(sc
.ch
))) {
129 sc
.SetState(SCE_CSOUND_OPERATOR
);
130 } else if (sc
.ch
== 'p') {
131 sc
.SetState(SCE_CSOUND_PARAM
);
132 } else if (sc
.ch
== 'a') {
133 sc
.SetState(SCE_CSOUND_ARATE_VAR
);
134 } else if (sc
.ch
== 'k') {
135 sc
.SetState(SCE_CSOUND_KRATE_VAR
);
136 } else if (sc
.ch
== 'i') { // covers both i-rate variables and i-statements
137 sc
.SetState(SCE_CSOUND_IRATE_VAR
);
138 } else if (sc
.ch
== 'g') {
139 sc
.SetState(SCE_CSOUND_GLOBAL_VAR
);
146 static void FoldCsoundInstruments(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
148 unsigned int lengthDoc
= startPos
+ length
;
149 int visibleChars
= 0;
150 int lineCurrent
= styler
.GetLine(startPos
);
151 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
152 int levelCurrent
= levelPrev
;
153 char chNext
= styler
[startPos
];
155 int styleNext
= styler
.StyleAt(startPos
);
156 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
158 chNext
= styler
.SafeGetCharAt(i
+ 1);
159 int style
= styleNext
;
160 styleNext
= styler
.StyleAt(i
+ 1);
161 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
162 if ((stylePrev
!= SCE_CSOUND_OPCODE
) && (style
== SCE_CSOUND_OPCODE
)) {
165 while ((j
< (sizeof(s
) - 1)) && (iswordchar(styler
[i
+ j
]))) {
166 s
[j
] = styler
[i
+ j
];
171 if (strcmp(s
, "instr") == 0)
173 if (strcmp(s
, "endin") == 0)
179 if (visibleChars
== 0)
180 lev
|= SC_FOLDLEVELWHITEFLAG
;
181 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
182 lev
|= SC_FOLDLEVELHEADERFLAG
;
183 if (lev
!= styler
.LevelAt(lineCurrent
)) {
184 styler
.SetLevel(lineCurrent
, lev
);
187 levelPrev
= levelCurrent
;
190 if (!isspacechar(ch
))
194 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
195 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
196 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
200 static const char * const csoundWordListDesc
[] = {
207 LexerModule
lmCsound(SCLEX_CSOUND
, ColouriseCsoundDoc
, "csound", FoldCsoundInstruments
, csoundWordListDesc
);