OLD | NEW |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
11 LilyPond is distributed in the hope that it will be useful, | 11 LilyPond is distributed in the hope that it will be useful, |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
18 */ | 18 */ |
19 | 19 |
20 #include "lily-lexer.hh" | 20 #include "lily-lexer.hh" |
21 | 21 |
22 #include <cctype> | 22 #include <cctype> |
23 #include <sstream> | 23 #include <sstream> |
24 | 24 |
25 #include "context.hh" // for nested_property_alist | 25 #include "context.hh" // for nested_property_alist |
26 #include "international.hh" | 26 #include "international.hh" |
27 #include "interval.hh" | 27 #include "interval.hh" |
28 #include "keyword.hh" | |
29 #include "main.hh" | 28 #include "main.hh" |
30 #include "moment.hh" | 29 #include "moment.hh" |
31 #include "parser.hh" | 30 #include "parser.hh" |
32 #include "scm-hash.hh" | 31 #include "scm-hash.hh" |
33 #include "source-file.hh" | 32 #include "source-file.hh" |
34 #include "warn.hh" | 33 #include "warn.hh" |
35 #include "program-option.hh" | 34 #include "program-option.hh" |
36 #include "lily-parser.hh" | 35 #include "lily-parser.hh" |
37 #include "ly-module.hh" | 36 #include "ly-module.hh" |
38 | 37 |
39 using std::string; | 38 using std::string; |
40 | 39 |
41 static Keyword_ent the_key_tab[] | 40 class Keyword_ent |
42 = | |
43 { | 41 { |
| 42 public: |
| 43 char const *name_; |
| 44 int tokcode_; |
| 45 }; |
| 46 |
| 47 static std::unordered_map<std::string, int> keytable{ |
44 {"accepts", ACCEPTS}, | 48 {"accepts", ACCEPTS}, |
45 {"addlyrics", ADDLYRICS}, | 49 {"addlyrics", ADDLYRICS}, |
46 {"alias", ALIAS}, | 50 {"alias", ALIAS}, |
47 {"alternative", ALTERNATIVE}, | 51 {"alternative", ALTERNATIVE}, |
48 {"book", BOOK}, | 52 {"book", BOOK}, |
49 {"bookpart", BOOKPART}, | 53 {"bookpart", BOOKPART}, |
50 {"change", CHANGE}, | 54 {"change", CHANGE}, |
51 {"chordmode", CHORDMODE}, | 55 {"chordmode", CHORDMODE}, |
52 {"chords", CHORDS}, | 56 {"chords", CHORDS}, |
53 {"consists", CONSISTS}, | 57 {"consists", CONSISTS}, |
(...skipping 25 matching lines...) Expand all Loading... |
79 {"rest", REST}, | 83 {"rest", REST}, |
80 {"revert", REVERT}, | 84 {"revert", REVERT}, |
81 {"score", SCORE}, | 85 {"score", SCORE}, |
82 {"sequential", SEQUENTIAL}, | 86 {"sequential", SEQUENTIAL}, |
83 {"set", SET}, | 87 {"set", SET}, |
84 {"simultaneous", SIMULTANEOUS}, | 88 {"simultaneous", SIMULTANEOUS}, |
85 {"tempo", TEMPO}, | 89 {"tempo", TEMPO}, |
86 {"type", TYPE}, | 90 {"type", TYPE}, |
87 {"unset", UNSET}, | 91 {"unset", UNSET}, |
88 {"with", WITH}, | 92 {"with", WITH}, |
89 {0, 0} | |
90 }; | 93 }; |
91 | 94 |
92 Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) | 95 Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) |
93 { | 96 { |
94 parser_ = parser; | 97 parser_ = parser; |
95 keytable_ = new Keyword_table (the_key_tab); | 98 |
96 chordmodifier_tab_ = SCM_EOL; | 99 chordmodifier_tab_ = SCM_EOL; |
97 pitchname_tab_stack_ = SCM_EOL; | 100 pitchname_tab_stack_ = SCM_EOL; |
98 sources_ = sources; | 101 sources_ = sources; |
99 scopes_ = SCM_EOL; | 102 scopes_ = SCM_EOL; |
100 error_level_ = 0; | 103 error_level_ = 0; |
101 is_main_input_ = false; | 104 is_main_input_ = false; |
102 main_input_level_ = 0; | 105 main_input_level_ = 0; |
103 start_module_ = SCM_EOL; | 106 start_module_ = SCM_EOL; |
104 extra_tokens_ = SCM_EOL; | 107 extra_tokens_ = SCM_EOL; |
105 smobify_self (); | 108 smobify_self (); |
106 | 109 |
107 add_scope (ly_make_module (false)); | 110 add_scope (ly_make_module (false)); |
108 push_note_state (SCM_EOL); | 111 push_note_state (SCM_EOL); |
109 chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); | 112 chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); |
110 } | 113 } |
111 | 114 |
112 Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser, | 115 Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser, |
113 SCM override_input) | 116 SCM override_input) |
114 : Includable_lexer () | 117 : Includable_lexer () |
115 { | 118 { |
116 parser_ = parser; | 119 parser_ = parser; |
117 keytable_ = (src.keytable_) ? new Keyword_table (*src.keytable_) : 0; | |
118 chordmodifier_tab_ = src.chordmodifier_tab_; | 120 chordmodifier_tab_ = src.chordmodifier_tab_; |
119 pitchname_tab_stack_ = src.pitchname_tab_stack_; | 121 pitchname_tab_stack_ = src.pitchname_tab_stack_; |
120 sources_ = src.sources_; | 122 sources_ = src.sources_; |
121 scopes_ = src.scopes_; | 123 scopes_ = src.scopes_; |
122 start_module_ = SCM_EOL; | 124 start_module_ = SCM_EOL; |
123 | 125 |
124 error_level_ = 0; | 126 error_level_ = 0; |
125 is_main_input_ = src.is_main_input_; | 127 is_main_input_ = src.is_main_input_; |
126 main_input_level_ = 0; | 128 main_input_level_ = 0; |
127 | 129 |
128 extra_tokens_ = SCM_EOL; | 130 extra_tokens_ = SCM_EOL; |
129 if (unsmob<Input> (override_input)) | 131 if (unsmob<Input> (override_input)) |
130 override_input_ = *unsmob<Input> (override_input); | 132 override_input_ = *unsmob<Input> (override_input); |
131 | 133 |
132 smobify_self (); | 134 smobify_self (); |
133 | 135 |
134 push_note_state (SCM_EOL); | 136 push_note_state (SCM_EOL); |
135 } | 137 } |
136 | 138 |
137 Lily_lexer::~Lily_lexer () | |
138 { | |
139 delete keytable_; | |
140 } | |
141 | |
142 void | 139 void |
143 Lily_lexer::add_scope (SCM module) | 140 Lily_lexer::add_scope (SCM module) |
144 { | 141 { |
145 ly_reexport_module (scm_current_module ()); | 142 ly_reexport_module (scm_current_module ()); |
146 if (!scm_is_pair (scopes_)) | 143 if (!scm_is_pair (scopes_)) |
147 start_module_ = scm_current_module (); | 144 start_module_ = scm_current_module (); |
148 | 145 |
149 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) | 146 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) |
150 ly_use_module (module, scm_car (s)); | 147 ly_use_module (module, scm_car (s)); |
151 scopes_ = scm_cons (module, scopes_); | 148 scopes_ = scm_cons (module, scopes_); |
(...skipping 24 matching lines...) Expand all Loading... |
176 scm_set_current_module (scm_car (scopes_)); | 173 scm_set_current_module (scm_car (scopes_)); |
177 else | 174 else |
178 scm_set_current_module (start_module_); | 175 scm_set_current_module (start_module_); |
179 | 176 |
180 return old; | 177 return old; |
181 } | 178 } |
182 | 179 |
183 int | 180 int |
184 Lily_lexer::lookup_keyword (const string &s) | 181 Lily_lexer::lookup_keyword (const string &s) |
185 { | 182 { |
186 return keytable_->lookup (s.c_str ()); | 183 auto const &it = keytable.find (s); |
| 184 if (it == keytable.end ()) |
| 185 { |
| 186 return -1; |
| 187 } |
| 188 return it->second; |
187 } | 189 } |
188 | 190 |
189 SCM | 191 SCM |
190 Lily_lexer::keyword_list () const | |
191 { | |
192 if (!keytable_) | |
193 return SCM_EOL; | |
194 | |
195 SCM l = SCM_EOL; | |
196 SCM *tail = &l; | |
197 for (vsize i = 0; i < keytable_->table_.size (); i++) | |
198 { | |
199 *tail = scm_acons (scm_from_utf8_string (keytable_->table_[i].name_), | |
200 scm_from_int (keytable_->table_[i].tokcode_), | |
201 SCM_EOL); | |
202 | |
203 tail = SCM_CDRLOC (*tail); | |
204 } | |
205 | |
206 return l; | |
207 } | |
208 | |
209 SCM | |
210 Lily_lexer::lookup_identifier_symbol (SCM sym) | 192 Lily_lexer::lookup_identifier_symbol (SCM sym) |
211 { | 193 { |
212 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) | 194 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) |
213 { | 195 { |
214 SCM var = ly_module_lookup (scm_car (s), sym); | 196 SCM var = ly_module_lookup (scm_car (s), sym); |
215 if (scm_is_true (var)) | 197 if (scm_is_true (var)) |
216 return scm_variable_ref (var); | 198 return scm_variable_ref (var); |
217 } | 199 } |
218 | 200 |
219 return SCM_UNDEFINED; | 201 return SCM_UNDEFINED; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 scm_display (scopes_, port); | 368 scm_display (scopes_, port); |
387 scm_puts (" >", port); | 369 scm_puts (" >", port); |
388 return 1; | 370 return 1; |
389 } | 371 } |
390 | 372 |
391 bool | 373 bool |
392 Lily_lexer::is_clean () const | 374 Lily_lexer::is_clean () const |
393 { | 375 { |
394 return include_stack_.empty (); | 376 return include_stack_.empty (); |
395 } | 377 } |
OLD | NEW |