]> git.donarmstrong.com Git - lilypond.git/blob - lily/translator-group.cc
(parse_symbol_list): Bugfix.
[lilypond.git] / lily / translator-group.cc
1 /*
2   translator-group.cc -- implement Translator_group
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "translator-group.hh"
10
11 #include "output-def.hh"
12 #include "warn.hh"
13 #include "scm-hash.hh"
14 #include "context-def.hh"
15 #include "context.hh"
16 #include "main.hh"
17 #include "music.hh"
18
19 Translator_group *
20 Translator_group::get_daddy_translator () const
21 {
22   return context ()->get_parent_context ()->implementation ();
23 }
24
25 void
26 translator_each (SCM list, Translator_method method)
27 {
28   for (SCM p = list; scm_is_pair (p); p = scm_cdr (p))
29     (unsmob_translator (scm_car (p))->*method) ();
30 }
31
32 void
33 Translator_group::initialize ()
34 {
35   precompute_method_bindings ();
36 }
37
38 void
39 Translator_group::finalize ()
40 {
41 }
42
43 bool
44 translator_accepts_any_of (Translator *tr, SCM ifaces)
45 {
46   SCM ack_ifs = scm_assoc (ly_symbol2scm ("events-accepted"),
47                            tr->translator_description ());
48   ack_ifs = scm_cdr (ack_ifs);
49   for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
50     if (scm_c_memq (scm_car (s), ack_ifs) != SCM_BOOL_F)
51       return true;
52   return false;
53 }
54
55 SCM
56 find_accept_translators (SCM gravlist, SCM ifaces)
57 {
58   SCM l = SCM_EOL;
59   for (SCM s = gravlist; scm_is_pair (s); s = scm_cdr (s))
60     {
61       Translator *tr = unsmob_translator (scm_car (s));
62       if (translator_accepts_any_of (tr, ifaces))
63         l = scm_cons (tr->self_scm (), l);
64     }
65   l = scm_reverse_x (l, SCM_EOL);
66
67   return l;
68 }
69
70 bool
71 Translator_group::try_music (Music *m)
72 {
73   SCM name = scm_sloppy_assq (ly_symbol2scm ("name"),
74                               m->get_property_alist (false));
75
76   if (!scm_is_pair (name))
77     return false;
78
79   name = scm_cdr (name);
80   SCM accept_list = scm_hashq_ref (accept_hash_table_, name, SCM_UNDEFINED);
81   if (accept_list == SCM_BOOL_F)
82     {
83       accept_list = find_accept_translators (get_simple_trans_list (),
84                                              m->get_property ("types"));
85       scm_hashq_set_x (accept_hash_table_, name, accept_list);
86     }
87
88   for (SCM p = accept_list; scm_is_pair (p); p = scm_cdr (p))
89     {
90       Translator *t = unsmob_translator (scm_car (p));
91       if (t && t->try_music (m))
92         return true;
93     }
94   return false;
95 }
96
97 SCM
98 Translator_group::get_simple_trans_list ()
99 {
100   return simple_trans_list_;
101 }
102
103 void
104 precomputed_recurse_over_translators (Context *c, Translator_precompute_index idx, Direction dir)
105 {
106   Translator_group *tg
107     = dynamic_cast<Translator_group *> (c->implementation ());
108
109   if (dir == DOWN)
110     {
111       tg->precomputed_translator_foreach (idx);
112       tg->call_precomputed_self_method (idx);
113     }
114
115   for (SCM s = c->children_contexts (); scm_is_pair (s);
116        s = scm_cdr (s))
117     {
118       precomputed_recurse_over_translators (unsmob_context (scm_car (s)), idx, dir);
119     }
120
121   if (dir == UP)
122     {
123       tg->precomputed_translator_foreach (idx);
124       tg->call_precomputed_self_method (idx);
125     }
126 }
127
128 void
129 recurse_over_translators (Context *c, Translator_method ptr, Translator_group_method tg_ptr, Direction dir)
130 {
131   Translator_group *tg
132     = dynamic_cast<Translator_group *> (c->implementation ());
133
134   if (dir == DOWN)
135     {
136       (tg->*tg_ptr) ();
137       translator_each (tg->get_simple_trans_list (), ptr);
138     }
139
140   for (SCM s = c->children_contexts (); scm_is_pair (s);
141        s = scm_cdr (s))
142     {
143       recurse_over_translators (unsmob_context (scm_car (s)), ptr, tg_ptr, dir);
144     }
145
146   if (dir == UP)
147     {
148       translator_each (tg->get_simple_trans_list (),
149                        ptr);
150
151       (tg->*tg_ptr) ();
152     }
153 }
154
155 Translator_group::Translator_group ()
156 {
157   simple_trans_list_ = SCM_EOL;
158   accept_hash_table_ = SCM_EOL;
159   context_ = 0;
160   smobify_self ();
161
162   accept_hash_table_ = scm_c_make_hash_table (19);
163 }
164
165 void
166 Translator_group::derived_mark () const
167 {
168 }
169
170 void
171 Translator_group::precompute_method_bindings ()
172 {
173   for (SCM s = simple_trans_list_; scm_is_pair (s); s = scm_cdr (s))
174     {
175       Translator *tr = unsmob_translator (scm_car (s));
176       Translator_void_method_ptr ptrs[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
177       tr->fetch_precomputable_methods (ptrs);
178
179       assert (tr);
180       for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
181         {
182           if (ptrs[i])
183             precomputed_method_bindings_[i].push (Translator_method_binding (tr, ptrs[i]));
184         }
185     }
186
187   fetch_precomputable_methods (precomputed_self_method_bindings_);
188 }
189
190 void
191 Translator_group::precomputed_translator_foreach (Translator_precompute_index idx)
192 {
193   Array<Translator_method_binding> &bindings (precomputed_method_bindings_[idx]);
194   for (int i = 0; i < bindings.size (); i++)
195     {
196       bindings[i].invoke ();
197     }
198 }
199
200 void
201 Translator_group::fetch_precomputable_methods (Translator_group_void_method ptrs[])
202 {
203   for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
204     ptrs[i] = 0;
205 }
206
207 void
208 Translator_group::call_precomputed_self_method (Translator_precompute_index idx)
209 {
210   if (precomputed_self_method_bindings_[idx])
211     (*precomputed_self_method_bindings_[idx]) (this);
212 }
213
214 Translator_group::~Translator_group ()
215 {
216 }
217
218 #include "ly-smobs.icc"
219
220 IMPLEMENT_SMOBS (Translator_group);
221 IMPLEMENT_DEFAULT_EQUAL_P (Translator_group);
222 IMPLEMENT_TYPE_P (Translator_group, "ly:translator-group?");
223
224 int
225 Translator_group::print_smob (SCM s, SCM port, scm_print_state *)
226 {
227   Translator_group *me = (Translator_group *) SCM_CELL_WORD_1 (s);
228   scm_puts ("#<Translator_group ", port);
229   scm_puts (classname (me), port);
230   scm_display (me->simple_trans_list_, port);
231   scm_puts (" >", port);
232   return 1;
233 }
234
235 SCM
236 Translator_group::mark_smob (SCM smob)
237 {
238   Translator_group *me = (Translator_group *)SCM_CELL_WORD_1 (smob);
239
240   me->derived_mark ();
241   scm_gc_mark (me->accept_hash_table_);
242   return me->simple_trans_list_;
243 }
244