]> git.donarmstrong.com Git - lilypond.git/blob - lily/moment-scheme.cc
Issue 4841: Let Scheme_hash_table::get return SCM_UNDEFINED for unknown keys
[lilypond.git] / lily / moment-scheme.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
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
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
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/>.
18 */
19
20 #include "moment.hh"
21
22 /* TODO: add optional factor argument. */
23 LY_DEFINE (ly_make_moment, "ly:make-moment",
24            1, 3, 0, (SCM m, SCM g, SCM gn, SCM gd),
25            "Create the moment with rational main timing @var{m},"
26            " and optional grace timing @var{g}.\n"
27            "\n"
28            "A @dfn{moment} is a point in musical time.  It consists of"
29            " a pair of rationals (@var{m},@tie{}@var{g}), where @var{m} is"
30            " the timing for the main notes, and @var{g} the timing for"
31            " grace notes.  In absence of grace notes, @var{g}@tie{}is zero.\n"
32            "\n"
33            "For compatibility reasons, it is possible to write two"
34            " numbers specifying numerator and denominator instead of"
35            " the rationals.  These forms cannot be mixed, and the two-"
36            "argument form is disambiguated by the sign of the second"
37            " argument: if it is positive, it can only be a denominator"
38            " and not a grace timing."
39           )
40 {
41   LY_ASSERT_TYPE (ly_is_rational, m, 1);
42   if (SCM_UNBNDP (g))
43     return Moment (ly_scm2rational (m)).smobbed_copy ();
44
45   if (SCM_UNBNDP (gn))
46     {
47       LY_ASSERT_TYPE (ly_is_rational, g, 2);
48       if (scm_is_true (scm_positive_p (g)))
49         {
50           LY_ASSERT_TYPE (scm_is_integer, m, 1);
51           LY_ASSERT_TYPE (scm_is_integer, g, 2);
52           return Moment (Rational (scm_to_int64 (m),
53                                    scm_to_int64 (g))).smobbed_copy ();
54         }
55       return Moment (ly_scm2rational (m),
56                      ly_scm2rational (g)).smobbed_copy ();
57     }
58
59   LY_ASSERT_TYPE (scm_is_integer, m, 1);
60   LY_ASSERT_TYPE (scm_is_integer, g, 2);
61   LY_ASSERT_TYPE (scm_is_integer, gn, 3);
62   I64 grace_num = scm_to_int64 (gn);
63   I64 grace_den = 1;
64   if (!SCM_UNBNDP (gd))
65     {
66       LY_ASSERT_TYPE (scm_is_integer, gd, 4);
67       grace_den = scm_to_int64 (gd);
68     }
69
70   return Moment (Rational (scm_to_int64 (m), scm_to_int64 (g)),
71                  Rational (grace_num, grace_den)).smobbed_copy ();
72 }
73
74 LY_DEFINE (ly_moment_sub, "ly:moment-sub",
75            2, 0, 0, (SCM a, SCM b),
76            "Subtract two moments.")
77 {
78   LY_ASSERT_SMOB (Moment, a, 1);
79   LY_ASSERT_SMOB (Moment, b, 2);
80
81   Moment *ma = unsmob<Moment> (a);
82   Moment *mb = unsmob<Moment> (b);
83
84   return (*ma - *mb).smobbed_copy ();
85 }
86
87 LY_DEFINE (ly_moment_add, "ly:moment-add",
88            2, 0, 0, (SCM a, SCM b),
89            "Add two moments.")
90 {
91   LY_ASSERT_SMOB (Moment, a, 1);
92   LY_ASSERT_SMOB (Moment, b, 2);
93
94   Moment *ma = unsmob<Moment> (a);
95   Moment *mb = unsmob<Moment> (b);
96
97   return (*ma + *mb).smobbed_copy ();
98 }
99
100 LY_DEFINE (ly_moment_mul, "ly:moment-mul",
101            2, 0, 0, (SCM a, SCM b),
102            "Multiply two moments.")
103 {
104   LY_ASSERT_SMOB (Moment, a, 1);
105   LY_ASSERT_SMOB (Moment, b, 2);
106
107   Moment *ma = unsmob<Moment> (a);
108   Moment *mb = unsmob<Moment> (b);
109   return (*ma * * mb).smobbed_copy ();
110 }
111
112 LY_DEFINE (ly_moment_div, "ly:moment-div",
113            2, 0, 0, (SCM a, SCM b),
114            "Divide two moments.")
115 {
116   LY_ASSERT_SMOB (Moment, a, 1);
117   LY_ASSERT_SMOB (Moment, b, 2);
118
119   Moment *ma = unsmob<Moment> (a);
120   Moment *mb = unsmob<Moment> (b);
121
122   return (*ma / * mb).smobbed_copy ();
123 }
124
125 LY_DEFINE (ly_moment_mod, "ly:moment-mod",
126            2, 0, 0, (SCM a, SCM b),
127            "Modulo of two moments.")
128 {
129   LY_ASSERT_SMOB (Moment, a, 1);
130   LY_ASSERT_SMOB (Moment, b, 2);
131
132   Moment *ma = unsmob<Moment> (a);
133   Moment *mb = unsmob<Moment> (b);
134   return (*ma % * mb).smobbed_copy ();
135 }
136
137 LY_DEFINE (ly_moment_grace, "ly:moment-grace",
138            1, 0, 0, (SCM mom),
139            "Extract grace timing as a rational number from @var{mom}.")
140 {
141   LY_ASSERT_SMOB (Moment, mom, 1);
142
143   return ly_rational2scm (unsmob<Moment> (mom)->grace_part_);
144 }
145
146 LY_DEFINE (ly_moment_grace_numerator, "ly:moment-grace-numerator",
147            1, 0, 0, (SCM mom),
148            "Extract numerator from grace timing.")
149 {
150   LY_ASSERT_SMOB (Moment, mom, 1);
151
152   Moment *ma = unsmob<Moment> (mom);
153
154   return scm_from_int64 (ma->grace_part_.numerator ());
155 }
156
157 LY_DEFINE (ly_moment_grace_denominator, "ly:moment-grace-denominator",
158            1, 0, 0, (SCM mom),
159            "Extract denominator from grace timing.")
160 {
161   LY_ASSERT_SMOB (Moment, mom, 1);
162   Moment *ma = unsmob<Moment> (mom);
163
164   return scm_from_int64 (ma->grace_part_.denominator ());
165 }
166
167 LY_DEFINE (ly_moment_main, "ly:moment-main",
168            1, 0, 0, (SCM mom),
169            "Extract main timing as a rational number from @var{mom}.")
170 {
171   LY_ASSERT_SMOB (Moment, mom, 1);
172
173   return ly_rational2scm (unsmob<Moment> (mom)->main_part_);
174 }
175
176 LY_DEFINE (ly_moment_main_numerator, "ly:moment-main-numerator",
177            1, 0, 0, (SCM mom),
178            "Extract numerator from main timing.")
179 {
180   LY_ASSERT_SMOB (Moment, mom, 1);
181   Moment *ma = unsmob<Moment> (mom);
182
183   return scm_from_int64 (ma->main_part_.numerator ());
184 }
185
186 LY_DEFINE (ly_moment_main_denominator, "ly:moment-main-denominator",
187            1, 0, 0, (SCM mom),
188            "Extract denominator from main timing.")
189 {
190   LY_ASSERT_SMOB (Moment, mom, 1);
191   Moment *ma = unsmob<Moment> (mom);
192
193   return scm_from_int64 (ma->main_part_.denominator ());
194 }
195
196 LY_DEFINE (ly_moment_less_p, "ly:moment<?",
197            2, 0, 0, (SCM a, SCM b),
198            "Compare two moments.")
199 {
200   LY_ASSERT_SMOB (Moment, a, 1);
201   LY_ASSERT_SMOB (Moment, b, 2);
202
203   Moment *ma = unsmob<Moment> (a);
204   Moment *mb = unsmob<Moment> (b);
205
206   return ly_bool2scm (*ma < *mb);
207 }
208