X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Funpure-pure-container.cc;h=ede75022c6d0c148857e19f01f22f1c2687138c5;hb=47db9a3883d726ca53e2133a3b2298f78dd6a32e;hp=9a8639dad09b718db0efcf2c926aeecaa057a175;hpb=f875ef39c544bd3499dae5360e9e24f69933575f;p=lilypond.git diff --git a/lily/unpure-pure-container.cc b/lily/unpure-pure-container.cc index 9a8639dad0..ede75022c6 100644 --- a/lily/unpure-pure-container.cc +++ b/lily/unpure-pure-container.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2011 Mike Solomon + Copyright (C) 2011--2015 Mike Solomon LilyPond is free software: you can redistribute it and/or modify @@ -21,90 +21,68 @@ #include "grob.hh" -static scm_t_bits unpure_pure_container_tag; - -bool -is_unpure_pure_container (SCM s) -{ - return (SCM_NIMP (s) && SCM_CELL_TYPE (s) == unpure_pure_container_tag); -} - -SCM -unpure_pure_container_unpure_part (SCM smob) +// Reroutes a call to the contained function after dropping last two +// arguments. Used for applying an "unpure" function in a "pure" +// context. +class Unpure_pure_call : public Smob1 { - LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1); - return (SCM) SCM_CELL_WORD_1 (smob); -} +public: + LY_DECLARE_SMOB_PROC (2, 0, 1, (SCM self, SCM arg1, SCM arg2, SCM rest)) + { + return scm_apply_0 (Unpure_pure_call::unsmob (self)->scm1 (), + scm_call_2 (ly_lily_module_constant ("drop-right"), + scm_cons2 (arg1, arg2, rest), + scm_from_int (2))); + } +}; SCM -unpure_pure_container_pure_part (SCM smob) +Unpure_pure_container::pure_part () const { - LY_ASSERT_TYPE (is_unpure_pure_container, smob, 1); - return (SCM) SCM_CELL_WORD_2 (smob); + return SCM_UNBNDP (scm2 ()) + ? Unpure_pure_call::make_smob (scm1 ()) + : scm2 (); } -LY_DEFINE (ly_unpure_pure_container_p, "ly:unpure-pure-container?", - 1, 0, 0, (SCM clos), - "Is @var{clos} an unpure pure container?") -{ - return scm_from_bool (is_unpure_pure_container (clos)); -} +const char Unpure_pure_container::type_p_name_[] = "ly:unpure-pure-container?"; LY_DEFINE (ly_make_unpure_pure_container, "ly:make-unpure-pure-container", 1, 1, 0, (SCM unpure, SCM pure), "Make an unpure-pure container. @var{unpure} should be an unpure" - " expression, and @var{pure} should be a pure expression. If @var{pure}" - " is ommitted, the value of @var{unpure} will be used twice.") + " expression, and @var{pure} should be a pure expression. If @var{pure}" + " is omitted, the value of @var{unpure} will be used twice," + " except that a callback is given two extra arguments" + " that are ignored for the sake of pure calculations.") { - SCM z; - - if (pure == SCM_UNDEFINED) - pure = unpure; - - SCM_NEWSMOB2 (z, unpure_pure_container_tag, SCM_UNPACK (unpure), SCM_UNPACK (pure)); - return z; + return Unpure_pure_container::make_smob (unpure, pure); } LY_DEFINE (ly_unpure_pure_container_unpure_part, "ly:unpure-pure-container-unpure-part", 1, 0, 0, (SCM pc), "Return the unpure part of @var{pc}.") { - LY_ASSERT_TYPE (is_unpure_pure_container, pc, 1); - return unpure_pure_container_unpure_part (pc); + LY_ASSERT_SMOB (Unpure_pure_container, pc, 1); + return Unpure_pure_container::unsmob (pc)->unpure_part (); } LY_DEFINE (ly_unpure_pure_container_pure_part, "ly:unpure-pure-container-pure-part", 1, 0, 0, (SCM pc), "Return the pure part of @var{pc}.") { - LY_ASSERT_TYPE (is_unpure_pure_container, pc, 1); - return unpure_pure_container_pure_part (pc); + LY_ASSERT_SMOB (Unpure_pure_container, pc, 1); + return Unpure_pure_container::unsmob (pc)->pure_part (); } int -print_unpure_pure_container (SCM s, SCM port, scm_print_state *) +Unpure_pure_container::print_smob (SCM port, scm_print_state *) { scm_puts ("#", port); return 1; } - -SCM -pure_mark (SCM pure) -{ - scm_gc_mark (unpure_pure_container_unpure_part (pure)); - scm_gc_mark (unpure_pure_container_pure_part (pure)); - return pure; -} - -void init_unpure_pure_container () -{ - unpure_pure_container_tag = scm_make_smob_type ("unpure-pure-container", 0); - scm_set_smob_mark (unpure_pure_container_tag, pure_mark); - scm_set_smob_print (unpure_pure_container_tag, print_unpure_pure_container); -}; - -ADD_SCM_INIT_FUNC (unpure_pure_container, init_unpure_pure_container);