VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_gui_extra / code_editor / juce_LuaCodeTokeniser.cpp
blobf046c4f7635be96cd1d435d3654970b3c898d7c4
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
23 ==============================================================================
26 namespace juce
29 struct LuaTokeniserFunctions
31 static bool isReservedKeyword (String::CharPointerType token, const int tokenLength) noexcept
33 static const char* const keywords2Char[] =
34 { "if", "or", "in", "do", nullptr };
36 static const char* const keywords3Char[] =
37 { "and", "end", "for", "nil", "not", nullptr };
39 static const char* const keywords4Char[] =
40 { "then", "true", "else", nullptr };
42 static const char* const keywords5Char[] =
43 { "false", "local", "until", "while", "break", nullptr };
45 static const char* const keywords6Char[] =
46 { "repeat", "return", "elseif", nullptr};
48 static const char* const keywordsOther[] =
49 { "function", "@interface", "@end", "@synthesize", "@dynamic", "@public",
50 "@private", "@property", "@protected", "@class", nullptr };
52 const char* const* k;
54 switch (tokenLength)
56 case 2: k = keywords2Char; break;
57 case 3: k = keywords3Char; break;
58 case 4: k = keywords4Char; break;
59 case 5: k = keywords5Char; break;
60 case 6: k = keywords6Char; break;
62 default:
63 if (tokenLength < 2 || tokenLength > 16)
64 return false;
66 k = keywordsOther;
67 break;
70 for (int i = 0; k[i] != nullptr; ++i)
71 if (token.compare (CharPointer_ASCII (k[i])) == 0)
72 return true;
74 return false;
77 template <typename Iterator>
78 static int parseIdentifier (Iterator& source) noexcept
80 int tokenLength = 0;
81 String::CharPointerType::CharType possibleIdentifier[100] = {};
82 String::CharPointerType possible (possibleIdentifier);
84 while (CppTokeniserFunctions::isIdentifierBody (source.peekNextChar()))
86 auto c = source.nextChar();
88 if (tokenLength < 20)
89 possible.write (c);
91 ++tokenLength;
94 if (tokenLength > 1 && tokenLength <= 16)
96 possible.writeNull();
98 if (isReservedKeyword (String::CharPointerType (possibleIdentifier), tokenLength))
99 return LuaTokeniser::tokenType_keyword;
102 return LuaTokeniser::tokenType_identifier;
105 template <typename Iterator>
106 static int readNextToken (Iterator& source)
108 source.skipWhitespace();
110 auto firstChar = source.peekNextChar();
112 switch (firstChar)
114 case 0:
115 break;
117 case '0': case '1': case '2': case '3': case '4':
118 case '5': case '6': case '7': case '8': case '9':
119 case '.':
121 auto result = CppTokeniserFunctions::parseNumber (source);
123 if (result == LuaTokeniser::tokenType_error)
125 source.skip();
127 if (firstChar == '.')
128 return LuaTokeniser::tokenType_punctuation;
131 return result;
134 case ',':
135 case ';':
136 case ':':
137 source.skip();
138 return LuaTokeniser::tokenType_punctuation;
140 case '(': case ')':
141 case '{': case '}':
142 case '[': case ']':
143 source.skip();
144 return LuaTokeniser::tokenType_bracket;
146 case '"':
147 case '\'':
148 CppTokeniserFunctions::skipQuotedString (source);
149 return LuaTokeniser::tokenType_string;
151 case '+':
152 source.skip();
153 CppTokeniserFunctions::skipIfNextCharMatches (source, '+', '=');
154 return LuaTokeniser::tokenType_operator;
156 case '-':
158 source.skip();
159 auto result = CppTokeniserFunctions::parseNumber (source);
161 if (source.peekNextChar() == '-')
163 source.skipToEndOfLine();
164 return LuaTokeniser::tokenType_comment;
167 if (result == LuaTokeniser::tokenType_error)
169 CppTokeniserFunctions::skipIfNextCharMatches (source, '-', '=');
170 return LuaTokeniser::tokenType_operator;
173 return result;
176 case '*': case '%':
177 case '=': case '!':
178 source.skip();
179 CppTokeniserFunctions::skipIfNextCharMatches (source, '=');
180 return LuaTokeniser::tokenType_operator;
182 case '?':
183 case '~':
184 source.skip();
185 return LuaTokeniser::tokenType_operator;
187 case '<': case '>':
188 case '|': case '&': case '^':
189 source.skip();
190 CppTokeniserFunctions::skipIfNextCharMatches (source, firstChar);
191 CppTokeniserFunctions::skipIfNextCharMatches (source, '=');
192 return LuaTokeniser::tokenType_operator;
194 default:
195 if (CppTokeniserFunctions::isIdentifierStart (firstChar))
196 return parseIdentifier (source);
198 source.skip();
199 break;
202 return LuaTokeniser::tokenType_error;
206 //==============================================================================
207 LuaTokeniser::LuaTokeniser() {}
208 LuaTokeniser::~LuaTokeniser() {}
210 int LuaTokeniser::readNextToken (CodeDocument::Iterator& source)
212 return LuaTokeniserFunctions::readNextToken (source);
215 CodeEditorComponent::ColourScheme LuaTokeniser::getDefaultColourScheme()
217 static const CodeEditorComponent::ColourScheme::TokenType types[] =
219 { "Error", Colour (0xffcc0000) },
220 { "Comment", Colour (0xff3c3c3c) },
221 { "Keyword", Colour (0xff0000cc) },
222 { "Operator", Colour (0xff225500) },
223 { "Identifier", Colour (0xff000000) },
224 { "Integer", Colour (0xff880000) },
225 { "Float", Colour (0xff885500) },
226 { "String", Colour (0xff990099) },
227 { "Bracket", Colour (0xff000055) },
228 { "Punctuation", Colour (0xff004400) }
231 CodeEditorComponent::ColourScheme cs;
233 for (auto& t : types)
234 cs.set (t.name, Colour (t.colour));
236 return cs;
239 } // namespace juce