]> git.donarmstrong.com Git - lilypond.git/blob - lily/unpure-pure-container.cc
Implements unpure-pure-containers in LilyPond.
[lilypond.git] / lily / unpure-pure-container.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2011 Mike Solomon <mike@apollinemike.com>
5
6
7   LilyPond is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   LilyPond is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 #include "unpure-pure-container.hh"
21
22 #include "grob.hh"
23
24 static scm_t_bits unpure_pure_container_tag;
25
26 bool
27 is_unpure_pure_container (SCM s)
28 {
29   return (SCM_NIMP (s) && SCM_CELL_TYPE (s) == unpure_pure_container_tag);
30 }
31
32 SCM
33 unpure_pure_container_unpure_part (SCM smob)
34 {
35   LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1);
36   return (SCM) SCM_CELL_WORD_1 (smob);
37 }
38
39 SCM
40 unpure_pure_container_pure_part (SCM smob)
41 {
42   LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1);
43   return (SCM) SCM_CELL_WORD_2 (smob);
44 }
45
46 LY_DEFINE (ly_unpure_pure_container_p, "ly:unpure-pure-container?",
47            1, 0, 0, (SCM clos),
48            "Is @var{clos} an unpure pure container?")
49 {
50   return scm_from_bool (is_unpure_pure_container (clos));
51 }
52
53 LY_DEFINE (ly_make_unpure_pure_container, "ly:make-unpure-pure-container",
54            1, 1, 0, (SCM unpure, SCM pure),
55            "Make an unpure-pure container.  @var{unpure} should be an unpure"
56            " expression, and @var{pure} should be a pure expression. If @var{pure}"
57            " is ommitted, the value of @var{unpure} will be used twice.")
58 {
59   SCM z;
60
61   if (pure == SCM_UNDEFINED)
62     pure = unpure;
63
64   SCM_NEWSMOB2 (z, unpure_pure_container_tag, SCM_UNPACK (unpure), SCM_UNPACK (pure));
65   return z;
66 }
67
68 LY_DEFINE (ly_unpure_pure_container_unpure_part, "ly:unpure-pure-container-unpure-part",
69            1, 0, 0, (SCM pc),
70            "Return the unpure part of @var{pc}.")
71 {
72   LY_ASSERT_TYPE (is_unpure_pure_container, pc, 1);
73   return unpure_pure_container_unpure_part (pc);
74 }
75
76 LY_DEFINE (ly_unpure_pure_container_pure_part, "ly:unpure-pure-container-pure-part",
77            1, 0, 0, (SCM pc),
78            "Return the pure part of @var{pc}.")
79 {
80   LY_ASSERT_TYPE (is_unpure_pure_container, pc, 1);
81   return unpure_pure_container_pure_part (pc);
82 }
83
84 int
85 print_unpure_pure_container (SCM s, SCM port, scm_print_state *)
86 {
87   scm_puts ("#<unpure-pure-container ", port);
88   scm_display (unpure_pure_container_unpure_part (s), port);
89   scm_puts (" ", port);
90   scm_display (unpure_pure_container_pure_part (s), port);
91   scm_puts (" >", port);
92   return 1;
93 }
94
95 SCM
96 pure_mark (SCM pure)
97 {
98   scm_gc_mark (unpure_pure_container_unpure_part (pure));
99   scm_gc_mark (unpure_pure_container_pure_part (pure));
100   return pure;
101 }
102
103 void init_unpure_pure_container ()
104 {
105   unpure_pure_container_tag = scm_make_smob_type ("unpure-pure-container", 0);
106   scm_set_smob_mark (unpure_pure_container_tag, pure_mark);
107   scm_set_smob_print (unpure_pure_container_tag, print_unpure_pure_container);
108 };
109
110 ADD_SCM_INIT_FUNC (unpure_pure_container, init_unpure_pure_container);