core: Add module-define!
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 14 Oct 2018 07:10:30 +0000 (09:10 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 14 Oct 2018 07:10:30 +0000 (09:10 +0200)
* src/module.c (module_define_x, module_printer): New function.
(make_initial_module): Use them.
* tests/srfi-0.test: Test it.
* src/mes.c (display_m0): Remove.  Update callers.
* mes/module/mes/fluids.mes (make-fluid): Rewrite.
* tests/macro.test: Test it.
* mes/module/mes/boot-0.scm.in (module-define!): Remove.
* mes/module/mes/boot-02.scm: Likewise.
* module/mes/misc.scm (pk, warn): New function.
* build-aux/check-mes.sh (tests): Run tests.

13 files changed:
build-aux/check-mes.sh
mes/module/mes/boot-0.scm.in
mes/module/mes/boot-02.scm
mes/module/mes/fluids.mes
module/mes/misc.scm
src/mes.c
src/module.c
src/reader.c
src/struct.c
src/vector.c
tests/guile.test
tests/macro.test [new file with mode: 0755]
tests/srfi-0.test [new file with mode: 0755]

index bb17b54b8600b8594e9c0407a26fafba361c5768..1e735711b79d0eb70d79d6f1914224458f88ecbb 100755 (executable)
@@ -34,6 +34,8 @@ MES_ARENA=${MES_ARENA-100000000}
 tests="
 tests/boot.test
 tests/read.test
+tests/srfi-0.test
+tests/macro.test
 tests/base.test
 tests/quasiquote.test
 tests/let.test
index 07034a24cfdd7a58a3c5867fd96830506c93fec8..23af005968d6596da51b8bc0b8becf527c62b7b4 100644 (file)
                             (cons (quote or) (cdr x))))
                 (car x)))))
 
-(define-macro (module-define! module name value)
-  ;;(list 'define name value)
-  #t)
-
 (define-macro (mes-use-module module)
   #t)
 ;; end boot-02.scm
index 0d5217624929526baa96474e6e28f945d73f2f98..d437b09b8f6941081e7997a677bd0144003957de 100644 (file)
                             (cons (quote or) (cdr x))))
                 (car x)))))
 
