promises.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* Copyright 1995-2011,2018
  2. Free Software Foundation, Inc.
  3. This file is part of Guile.
  4. Guile is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Lesser General Public License as published
  6. by the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Guile is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with Guile. If not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #ifdef HAVE_CONFIG_H
  16. # include <config.h>
  17. #endif
  18. #include <alloca.h>
  19. #include "alist.h"
  20. #include "async.h"
  21. #include "continuations.h"
  22. #include "debug.h"
  23. #include "deprecation.h"
  24. #include "dynwind.h"
  25. #include "eq.h"
  26. #include "eval.h"
  27. #include "feature.h"
  28. #include "fluids.h"
  29. #include "goops.h"
  30. #include "gsubr.h"
  31. #include "hash.h"
  32. #include "hashtab.h"
  33. #include "list.h"
  34. #include "macros.h"
  35. #include "memoize.h"
  36. #include "modules.h"
  37. #include "ports.h"
  38. #include "print.h"
  39. #include "procprop.h"
  40. #include "procs.h"
  41. #include "programs.h"
  42. #include "smob.h"
  43. #include "srcprop.h"
  44. #include "stackchk.h"
  45. #include "strings.h"
  46. #include "threads.h"
  47. #include "throw.h"
  48. #include "values.h"
  49. #include "promises.h"
  50. scm_t_bits scm_tc16_promise;
  51. SCM_DEFINE (scm_make_promise, "make-promise", 1, 0, 0,
  52. (SCM thunk),
  53. "Create a new promise object.\n\n"
  54. "@code{make-promise} is a procedural form of @code{delay}.\n"
  55. "These two expressions are equivalent:\n"
  56. "@lisp\n"
  57. "(delay @var{exp})\n"
  58. "(make-promise (lambda () @var{exp}))\n"
  59. "@end lisp\n")
  60. #define FUNC_NAME s_scm_make_promise
  61. {
  62. SCM_VALIDATE_THUNK (1, thunk);
  63. SCM_RETURN_NEWSMOB2 (scm_tc16_promise,
  64. SCM_UNPACK (thunk),
  65. SCM_UNPACK (scm_make_recursive_mutex ()));
  66. }
  67. #undef FUNC_NAME
  68. static int
  69. promise_print (SCM exp, SCM port, scm_print_state *pstate)
  70. {
  71. int writingp = SCM_WRITINGP (pstate);
  72. scm_puts ("#<promise ", port);
  73. SCM_SET_WRITINGP (pstate, 1);
  74. scm_iprin1 (SCM_PROMISE_DATA (exp), port, pstate);
  75. SCM_SET_WRITINGP (pstate, writingp);
  76. scm_putc ('>', port);
  77. return !0;
  78. }
  79. SCM_DEFINE (scm_force, "force", 1, 0, 0,
  80. (SCM promise),
  81. "If @var{promise} has not been computed yet, compute and\n"
  82. "return @var{promise}, otherwise just return the previously computed\n"
  83. "value.")
  84. #define FUNC_NAME s_scm_force
  85. {
  86. SCM_VALIDATE_SMOB (1, promise, promise);
  87. scm_lock_mutex (SCM_PROMISE_MUTEX (promise));
  88. if (!SCM_PROMISE_COMPUTED_P (promise))
  89. {
  90. SCM ans = scm_call_0 (SCM_PROMISE_DATA (promise));
  91. if (!SCM_PROMISE_COMPUTED_P (promise))
  92. {
  93. SCM_SET_PROMISE_DATA (promise, ans);
  94. SCM_SET_PROMISE_COMPUTED (promise);
  95. }
  96. }
  97. scm_unlock_mutex (SCM_PROMISE_MUTEX (promise));
  98. return SCM_PROMISE_DATA (promise);
  99. }
  100. #undef FUNC_NAME
  101. SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
  102. (SCM obj),
  103. "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
  104. "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
  105. #define FUNC_NAME s_scm_promise_p
  106. {
  107. return scm_from_bool (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
  108. }
  109. #undef FUNC_NAME
  110. void
  111. scm_init_promises ()
  112. {
  113. scm_tc16_promise = scm_make_smob_type ("promise", 0);
  114. scm_set_smob_print (scm_tc16_promise, promise_print);
  115. #include "promises.x"
  116. scm_add_feature ("delay");
  117. }