]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.85
authorfred <fred>
Fri, 8 Sep 2000 14:10:20 +0000 (14:10 +0000)
committerfred <fred>
Fri, 8 Sep 2000 14:10:20 +0000 (14:10 +0000)
lily/translator-def.cc [new file with mode: 0644]

diff --git a/lily/translator-def.cc b/lily/translator-def.cc
new file mode 100644 (file)
index 0000000..558d078
--- /dev/null
@@ -0,0 +1,292 @@
+/*   
+  translator-def.cc --  implement Translator_def
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  
+ */
+
+#include "lily-proto.hh"
+#include "translator-def.hh"
+#include "translator-group.hh"
+#include "warn.hh"
+#include "music-output-def.hh"
+
+#include "ly-smobs.icc"
+
+int
+Translator_def::print_smob (SCM smob, SCM port, scm_print_state*)
+{
+  Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
+
+  scm_puts("#<Translator_def ", port);
+  scm_display (me->type_name_, port);
+  scm_puts (">", port);
+  return 1;
+}
+
+
+SCM
+Translator_def::mark_smob (SCM smob)
+{
+  Translator_def* me = (Translator_def*) SCM_CELL_WORD_1 (smob);
+  scm_gc_mark (me->consists_name_list_);
+  scm_gc_mark (me->accepts_name_list_);
+  scm_gc_mark (me->end_consists_name_list_);
+  scm_gc_mark (me->property_ops_);  
+  scm_gc_mark (me->translator_group_type_);
+  return me->type_name_;
+}
+
+SCM push_sym;
+SCM assign_sym;
+
+static void
+foo_init ()
+{
+  push_sym = scm_permanent_object (ly_symbol2scm ("push"));
+  assign_sym = scm_permanent_object (ly_symbol2scm ("assign"));
+}
+
+ADD_SCM_INIT_FUNC(transdef, foo_init);
+
+Translator_def::Translator_def ()
+{
+  translator_group_type_ = SCM_EOL;
+  accepts_name_list_ = SCM_EOL;   
+  consists_name_list_ = SCM_EOL;
+  end_consists_name_list_ = SCM_EOL;
+  property_ops_ = SCM_EOL;
+  type_name_ = SCM_EOL;
+}
+Translator_def::~Translator_def ()
+{
+}
+
+Translator_def::Translator_def (Translator_def const & s)
+  : Input (s)
+{
+  consists_name_list_ = scm_list_copy (s.consists_name_list_);
+  end_consists_name_list_ = scm_list_copy (s.end_consists_name_list_);
+  accepts_name_list_ = scm_list_copy (s.accepts_name_list_);
+  property_ops_ = scm_list_copy (s.property_ops_);
+
+  translator_group_type_ = s.translator_group_type_;
+  type_name_ = s.type_name_;
+}
+
+
+
+void
+Translator_def::set_acceptor (SCM name, bool add)
+{
+  if (add)
+    this->accepts_name_list_ = gh_append2 (this->accepts_name_list_, gh_cons (name, SCM_EOL));
+  else
+    this->accepts_name_list_ = scm_delete_x (name, this->accepts_name_list_);
+}
+
+
+SCM
+Translator_def::modify_definition (SCM list, SCM str, bool add)
+{
+  String s = ly_scm2string (str);
+  if (!get_translator_l (s))
+    error (_ ("Program has no such type"));
+
+  if (add)
+    {
+      if (scm_memq (str, list) != SCM_BOOL_F)
+       {
+         warning (_f("Already contains: `%s'", s));
+         warning (_f("Not adding translator: `%s'", s));
+       }
+      else
+       list= gh_cons (str, list);
+    }
+  else
+    {
+      list = scm_delete_x (str, list);
+    }
+  return list;
+}
+
+
+
+void
+Translator_def::remove_element (SCM s)
+{
+  this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, false);
+  this->consists_name_list_ = modify_definition (this->consists_name_list_, s, false);
+}
+
+void
+Translator_def::add_element (SCM s)
+{
+  this->consists_name_list_ = modify_definition (this->consists_name_list_, s, true);
+}
+
+void
+Translator_def::add_last_element (SCM s)
+{
+  this->end_consists_name_list_ = modify_definition (this->end_consists_name_list_, s, true);
+}
+void
+Translator_def::add_push_property (SCM props, SCM syms,  SCM vals)
+{
+  this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, vals, SCM_UNDEFINED),
+                                   this->property_ops_);
+}
+
+void
+Translator_def::add_pop_property (SCM props, SCM syms)
+{
+  this->property_ops_ = gh_cons (gh_list (push_sym, props, syms, SCM_UNDEFINED),
+                                 this->property_ops_);
+}
+
+/*
+  Do it. SYMS maybe a symbol or a list of symbols. VAL is
+  SCM_UNDEFINED in case of a pop
+*/
+void
+Translator_def::apply_pushpop_property (Translator_group* me,SCM syms, SCM eprop, SCM val)
+{
+  if (gh_symbol_p (syms))
+    dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (syms, eprop, val);
+  else for (SCM s = syms; gh_pair_p (s); s = gh_cdr (s))
+    dynamic_cast<Translator_group*>(me)->execute_single_pushpop_property (gh_car (s), eprop, val);
+}
+
+
+
+Link_array<Translator_def>
+Translator_def::path_to_acceptable_translator (SCM type_str, Music_output_def* odef) const
+{
+  assert (gh_string_p (type_str));
+  
+  Link_array<Translator_def> accepted_arr;
+  for (SCM s = accepts_name_list_; gh_pair_p (s); s = gh_cdr (s))
+    {
+      Translator_def *t = unsmob_translator_def (odef->find_translator_l (gh_car (s)));
+      if (!t)
+       continue;
+      accepted_arr.push (t);
+    }
+
+
+  Link_array<Translator_def> best_result;
+  for (int i=0; i < accepted_arr.size (); i++)
+    if (scm_equal_p (accepted_arr[i]->type_name_, type_str) == SCM_BOOL_T)
+      {
+       best_result.push (accepted_arr[i]);
+       return best_result;
+      }
+
+  int best_depth= INT_MAX;
+  for (int i=0; i < accepted_arr.size (); i++)
+    {
+      Translator_def * g = accepted_arr[i];
+
+      Link_array<Translator_def> result
+       = g->path_to_acceptable_translator (type_str, odef);
+      if (result.size () && result.size () < best_depth)
+       {
+         result.insert (g,0);
+         best_result = result;
+       }
+    }
+
+  return best_result;
+}
+IMPLEMENT_UNSMOB(Translator_def,translator_def);
+IMPLEMENT_SMOBS(Translator_def);
+IMPLEMENT_DEFAULT_EQUAL_P(Translator_def);
+
+
+static SCM
+trans_list (SCM namelist, Translator_group*tg)
+{
+  SCM l = SCM_EOL;
+  for (SCM s = namelist; gh_pair_p (s) ; s = gh_cdr (s))
+    {
+      Translator * t = get_translator_l (ly_scm2string (gh_car (s)));
+      if (!t)
+       warning (_f ("can't find: `%s'", s));
+      else
+       {
+         Translator * tr = t->clone ();
+         SCM str = tr->self_scm ();
+         l = gh_cons (str, l);
+
+         tr->daddy_trans_l_ = tg;
+         tr->output_def_l_  = tg->output_def_l_;
+
+         scm_unprotect_object (str);
+       }
+    }
+  return l; 
+}
+
+
+Translator_group *
+Translator_def::instantiate (Music_output_def* md)
+{
+  Translator * g = get_translator_l (ly_scm2string (translator_group_type_));
+  g = g->clone (); 
+
+  Translator_group *tg = dynamic_cast<Translator_group*> (g);
+  tg->output_def_l_ = md;
+  tg->definition_ = self_scm ();
+  tg->type_str_ = ly_scm2string (type_name_);
+  SCM correct_order = scm_reverse (property_ops_); // pity of the mem.
+  for (SCM s = correct_order; gh_pair_p (s); s = gh_cdr (s))
+    {
+      SCM entry = gh_car (s);
+      SCM type = gh_car (entry);
+      entry = gh_cdr (entry); 
+      
+      if (type == push_sym)
+       {
+         SCM val = gh_cddr (entry);
+         val = gh_pair_p (val) ? gh_car (val) : SCM_UNDEFINED;
+
+         apply_pushpop_property (tg, gh_car (entry), gh_cadr (entry), val);
+       }
+      else if (type == assign_sym)
+       {
+         tg->set_property (gh_car(entry), gh_cadr (entry));
+       }
+    }
+
+  SCM l1 = trans_list (consists_name_list_, tg);
+  SCM l2 =trans_list (end_consists_name_list_,tg);
+  l1 = scm_reverse_x (l1, l2);
+  
+  tg->simple_trans_list_ = l1;
+  
+  return tg;
+}
+
+SCM
+Translator_def::clone_scm () const
+{
+  Translator_def * t = new Translator_def (*this);
+  return t->unprotected_smobify_self ();
+}
+
+SCM
+Translator_def::make_scm ()
+{
+  Translator_def* t = new Translator_def;
+  return t->unprotected_smobify_self ();
+}
+
+void
+Translator_def::add_property_assign (SCM nm, SCM val)
+{
+  this->property_ops_ = gh_cons (gh_list (assign_sym, scm_string_to_symbol (nm), val, SCM_UNDEFINED),
+                                this->property_ops_);
+}
+