-(define-macro (module-define! module name value)
-  ;;(list 'define name value)
-  #t)
-
 (define-macro (mes-use-module module)
   #t)
 
index a415c247a384862d4ed8d226c9add079139feeba..5fe3f187aae294f44263ae4f76f3e540c9be69ff 100644 (file)
@@ -1,7 +1,7 @@
 ;;; -*-scheme-*-
 
 ;;; GNU Mes --- Maxwell Equations of Software
-;;; Copyright © 2016 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2016,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 ;;;
 ;;; This file is part of GNU Mes.
 ;;;
 
 (mes-use-module (mes scm))
 
-
-(define (sexp:define e a)
-  (if (atom? (car (cdr e))) (cons (car (cdr e))
-                                  (core:eval (car (cdr (cdr e))) a))
-      (cons (car (car (cdr e)))
-            (core:eval (cons (quote lambda)
-                             (cons (cdr (car (cdr e))) (cdr (cdr e)))) a))))
-
-(define (f:env:define a+ a)
-  (set-cdr! a+ (cdr a))
-  (set-cdr! a a+)
-  ;;(set-cdr! (assq '*closure* a) a+)
-  )
-
-(define (env:escape-closure a n)
-  (if (eq? (caar a) '*closure*) (if (= 0 n) a
-                                    (env:escape-closure (cdr a) (- n 1)))
-      (env:escape-closure (cdr a) n)))
-
-(define-macro (module-define! name value a)
-  `(f:env:define (cons (sexp:define (cons 'define (cons ',name (cons ,value '()))) ,a) '()) (env:escape-closure ,a 1)))
-
 (define-macro (make-fluid . default)
-  `(begin
-     ,(let ((fluid (symbol-append 'fluid: (gensym)))
-            (module (current-module)))
-        `(begin
-           (module-define! ,fluid
-                           (let ((v ,(and (pair? default) (car default))))
-                             (lambda ( . rest)
-                               (if (null? rest) v
-                                   (set! v (car rest))))) ',module)
-           ',fluid))))
+  ((lambda (fluid)
+     `(begin
+        (module-define!
+         (boot-module)
+        ',fluid
+        ((lambda (v)
+           (lambda ( . rest)
+             (if (null? rest) v
+                 (set! v (car rest)))))
+         ,(and (pair? default) (car default))))
+        ',fluid))
+   (symbol-append 'fluid: (gensym))))
 
 (define (fluid-ref fluid)
   (fluid))
index e6d15275b00266a314902dc9172be3d1f76eb1bd..c3dae084ef38a909d7d6eba79b1b001288d7583e 100644 (file)
@@ -22,7 +22,9 @@
             disjoin
             guile?
             mes?
+            pk
             pke
+            warn
             stderr
             string-substitute))
 
 (define (stderr string . rest)
   (apply logf (cons* (current-error-port) string rest)))
 
+(define (pk . stuff)
+  (newline)
+  (display ";;; ")
+  (write stuff)
+  (newline)
+  (car (last-pair stuff)))
+
 (define (pke . stuff)
   (newline (current-error-port))
   (display ";;; " (current-error-port))
@@ -50,6 +59,8 @@
   (newline (current-error-port))
   (car (last-pair stuff)))
 
+(define warn pke)
+
 (define (disjoin . predicates)
   (lambda (. arguments)
     (any (lambda (o) (apply o arguments)) predicates)))
index cd259e63760d664b5067c4145628b55664b358c1..97495f98fc05f16e5d36762274af3fbb7f061242 100644 (file)
--- a/src/mes.c
+++ b/src/mes.c
@@ -52,6 +52,8 @@ SCM r1 = 0;
 SCM r2 = 0;
 // continuation
 SCM r3 = 0;
+// current-module
+SCM m0 = 0;
 // macro
 SCM g_macros = 1;
 SCM g_ports = 1;
@@ -662,7 +664,7 @@ check_apply (SCM f, SCM e) ///((internal))
 SCM
 gc_push_frame () ///((internal))
 {
-  SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cell_nil))));
+  SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cons (m0, cell_nil)))));
   g_stack = cons (frame, g_stack);
   return g_stack;
 }
@@ -897,7 +899,10 @@ push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
   r2 = p2;
   gc_push_frame ();
   r1 = p1;
-  r0 = a;
+  // if (TYPE (a) == TPAIR)
+  //   r0 = module_clone_locals (r0, a);
+  // else
+    r0 = a;
   r3 = x;
   return cell_unspecified;
 }
@@ -910,6 +915,7 @@ gc_peek_frame () ///((internal))
   r2 = CADR (frame);
   r3 = CAR (CDDR (frame));
   r0 = CADR (CDDR (frame));
+  m0 = CAR (CDDR (CDDR (frame)));
   return frame;
 }
 
@@ -1017,6 +1023,9 @@ expand_variable (SCM x, SCM formals) ///((internal))
   return expand_variable_ (x, formals, 1);
 }
 
+SCM struct_ref_ (SCM x, long i);
+SCM vector_ref_ (SCM x, long i);
+
 SCM
 eval_apply ()
 {
@@ -1268,12 +1277,7 @@ eval_apply ()
                     {
                       entry = module_variable (r0, name);
                       if (entry == cell_f)
-                        {
-                          entry = cons (name, cell_f);
-                          aa = cons (entry, cell_nil);
-                          set_cdr_x (aa, cdr (r0));
-                          set_cdr_x (r0, aa);
-                        }
+                        module_define_x (m0, name, cell_f);
                     }
                 }
               r2 = r1;
@@ -1507,6 +1511,8 @@ eval_apply ()
 
               push_cc (input, r2, r0, cell_vm_return);
               x = read_input_file_env (r0);
+              if (g_debug > 3)
+                module_printer (m0);
               gc_pop_frame ();
               input = r1;
               r1 = x;
