Minimal syntactic fluids support.
[mes.git] / module / mes / fluids.mes
1 ;;; -*-scheme-*-
2
3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
5 ;;;
6 ;;; This file is part of Mes.
7 ;;;
8 ;;; Mes is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; Mes is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with Mes.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;;; Code:
24
25 (mes-use-module (mes scm))
26
27 (define (env:define a+ a)
28   (set-cdr! a+ (cdr a))
29   (set-cdr! a a+)
30   ;;(set-cdr! (assq '*closure* a) a+)
31   )
32
33 (define (env:escape-closure a)
34   (let loop ((a a) (n 1))
35     (if (eq? (caar a) '*closure*) (if (= 0 n) a
36                                       (loop (cdr a) (- n 1)))
37         (loop (cdr a) n))))
38
39 (define (sexp:define e a)
40   (if (atom? (cadr e)) (cons (cadr e) (eval-env (caddr e) a))
41       (cons (caadr e) (eval-env (cons 'lambda (cons (cdadr e) (cddr e))) a))))
42
43 (define-macro (module-define! name value a)
44   `(env:define (cons (sexp:define (cons 'define (cons ',name (cons ,value '()))) ,a) '()) (env:escape-closure ,a)))
45
46 (define-macro (make-fluid . default)
47   `(begin
48      ,(let ((fluid (symbol-append 'fluid: (gensym)))
49             (module (current-module)))
50         `(begin
51            (module-define! ,fluid
52                            (let ((v ,(and (pair? default) (car default))))
53                              (lambda ( . rest)
54                                (if (null? rest) v
55                                    (set! v (car rest))))) ',module)
56            ',fluid))))
57
58 (define (fluid-ref fluid)
59   (fluid))
60
61 (define (fluid-set! fluid value)
62   (fluid value))
63
64 (define-macro (fluid? fluid)
65   `(begin
66      (and (symbol? ,fluid)
67           (symbol-prefix? 'fluid: ,fluid))))
68
69 (define (with-fluid* fluid value thunk)
70   (let ((v (fluid)))
71     (fluid-set! fluid value)
72     (let ((r (thunk)))
73       (fluid-set! fluid v)
74       r)))
75
76 ;; (define-macro (with-fluids*-macro fluids values thunk)
77 ;;   `(begin
78 ;;      ,@(map (lambda (f v) (list 'set! f v)) fluids values)
79 ;;      (,thunk)))
80
81 ;; (define (with-fluids*-next fluids values thunk)
82 ;;   `(with-fluids*-macro ,fluids ,values ,thunk))
83
84 ;; (define (with-fluids* fluids values thunk)
85 ;;   (primitive-eval (with-fluids*-next fluids values thunk)))
86
87 ;; (define-macro (with-fluids bindings . bodies)
88 ;;   `(let ()
89 ;;     (define (expand bindings a)
90 ;;       (if (null? bindings)
91 ;;           (cons (car bindings) (expand (cdr bindings) a))))
92 ;;     (eval-env (begin ,@bodies) (expand ',bindings (current-module)))))
93
94 (define (dynamic-wind in-guard thunk out-guard)
95   (in-guard)
96   (let ((r (thunk)))
97     (out-guard)
98     r))