]> git.donarmstrong.com Git - lilypond.git/blob - lily/context.cc
cf5b1616798b74f1ed176bd46a9d22a40ba8c508
[lilypond.git] / lily / context.cc
1 #include "translator-group.hh"
2 #include "context-def.hh"
3 #include "warn.hh"
4 #include "music-output-def.hh"
5 #include "scm-hash.hh"
6 #include "main.hh"
7
8 bool
9 Translator_group::is_removable () const
10 {
11   return trans_group_list_ == SCM_EOL && ! iterator_count_;
12 }
13
14 Translator_group *
15 Translator_group::find_existing_translator (SCM n, String id)
16 {
17   if ((is_alias (n) && (id_string_ == id || id.is_empty ())) || n == ly_symbol2scm ("Current"))
18     return this;
19
20   Translator_group* r = 0;
21   for (SCM p = trans_group_list_; !r && gh_pair_p (p); p = ly_cdr (p))
22     {
23       Translator *  t = unsmob_translator (ly_car (p));
24       
25       r = dynamic_cast<Translator_group*> (t)->find_existing_translator (n, id);    }
26
27   return r;
28 }
29
30
31 Translator_group*
32 Translator_group::find_create_translator (SCM n, String id, SCM operations)
33 {
34   Translator_group * existing = find_existing_translator (n,id);
35   if (existing)
36     return existing;
37
38
39   /*
40     TODO: use accepts_list_.
41    */
42   Link_array<Context_def> path
43     = unsmob_context_def (definition_)->path_to_acceptable_translator (n, get_output_def ());
44
45   if (path.size ())
46     {
47       Translator_group * current = this;
48
49       // start at 1.  The first one (index 0) will be us.
50       for (int i=0; i < path.size (); i++)
51         {
52           SCM ops = (i == path.size () -1) ? operations : SCM_EOL;
53
54           Translator_group * new_group
55             = path[i]->instantiate (ops);
56
57           if (i == path.size () -1)
58             {
59               new_group->id_string_ = id;
60             }
61
62           current->add_fresh_group_translator (new_group);
63           apply_property_operations (new_group, ops);
64           
65           current = new_group;
66         }
67
68       return current;
69     }
70
71   Translator_group *ret = 0;
72   if (daddy_trans_)
73     ret = daddy_trans_->find_create_translator (n, id, operations);
74   else
75     {
76       warning (_f ("Cannot find or create `%s' called `%s'",
77                    ly_symbol2string (n).to_str0 (), id));
78       ret =0;
79     }
80   return ret;
81 }
82
83 /*
84   Default child context as a SCM string, or something else if there is
85   none.
86 */
87 SCM
88 default_child_context_name (Translator_group const *tg)
89 {
90   return gh_pair_p (tg->accepts_list_)
91     ? ly_car (scm_last_pair (tg->accepts_list_))
92     : SCM_EOL;
93 }
94
95
96 bool
97 Translator_group::is_bottom_context () const
98 {
99   return !gh_symbol_p (default_child_context_name (this));
100 }
101
102 Translator_group*
103 Translator_group::get_default_interpreter ()
104 {
105   if (!is_bottom_context ())
106     {
107       SCM nm = default_child_context_name (this);
108       SCM st = get_output_def ()->find_translator (nm);
109
110       Context_def *t = unsmob_context_def (st);
111       if (!t)
112         {
113           warning (_f ("can't find or create: `%s'", ly_symbol2string (nm).to_str0 ()));
114           t = unsmob_context_def (this->definition_);
115         }
116       Translator_group *tg = t->instantiate (SCM_EOL);
117       add_fresh_group_translator (tg);
118       if (!tg->is_bottom_context ())
119         return tg->get_default_interpreter ();
120       else
121         return tg;
122     }
123   return this;
124 }
125
126 /*
127   PROPERTIES
128  */
129 Translator_group*
130 Translator_group::where_defined (SCM sym) const
131 {
132   if (properties_dict ()->contains (sym))
133     {
134       return (Translator_group*)this;
135     }
136
137   return (daddy_trans_) ? daddy_trans_->where_defined (sym) : 0;
138 }
139
140 /*
141   return SCM_EOL when not found.
142 */
143 SCM
144 Translator_group::internal_get_property (SCM sym) const
145 {
146   SCM val =SCM_EOL;
147   if (properties_dict ()->try_retrieve (sym, &val))
148     return val;
149
150   if (daddy_trans_)
151     return daddy_trans_->internal_get_property (sym);
152   
153   return val;
154 }
155
156 void
157 Translator_group::internal_set_property (SCM sym, SCM val)
158 {
159 #ifndef NDEBUG
160   if (internal_type_checking_global_b)
161     assert (type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")));
162 #endif
163   
164   properties_dict ()->set (sym, val);
165 }
166
167 /*
168   TODO: look up to check whether we have inherited var? 
169  */
170 void
171 Translator_group::unset_property (SCM sym)
172 {
173   properties_dict ()->remove (sym);
174 }
175