@@ -1594,12 +1600,12 @@ apply (SCM f, SCM x, SCM a) ///((internal))
 SCM
 mes_g_stack (SCM a) ///((internal))
 {
-  r0 = a;
+  //r0 = a;
   r1 = MAKE_CHAR (0);
   r2 = MAKE_CHAR (0);
   r3 = MAKE_CHAR (0);
   g_stack = cons (cell_nil, cell_nil);
-  return r0;
+  return a;
 }
 
 //\f Environment setup
@@ -2025,20 +2031,6 @@ g_cells[cell_vm_return].car = cstring_to_list (scm_vm_return.car);
   a = acons (cell_symbol_mes_version, MAKE_STRING (cstring_to_list (VERSION)), a);
   a = acons (cell_symbol_mes_prefix, MAKE_STRING (cstring_to_list (PREFIX)), a);
 
-  char *compiler = "gnuc";
-#if __MESC__
-  compiler = "mesc";
-#elif __TINYC__
-  compiler = "tcc";
-#endif
-  a = acons (cell_symbol_compiler, MAKE_STRING (cstring_to_list (compiler)), a);
-
-  char *arch = "x86";
-#if __x86_64__
-  arch = "x86_64";
-#endif
-  a = acons (cell_symbol_arch, MAKE_STRING (cstring_to_list (arch)), a);
-
   a = acons (cell_type_char, MAKE_NUMBER (TCHAR), a);
   a = acons (cell_type_closure, MAKE_NUMBER (TCLOSURE), a);
   a = acons (cell_type_continuation, MAKE_NUMBER (TCONTINUATION), a);
@@ -2064,9 +2056,31 @@ g_cells[cell_vm_return].car = cstring_to_list (scm_vm_return.car);
 }
 
 SCM
-mes_environment () ///((internal))
+mes_environment (int argc, char *argv[])
 {
   SCM a = mes_symbols ();
+
+  char *compiler = "gnuc";
+#if __MESC__
+  compiler = "mesc";
+#elif __TINYC__
+  compiler = "tcc";
+#endif
+  a = acons (cell_symbol_compiler, MAKE_STRING (cstring_to_list (compiler)), a);
+
+  char *arch = "x86";
+#if __x86_64__
+  arch = "x86_64";
+#endif
+  a = acons (cell_symbol_arch, MAKE_STRING (cstring_to_list (arch)), a);
+
+#if !MES_MINI
+  SCM lst = cell_nil;
+  for (int i=argc-1; i>=0; i--)
+    lst = cons (MAKE_STRING (cstring_to_list (argv[i])), lst);
+  a = acons (cell_symbol_argv, lst, a);
+#endif
+
   return mes_g_stack (a);
 }
 
@@ -2287,9 +2301,8 @@ load_boot (char *prefix, char const *boot, char const *location)
 }
 
 SCM
-load_env (SCM a) ///((internal))
+load_env () ///((internal))
 {
-  r0 = a;
   g_stdin = -1;
   char prefix[1024];
   char boot[1024];
@@ -2328,15 +2341,13 @@ load_env (SCM a) ///((internal))
       exit (1);
     }
 
-  if (!g_function)
-    r0 = mes_builtins (r0);
   r2 = read_input_file_env (r0);
   g_stdin = STDIN;
   return r2;
 }
 
 SCM
