78a525fd76c1fde41a99ee62e8582961705eb53d
[mes.git] / module / mes / base-0.mes
1 ;;; -*-scheme-*-
2
3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016,2017 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 (define (effective-version) %version)
30 (define mes? #t)
31 (define guile? #f)
32 (define guile-1.8? #f)
33 (define guile-2? #f)
34
35 (define (primitive-eval e) (core:eval e (current-module)))
36 (define eval core:eval)
37
38 (define (caar x) (car (car x)))
39 (define (cadr x) (car (cdr x)))
40 (define (cdar x) (cdr (car x)))
41 (define (cddr x) (cdr (cdr x)))
42
43 (define-macro (defined? x)
44   (list 'assq x '(cddr (current-module))))
45
46 (if (defined? 'current-input-port) #t
47     (define (current-input-port) 0))
48
49 (define (current-output-port) 1)
50 (define (current-error-port) 2)
51 (define (port-filename port) "<stdin>")
52 (define (port-line port) 0)
53 (define (port-column port) 0)
54 (define (ftell port) 0)
55 (define (false-if-exception x) x)
56
57 (define (cons* . rest)
58   (if (null? (cdr rest)) (car rest)
59       (cons (car rest) (core:apply cons* (cdr rest) (current-module)))))
60
61 (define (apply f h . t) (apply-env f (cons h t) (current-module)))
62 (define (apply f h . t)
63   (if (null? t) (core:apply f h (current-module))
64       (apply f (apply cons* (cons h t)))))
65
66 (define-macro (cond . clauses)
67   (list 'if (pair? clauses)
68         (list (cons
69                'lambda
70                (cons
71                 '(test)
72                 (list (list 'if 'test
73                             (if (pair? (cdar clauses))
74                                 (if (eq? (cadar clauses) '=>)
75                                     (append2 (cddar clauses) '(test))
76                                     (list (cons 'lambda (cons '() (car clauses)))))
77                                 (list (cons 'lambda (cons '() (car clauses)))))
78                             (if (pair? (cdr clauses))
79                                 (cons 'cond (cdr clauses)))))))
80               (car (car clauses)))))
81
82 (define else #t)
83
84 (define-macro (simple-let bindings . rest)
85   (cons (cons 'lambda (cons (map1 car bindings) rest))
86         (map1 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 'if (list getenv "MES_DEBUG")
105               (list 'begin
106                     (list core:display-error "read ")
107                     (list core:display-error file)
108                     (list core:display-error "\n")))
109      (list 'push! '*input-ports* (list current-input-port))
110      (list 'set-current-input-port (list open-input-file file))
111      (list 'primitive-load)
112      (list 'set-current-input-port (list 'pop! '*input-ports*))))
113
114 (define include load)
115 (define-macro (include-from-path file)
116   (list 'load (list string-append "module/" file)))
117
118 (include "module/mes/type-0.mes")
119
120 (define (memq x lst)
121   (if (null? lst) #f
122       (if (eq? x (car lst)) lst
123           (memq x (cdr lst)))))
124
125 (define (string-join lst infix)
126   (if (null? (cdr lst)) (car lst)
127       (string-append (car lst) infix (string-join (cdr lst) infix))))
128
129 (define *mes-prefix* "module/")
130 (define (module->file o)
131   (string-append (string-join (map1 symbol->string o) "/") ".mes"))
132
133 (define *modules* '(mes/base-0.mes))
134 (define (mes-load-module-env module a)
135   (push! *input-ports* (current-input-port))
136   (set-current-input-port (open-input-file (string-append *mes-prefix* (module->file module))))
137   (let ((x (core:eval (append (cons 'begin (read-input-file-env a))
138                               '((current-module)))
139                       a)))
140     (set-current-input-port (pop! *input-ports*))
141     x))
142 (define (not x)
143   (if x #f #t))
144 (define-macro (mes-use-module module)
145   (list
146    'begin
147    (list 'if (list 'not (list 'memq (list string->symbol (module->file module)) '*modules*))
148          (list
149           'begin
150           (list 'set! '*modules* (list cons (list string->symbol (module->file module)) '*modules*))
151           (list 'load (list string-append '*mes-prefix* (module->file module)))))))
152
153 (mes-use-module (srfi srfi-0))
154 (mes-use-module (mes base))
155 (mes-use-module (mes quasiquote))
156 (mes-use-module (mes let))
157 (mes-use-module (mes scm))
158 (mes-use-module (srfi srfi-13))
159 (mes-use-module (mes display))
160 (mes-use-module (mes catch))