add scheme apply, rename apply-> apply_env.
[mes.git] / scm.mes
1 ;;; -*-scheme-*-
2
3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
5 ;;;
6 ;;; scm.mes: 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 ;; The Maxwell Equations of Software -- John McCarthy page 13
22 ;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
23
24 (define (defined? x)
25   (assq x (current-module)))
26
27 (define (procedure? p)
28   (cond ((builtin? p) #t)
29         ((pair? p) (eq? (car p) 'lambda))
30         (#t #f)))
31
32 (define (list . rest) rest)
33 (define (vector . rest) (list->vector rest))
34 (define assv assq)
35 (define (memq x lst)
36   (cond ((null? lst) #f)
37         ((eq? x (car lst)) lst)
38         (#t (memq x (cdr lst)))))
39 (define memv memq)
40
41 (define-macro (and x y)
42   (cond (x y)
43         (#t #f)))
44
45 (define-macro (or x y)
46   (cond (x x)
47         (#t y)))
48
49 (define (split-params bindings params)
50   (cond ((null? bindings) params)
51         (#t (split-params (cdr bindings)
52                           (append params (cons (caar bindings) '()))))))
53
54 (define (split-values bindings values)
55   (cond ((null? bindings) values)
56         (#t (split-values (cdr bindings)
57                           (append values (cdar bindings) '())))))
58
59 (define-macro (let bindings . body)
60   (cons (cons 'lambda (cons (split-params bindings '()) body))
61         (split-values bindings '())))
62
63 (define (expand-let* bindings body)
64   (cond ((null? bindings)
65          (cons (cons 'lambda (cons '() body)) '()))
66         (#t
67          (cons
68           (cons 'lambda (cons (cons (caar bindings) '())
69                               (cons (expand-let* (cdr bindings) body) '())))
70           (cdar bindings)))))
71
72 (define-macro (let* bindings . body)
73   (expand-let* bindings body))
74
75 (define (map f l . r)
76   (cond ((null? l) '())
77         ((null? r) (cons (f (car l)) (map f (cdr l))))
78         ((null? (cdr r))
79          (cons (f (car l) (caar r)) (map f (cdr l) (cdar r))))))
80
81 (define (not x)
82   (cond (x #f)
83         (#t #t)))
84
85 (define-macro (if expr then . else)
86   (cond ((not (eq? (c:eval expr (current-module)) #f))
87          then)
88         (#t
89          (cond ((pair? else) (car else))
90                (#t *unspecified*)))))
91
92 (define (unspecified-bindings bindings params)
93   (cond ((null? bindings) params)
94         (#t (unspecified-bindings
95              (cdr bindings)
96              (append params (cons (cons (caar bindings) '(*unspecified*)) '()))))))
97
98 (define (letrec-setters bindings setters)
99   (cond ((null? bindings) setters)
100         (#t (letrec-setters (cdr bindings)
101                             (append setters
102                                     (cons (cons 'set! (car bindings)) '()))))))
103
104 (define-macro (letrec bindings . body)
105   (cons 'let (cons (unspecified-bindings bindings '())
106                     (append (letrec-setters bindings '())
107                             body)))  )
108
109 (define (begin . rest)
110   (let () rest))
111
112 (define (apply f args)
113   (c:eval (cons f args) (current-module)))