-bload_env (SCM a) ///((internal))
+bload_env () ///((internal))
 {
 #if !_POSIX_SOURCE
   char *mo = "mes/boot-0.32-mo";
@@ -2376,23 +2387,11 @@ bload_env (SCM a) ///((internal))
   gc_peek_frame ();
   g_symbols = r1;
   g_stdin = STDIN;
+  // SCM a = struct_ref (r0, 3);
+  // a = mes_builtins (a);
+  // struct_set_x (r0, 3, a);
   r0 = mes_builtins (r0);
 
-  char *compiler = "gnuc";
-#if __MESC__
-  compiler = "mesc";
-#elif __TINYC__
-  compiler = "tcc";
-#endif
-
-  a = acons (cell_symbol_compiler, MAKE_STRING (cstring_to_list (compiler)), a);
-
-  char *arch = "x86";
-#if __x86_64__
-  arch = "x86_64";
-#endif
-  a = acons (cell_symbol_arch, MAKE_STRING (cstring_to_list (arch)), a);
-
   if (g_debug > 3)
     {
       eputs ("symbols: ");
@@ -2448,21 +2447,20 @@ main (int argc, char *argv[])
     GC_SAFETY = atoi (p);
   g_stdin = STDIN;
   g_stdout = STDOUT;
-  r0 = mes_environment ();
+
+  SCM a = mes_environment (argc, argv);
+  a = mes_builtins (a);
+  m0 = make_initial_module (a);
+
+  if (g_debug > 3)
+    module_printer (m0);
 
   SCM program = (argc > 1 && !strcmp (argv[1], "--load"))
-    ? bload_env (r0) : load_env (r0);
+    ? bload_env () : load_env ();
   g_tiny = argc > 2 && !strcmp (argv[2], "--tiny");
   if (argc > 1 && !strcmp (argv[1], "--dump"))
     return dump ();
 
-#if !MES_MINI
-  SCM lst = cell_nil;
-  for (int i=argc-1; i>=0; i--)
-    lst = cons (MAKE_STRING (cstring_to_list (argv[i])), lst);
-  r0 = acons (cell_symbol_argv, lst, r0); // FIXME
-  r0 = acons (cell_symbol_argv, lst, r0);
-#endif
   push_cc (r2, cell_unspecified, r0, cell_unspecified);
 
   if (g_debug > 2)
index 6c1d348961448749f0d669c4b20126879c23c396..9f2aacbf030282934abddabc11b7e9b9dd4e5759 100644 (file)
  * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+SCM make_vector__ (long k);
+SCM struct_ref_ (SCM x, long i);
+SCM struct_set_x_ (SCM x, long i, SCM e);
+SCM vector_ref_ (SCM x, long i);
+SCM vector_set_x_ (SCM x, long i, SCM e);
+
 SCM
-make_initial_module (SCM a)
+make_initial_module (SCM a) ///((internal))
 {
   SCM fields = cell_nil;
   fields = cons (cstring_to_symbol ("globals"), fields);
@@ -31,17 +37,105 @@ make_initial_module (SCM a)
   a = acons (module_type_name, module_type, a);
   SCM values = cell_nil;
   SCM name = cons (cstring_to_symbol ("boot"), cell_nil);
-  SCM globals = cell_nil;
-  values = cons (a, values);
+  //SCM globals = make_vector__ (28 * 27);
+  SCM globals = make_vector__ (30 * 27);
   values = cons (globals, values);
+  SCM locals = cell_nil;
+  values = cons (locals, values);
   values = cons (name, values);
-  SCM module = make_struct (module_type_name, values, cell_unspecified);
+  SCM module = make_struct (module_type_name, values, cell_module_printer);
+  r0 = cell_nil;
+  r0 = cons (CAR (a), r0);
+
+  m0 = module;
+  while (TYPE (a) == TPAIR)
+    {
+      if (g_debug > 3)
+        {
+          eputs ("entry="); display_error_ (CAR (a)); eputs ("\n");
+        }
+      module_define_x (module, CAAR (a), CDAR (a));
+      a = CDR (a);
+    }
+
   return module;
 }
 
+SCM
+module_printer (SCM module)
+{
+  eputs ("#<"); display_error_ (struct_ref_ (module, 0)); eputc (' ');
+  //eputs ("printer: "); display_error_ (struct_ref_ (module, 1)); eputc (' ');
+  eputs ("name: "); display_error_ (struct_ref_ (module, 2)); eputc (' ');
+  eputs ("locals: "); display_error_ (struct_ref_ (module, 3)); eputc (' ');
+  eputs ("globals:\n  ");
+  SCM v = struct_ref_ (m0, 4);
+  for (int i=0; i<LENGTH (v); i++)
+    {
+      SCM e = vector_ref_ (v, i);
+      if (e != cell_unspecified)
+        {
+          eputc ('[');
+          while (TYPE (e) == TPAIR)
+            {
+              display_error_ (CAAR (e));
+              e = CDR (e);
+              if (TYPE (e) == TPAIR)
+                eputc (' ');
+            }
+          eputs ("]\n  ");
+        }
+    }
+  eputc ('>');
+}
+
+
+
+int
+char_hash (int c)
+{
+  if (c >= 'a' && c <= 'z')
+    return c - 'a';
+  return 27;
+}
+
+int
+module_hash (SCM x) ///((internal))
+{
+  int hash = char_hash (VALUE (CAR (STRING (x)))) * 27;
+  if (TYPE (CDR (STRING (x))) == TPAIR)
+    hash = hash + char_hash (VALUE (CADR (STRING (x))));
+  else
+    hash = hash + char_hash (0);
+  assert (hash <= 756);
+  return hash;
+}
+
+SCM
+module_variable (SCM module, SCM name)
+{
+  //SCM locals = struct_ref_ (module, 3);
+  SCM locals = module;
+  SCM x = assq (name, locals);
+  if (x == cell_f)
+    {
+      int hash = module_hash (name);
+      module = m0;
+      SCM globals = struct_ref_ (module, 4);
+      SCM bucket = vector_ref_ (globals, hash);
+      if (TYPE (bucket) == TPAIR)
+        x = assq (name, bucket);
+    }
+  return x;
+}
+
 SCM
 module_ref (SCM module, SCM name)
 {
+  if (g_debug > 4)
+    {
+      eputs ("module_ref: "); display_error_ (name); eputs ("\n");
+    }
   SCM x = module_variable (module, name);
   if (x == cell_f)
     return cell_undefined;
@@ -49,9 +143,19 @@ module_ref (SCM module, SCM name)
 }
 
 SCM
-module_variable (SCM module, SCM name)
+module_define_x (SCM module, SCM name, SCM value)
 {
-  //SCM locals = struct_ref (module, 4);
-  SCM locals = module;
-  return assq (name, locals);
+  if (g_debug > 4)
+    {
+      eputs ("module_define_x: "); display_error_ (name); eputs ("\n");
+    }
+  int hash = module_hash (name);
+  module = m0;
+  SCM globals = struct_ref_ (module, 4);
+  SCM bucket = vector_ref_ (globals, hash);
+  if (TYPE (bucket) != TPAIR)
+    bucket = cell_nil;
+  bucket = acons (name, value, bucket);
+  vector_set_x_ (globals, hash, bucket);
+  return cell_t;
 }
index ef699a7d836ff7ac6330e4eb01ae0ee9b2b256e1..5f4e3bec157e34f0fc474617143017858c4c86a7 100644 (file)
@@ -34,8 +34,9 @@ read_input_file_env_ (SCM e, SCM a)
 SCM
 read_input_file_env (SCM a)
 {
-  r0 = a;
-  return read_input_file_env_ (read_env (r0), r0);
+  //r0 = a;
+  //return read_input_file_env_ (read_env (r0), r0);
+  return read_input_file_env_ (read_env (cell_nil), cell_nil);
 }
 
 int
index 75e43a46b04222c1e281e087d7f6e868a6693d8f..f73013dc2bfeae7009b61e32c99ddbb3cb06bac1 100644 (file)
@@ -47,11 +47,11 @@ struct_length (SCM x)
 }
 
 SCM
-struct_ref (SCM x, SCM i)
+struct_ref_ (SCM x, long i)
 {
   assert (TYPE (x) == TSTRUCT);
-  assert (VALUE (i) < LENGTH (x));
-  SCM e = STRUCT (x) + VALUE (i);
+  assert (i < LENGTH (x));
+  SCM e = STRUCT (x) + i;
   if (TYPE (e) == TREF)
     e = REF (e);
   if (TYPE (e) == TCHAR)
@@ -62,10 +62,22 @@ struct_ref (SCM x, SCM i)
 }
 
 SCM
-struct_set_x (SCM x, SCM i, SCM e)
+struct_set_x_ (SCM x, long i, SCM e)
 {
   assert (TYPE (x) == TSTRUCT);
   assert (VALUE (i) < LENGTH (x));
-  g_cells[STRUCT (x)+VALUE (i)] = g_cells[vector_entry (e)];
+  g_cells[STRUCT (x)+i] = g_cells[vector_entry (e)];
   return cell_unspecified;
 }
+
+SCM
+struct_ref (SCM x, SCM i)
+{
+  return struct_ref_ (x, VALUE (i));
+}
+
+SCM
+struct_set_x (SCM x, SCM i, SCM e)
+{
+  return struct_set_x_ (x, VALUE (i), e);
+}
index 0e34d93c89553bd9b6d71c97d391e01d9520e5da..09517d562410129230b3b5156e0631721ed28ce8 100644 (file)
@@ -42,11 +42,11 @@ vector_length (SCM x)
 }
 
 SCM
