bc5c110325078a989a45d11f64686c09ea64bfec
[mes.git] / module / mes / base-0.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 ;;; base-0.mes is the first file being loaded from the Mes core.  It
24 ;;; provides primitives that use Mes internals to create the illusion
25 ;;; of compatibility with Guile.  It is not safe to be run by Guile.
26
27 ;;; Code:
28
29 #f ;; FIXME -- needed for --dump, then --load
30
31 (define (primitive-eval e) (eval-env e (current-module)))
32 (define eval eval-env)
33 (define (expand-macro e) (expand-macro-env e (current-module)))
34
35 (define quotient /)
36
37 (define-macro (defined? x)
38   (list 'assq x '(cddr (current-module))))
39
40 (if (defined? 'current-input-port) #t
41     (define (current-input-port) 0))
42
43 (define (current-output-port) 1)
44 (define (current-error-port) 2)
45 (define (port-filename port) "<stdin>")
46 (define (port-line port) 0)
47 (define (port-column port) 0)
48 (define (ftell port) 0)
49 (define (false-if-exception x) x)
50
51 (define (cons* x . rest)
52   (define (loop rest)
53     (if (null? (cdr rest)) (car rest)
54         (cons (car rest) (loop (cdr rest)))))
55   (loop (cons x rest)))
56
57 (define (apply f h . t) (apply-env f (cons h t) (current-module)))
58 (define (apply f h . t)
59   (if (null? t) (apply-env f h (current-module))
60       (apply f (apply cons* (cons h t)))))
61
62 (define-macro (cond . clauses)
63   (list 'if (null? clauses) *unspecified*
64         (if (null? (cdr clauses))
65            (list 'if (car (car clauses))
66                  (list (cons 'lambda (cons '() (cons (car (car clauses)) (cdr (car clauses))))))
67                  *unspecified*)
68            (if (eq? (car (cadr clauses)) 'else)
69                (list 'if (car (car clauses))
70                    (list (cons 'lambda (cons '() (car clauses))))
71                    (list (cons 'lambda (cons '() (cons *unspecified* (cdr (cadr clauses)))))))
72                (list 'if (car (car clauses))
73                    (list (cons 'lambda (cons '() (car clauses))))
74                    (cons 'cond (cdr clauses)))))))
75
76 (define else #t)
77
78 (define (map f l . r)
79   (if (null? l) '()
80       (if (null? r) (cons (f (car l)) (map f (cdr l)))
81           (if (null? (cdr r))
82               (cons (f (car l) (caar r)) (map f (cdr l) (cdar r)))))))
83
84 (define-macro (simple-let bindings . rest)
85   (cons (cons 'lambda (cons (map car bindings) rest))
86         (map cadr bindings)))
87
88 (define-macro (let bindings . rest)
89   (cons 'simple-let (cons bindings rest)))
90
91 (define *input-ports* '())
92 (define-macro (push! stack o)
93   (cons
94    'begin
95    (list
96     (list 'set! stack (list cons o stack))
97     stack)))
98 (define-macro (pop! stack)
99   (list 'let (list (list 'o (list car stack)))
100         (list 'set! stack (list cdr stack))
101         'o))
102 (define-macro (load file)
103   (list 'begin
104      (list 'push! '*input-ports* (list current-input-port))
105      (list 'set-current-input-port (list open-input-file file))
106      (list 'primitive-load)
107      (list 'set-current-input-port (list 'pop! '*input-ports*))))
108 (define (memq x lst)
109   (if (null? lst) #f
110       (if (eq? x (car lst)) lst
111           (memq x (cdr lst)))))
112
113 (define (string-join lst infix)
114   (if (null? (cdr lst)) (car lst)
115       (string-append (car lst) infix (string-join (cdr lst) infix))))
116
117 (define *mes-prefix* "module/")
118 (define (module->file o)
119   (string-append (string-join (map symbol->string o) "/") ".mes"))
120
121 (define *modules* '(mes/base-0.mes))
122 (define (mes-load-module-env module a)
123   (push! *input-ports* (current-input-port))
124   (set-current-input-port (open-input-file (string-append *mes-prefix* (module->file module))))
125   (let ((x (eval-env (append (cons 'begin (read-input-file-env #f a))
126                              '((current-module)))
127                      a)))
128     (set-current-input-port (pop! *input-ports*))
129     x))
130 (define (not x)
131   (if x #f #t))
132 (define-macro (mes-use-module module)
133   (list
134    'begin
135    (list 'if (list 'not (list 'memq (list string->symbol (module->file module)) '*modules*))
136          (list
137           'begin
138           (list 'set! '*modules* (list cons (list string->symbol (module->file module)) '*modules*))
139           ;; (list display "loading file=" (list current-error-port))
140           ;; (list display (module->file module) (list current-error-port))
141           ;; (list newline (list current-error-port))
142           (list 'load (list string-append '*mes-prefix* (module->file module)))))))
143
144 (mes-use-module (srfi srfi-0))
145 (mes-use-module (mes base))
146 (mes-use-module (mes scm))