-vector_ref (SCM x, SCM i)
+vector_ref_ (SCM x, long i)
 {
   assert (TYPE (x) == TVECTOR);
-  assert (VALUE (i) < LENGTH (x));
-  SCM e = VECTOR (x) + VALUE (i);
+  assert (i < LENGTH (x));
+  SCM e = VECTOR (x) + i;
   if (TYPE (e) == TREF)
     e = REF (e);
   if (TYPE (e) == TCHAR)
@@ -56,6 +56,12 @@ vector_ref (SCM x, SCM i)
   return e;
 }
 
+SCM
+vector_ref (SCM x, SCM i)
+{
+  return vector_ref_ (x, VALUE (i));
+}
+
 SCM
 vector_entry (SCM x)
 {
@@ -65,14 +71,20 @@ vector_entry (SCM x)
 }
 
 SCM
-vector_set_x (SCM x, SCM i, SCM e)
+vector_set_x_ (SCM x, long i, SCM e)
 {
   assert (TYPE (x) == TVECTOR);
-  assert (VALUE (i) < LENGTH (x));
-  g_cells[VECTOR (x)+VALUE (i)] = g_cells[vector_entry (e)];
+  assert (i < LENGTH (x));
+  g_cells[VECTOR (x)+i] = g_cells[vector_entry (e)];
   return cell_unspecified;
 }
 
+SCM
+vector_set_x (SCM x, SCM i, SCM e)
+{
+  return vector_set_x_ (x, VALUE (i), e);
+}
+
 SCM
 list_to_vector (SCM x)
 {
index 350c523de753f051db7417f3fa251037f89fc391..cb63692b87ab7cdbb939b97383e65bd4de0bc04c 100755 (executable)
@@ -26,11 +26,13 @@ exec ${MES-src/mes} --no-auto-compile -L ${0%/*} -L module -C module -e '(tests
 (define-module (tests guile)
   #:use-module (ice-9 rdelim)
   #:use-module (mes mes-0)
+  #:use-module (mes misc)
   #:use-module (mes test))
 
 (cond-expand
  (mes
   (mes-use-module (mes test))
+  (mes-use-module (mes misc))
   (mes-use-module (mes guile)))
  (else))
 
@@ -71,14 +73,6 @@ exec ${MES-src/mes} --no-auto-compile -L ${0%/*} -L module -C module -e '(tests
          (set-current-input-port (car ipstk))
          (fluid-set! *input-stack* (cdr ipstk))))))
 
-;; Return #f if empty
-(define (pop-input)
-  (let ((ipstk (fluid-ref *input-stack*)))
-    (if (null? ipstk) #f
-       (begin
-         (set-current-input-port (car ipstk))
-         (fluid-set! *input-stack* (cdr ipstk))))))
-
 (pass-if-equal "push-input"
     "bla"
   (let ()
@@ -102,8 +96,7 @@ exec ${MES-src/mes} --no-auto-compile -L ${0%/*} -L module -C module -e '(tests
             (unless (eof-object? ch) (write-char ch) (iter (read-char))))
           (pop-input)
           (let iter ((ch (read-char)))
-            (unless (eof-object? ch) (write-char ch) (iter (read-char))))
-          )))))
+            (unless (eof-object? ch) (write-char ch) (iter (read-char)))))))))
 
 (pass-if "input-stack/2"
   (let ((sp (open-input-string "abc")))
diff --git a/tests/macro.test b/tests/macro.test
new file mode 100755 (executable)
index 0000000..0c87421
--- /dev/null
@@ -0,0 +1,119 @@
+#! /bin/sh
+# -*-scheme-*-
+if [ "$MES" != guile ]; then
+    export MES_BOOT=boot-02.scm
+    MES=${MES-$(dirname $0)/../src/mes}
+    $MES < $0
+    exit $?
+else
+    exit 0
+fi
+exec ${MES-mes} --no-auto-compile -L ${0%/*} -L module -C module -e '(tests macro)' -s "$0" "$@"
+!#
+
+;;; -*-scheme-*-
+
+;;; GNU Mes --- Maxwell Equations of Software
+;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;;
+;;; This file is part of GNU Mes.
+;;;
+;;; GNU Mes is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Mes is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (tests boot)
+  #:use-module (mes mes-0)
+  #:use-module (mes test))
+
+(cond-expand
+ (mes
+  (primitive-load "module/mes/test.scm"))
+ (guile-2)
+ (guile
+  (use-modules (ice-9 syncase))))
+
+(pass-if "first dummy" #t)
+(pass-if-not "second dummy" #f)
+
+(define gensym
+  ((lambda (symbols)
+     (lambda (. rest)
+       ((lambda (head tail)
+          (set! symbols tail)
+          head)
+        (car symbols)
+        (cdr symbols))))
+   '(g0 g1 g2 g3 g4)))
+
+;; type-0.mes
+(define (string . lst)
+  (core:make-cell <cell:string> lst 0))
+
+(define (string->symbol s)
+  (if (not (pair? (core:car s))) '()
+      (list->symbol (core:car s))))
+
+(define (symbol->list s)
+  (core:car s))
+
+;; boot-0.scm
+(define (symbol->string s)
+  (apply string (symbol->list s)))
+
+(define (string-append . rest)
+  (apply string (apply append (map1 string->list rest))))
+
+;; scm.mes
+(define (symbol-append . rest)
+  (string->symbol (apply string-append (map symbol->string rest))))
+
+(define-macro (make-fluid . default)
+  ((lambda (fluid)
+     (list
+      'begin
+      (list
+       'module-define!
+       (list 'boot-module)
+       (list 'quote fluid)
+       (list
+        (lambda (v)
+          (lambda ( . rest)
+            (if (null? rest) v
+                (set! v (car rest)))))
+        (and (pair? default) (car default))))
+      (list 'quote fluid)))
+   (symbol-append 'fluid: (gensym))))
+
+(define fluid (make-fluid 42))
+
+(pass-if-eq "fluid" 42 (fluid))
+
+(fluid 0)
+(pass-if-eq "fluid 0" 0 (fluid))
+
+(fluid '())
+(pass-if-eq "fluid null" '() (fluid))
+
+(define (fluid-ref fluid)
+  (fluid))
+
+(define (fluid-set! fluid value)
+  (fluid value))
+
+(fluid-set! fluid 0)
+(pass-if-eq "fluid 0" 0 (fluid-ref fluid))
+
+(fluid-set! fluid '())
+(pass-if-eq "fluid null" '() (fluid-ref fluid))
+
+(result 'report)
diff --git a/tests/srfi-0.test b/tests/srfi-0.test
new file mode 100755 (executable)
index 0000000..90c526a
--- /dev/null
@@ -0,0 +1,48 @@
+#! /bin/sh
+# -*-scheme-*-
+if [ "$MES" != guile ]; then
+    export MES_BOOT=boot-02.scm
+    MES=${MES-$(dirname $0)/../src/mes}
+    $MES < $0
+    exit $?
+fi
+exec ${MES-mes} --no-auto-compile -L ${0%/*} -L module -C module -e '(tests boot)' -s "$0" "$@"
+!#
+
+;;; -*-scheme-*-
+
+;;; GNU Mes --- Maxwell Equations of Software
+;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;;
+;;; This file is part of GNU Mes.
+;;;
+;;; GNU Mes is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Mes is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (tests srfi-0)
+  #:use-module (mes mes-0)
+  #:use-module (mes test))
+
+(display "srfi-0...\n")
+
+(cond-expand
+ (mes
+  (display "mes\n")
+  (exit 0))
+ (guile
+  (display "guile\n")
+  (exit guile?))
+ (else
+  (exit 1)))
+
+(exit 1)