Add reader in Scheme.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 19 Nov 2016 22:25:24 +0000 (23:25 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 12 Dec 2016 19:35:19 +0000 (20:35 +0100)
* module/mes/read-0.mes: New file.
* mes.c (char_to_integer, integer_to_char, null_p): Move to core.
 (peek_byte, read_byte, unread_byte): New function.
 (main): --dump, --load: New option.
* lib.c (char_to_integer, integer_to_char): Remove.
* NEWS: Update.

25 files changed:
.gitignore
GNUmakefile
NEWS
lib.c
mes.c
module/mes/base-0.mes
module/mes/read-0.mes [new file with mode: 0644]
quasiquote.c
scripts/elf.mes
scripts/mescc.mes
scripts/paren.mes
scripts/repl.mes
tests/base.test
tests/closure.test
tests/cwv.test
tests/let-syntax.test
tests/let.test
tests/match.test
tests/psyntax.test
tests/quasiquote.test
tests/read.test [new file with mode: 0755]
tests/record.test
tests/scm.test
tests/vector.test
type.c

index 505f3185a5f4b9a1ebe18a6e5d7405234bd12f1d..6f98ac5e857b1f846e179107b565526ebe3fa95b 100644 (file)
@@ -13,6 +13,7 @@
 /ChangeLog
 /a.out
 /mes
+/read-0.mo
 /out
 ?
 ?.mes
index c67750e41cbacca978fd880ceaba3f840e27d7f1..1e9b57b50fc6f3a4693da16188ef7d5d68fddfac 100644 (file)
@@ -44,6 +44,7 @@ distclean: clean
 check: all guile-check mes-check
 
 TESTS:=\
+ tests/read.test\
  tests/base.test\
  tests/closure.test\
  tests/quasiquote.test\
@@ -60,10 +61,16 @@ TESTS:=\
 BASE-0:=module/mes/base-0.mes
 MES-0:=guile/mes-0.scm
 MES:=./mes
+# use module/mes/read-0.mes rather than C-core reader
+MES_FLAGS:=--load
+export MES_FLAGS
 
 mes-check: all
        set -e; for i in $(TESTS); do ./$$i; done
 
+dump: all
+       ./mes --dump < module/mes/read-0.mes > read-0.mo
+
 guile-check:
        set -e; for i in $(TESTS); do\
                guile -s <(cat $(MES-0) module/mes/test.mes $$i);\
@@ -85,6 +92,9 @@ guile-mescc: mescc.cat
        chmod +x a.out
        ./a.out
 
+paren: all
+       scripts/paren.mes
+
 help: help-top
 
 install: all
diff --git a/NEWS b/NEWS
index d75de6ade4fbef2672ffbdce42ee1b6e0bfccc93..c9c3efdd510018017737af03a8b0b61ec5863ec3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Please send Mes bug reports to janneke@gnu.org.
 *** Garbage collector aka Jam scraper.
 A variant on SICP's stop and copy Garbage Colletor (Jam Scraper?)
 algorithm has been implemented.
-
+*** The reader has been moved to Scheme.
 * Changes in 0.2 since 0.1
 ** Core
 *** Names of symbols and strings are list of characters [WAS: c-string].
diff --git a/lib.c b/lib.c
index da6fd34a9102ef90af69a217080d2e861c342e0f..6c47045b71b894a897f0b75b134175f3ccd9bab9 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -79,20 +79,6 @@ vector_to_list (SCM v)
   return x;
 }
 
-SCM
-integer_to_char (SCM x)
-{
-  assert (TYPE (x) == NUMBER);
-  return make_char (VALUE (x));
-}
-
-SCM
-char_to_integer (SCM x)
-{
-  assert (TYPE (x) == CHAR);
-  return make_number (VALUE (x));
-}
-
 SCM
 builtin_exit (SCM x)
 {
diff --git a/mes.c b/mes.c
index 8fd3429759ebf2aafb806c66fc779429f5a0a6aa..f8d834857bc137d4b4e3ae1929d84e94f3719a04 100644 (file)
--- a/mes.c
+++ b/mes.c
 #define MES_MINI 0 // 1 for gc-2a.test, gc-3.test
 
 #if MES_FULL
-int ARENA_SIZE = 400000000; // need this much for scripts/mescc.mes
-//int ARENA_SIZE = 300000000; // need this much for tests/match.scm
-//int ARENA_SIZE = 30000000; // need this much for tests/record.scm
-//int ARENA_SIZE = 500000; // enough for tests/scm.test
-//int ARENA_SIZE = 60000; // enough for tests/base.test
+int ARENA_SIZE = 200000000;
 int GC_SAFETY = 10000;
 int GC_FREE = 20000;
 #else
-//int ARENA_SIZE = 500; // MINI
-int ARENA_SIZE = 4000; // MES_MINI, gc-3.test
-//int ARENA_SIZE = 10000; // gc-2a.test
-//int ARENA_SIZE = 18000; // gc-2.test -->KRAK
-//int ARENA_SIZE = 23000; // gc-2.test OK
-// int GC_SAFETY = 1000;
-// int GC_FREE = 1000;
-int GC_SAFETY = 10;
-int GC_FREE = 10;
+int ARENA_SIZE = 15000;
+int GC_SAFETY = 1000;
+int GC_FREE = 100;
 #endif
 
 typedef long SCM;
@@ -154,6 +144,9 @@ scm scm_symbol_call_with_values = {SYMBOL, "call-with-values"};
 scm scm_symbol_current_module = {SYMBOL, "current-module"};
 scm scm_symbol_primitive_load = {SYMBOL, "primitive-load"};
 
+scm scm_symbol_the_unquoters = {SYMBOL, "*the-unquoters*"};
+
+scm char_eof = {CHAR, .name="*eof*", .value=-1};
 scm char_nul = {CHAR, .name="nul", .value=0};
 scm char_backspace = {CHAR, .name="backspace", .value=8};
 scm char_tab = {CHAR, .name="tab", .value=9};
@@ -669,11 +662,6 @@ vm_apply_env ()
     SCM body = cddr (r1);
     SCM p = pairlis (args, r2, r0);
     return call_lambda (body, p, p, r0);
-    // r2 = p;
-    // cache_invalidate_range (r2, g_cells[r0].cdr);
-    // SCM r = begin_env (cddr (r1), cons (cons (cell_closure, p), p));
-    // cache_invalidate_range (r2, g_cells[r0].cdr);
-    // return r;
   }
   else if (car (r1) == cell_closure) {
     SCM args = caddr (r1);
@@ -682,12 +670,6 @@ vm_apply_env ()
     aa = cdr (aa);
     SCM p = pairlis (args, r2, aa);
     return call_lambda (body, p, aa, r0);
-    // r2 = p;
-    // r3 = aa;
-    // cache_invalidate_range (r2, g_cells[r3].cdr);
-    // SCM r = begin_env (body, cons (cons (cell_closure, p), p));
-    // cache_invalidate_range (r2, g_cells[r3].cdr);
-    // return r;
   }
 #if BOOT
   else if (car (r1) == cell_symbol_label)
@@ -742,7 +724,7 @@ vm_eval_env ()
         if (car (r1) == cell_symbol_define_macro)
           return define_env (r1, r0);
         if (car (r1) == cell_symbol_primitive_load)
-          return load_env (r0);
+          return begin_env (read_input_file_env (r0), r0);
 #else
         if (car (r1) == cell_symbol_define) {
         fprintf (stderr, "C DEFINE: ");
@@ -878,9 +860,6 @@ SCM
 make_function (SCM name, SCM id, SCM arity)
 {
   g_cells[tmp_num3].value = FUNCTION;
-  // function fun_read_byte = {.function0=&read_byte, .arity=0};
-  // scm scm_read_byte = {FUNCTION, .name="read-int", .function=&fun_read_byte};
-  // SCM cell_read_byte = 93;
   function *f = (function*)malloc (sizeof (function));
   f->arity = VALUE (arity);
   g_cells[tmp_num4].value = (long)f;
@@ -926,6 +905,13 @@ cstring_to_list (char const* s)
   return p;
 }
 
+/// read: from type.c
+SCM
+null_p (SCM x)
+{
+  return x == cell_nil ? cell_t : cell_f;
+}
+
 SCM
 list_of_char_equal_p (SCM a, SCM b)
 {
@@ -1035,6 +1021,20 @@ vector_set_x (SCM x, SCM i, SCM e)
   return cell_unspecified;
 }
 
+SCM
+list_to_vector (SCM x)
+{
+  VALUE (tmp_num) = VALUE (length (x));
+  SCM v = make_vector (tmp_num);
+  SCM p = VECTOR (v);
+  while (x != cell_nil)
+    {
+      g_cells[p++] = g_cells[vector_entry (car (x))];
+      x = cdr (x);
+    }
+  return v;
+}
+
 SCM
 lookup (SCM s, SCM a)
 {
@@ -1085,20 +1085,6 @@ lookup_char (int c, SCM a)
   return lookup (cons (make_char (c), cell_nil), a);
 }
 
-SCM
-list_to_vector (SCM x)
-{
-  g_cells[tmp_num].value = VALUE (length (x));
-  SCM v = make_vector (tmp_num);
-  SCM p = VECTOR (v);
-  while (x != cell_nil)
-    {
-      g_cells[p++] = g_cells[vector_entry (car (x))];
-      x = cdr (x);
-    }
-  return v;
-}
-
 SCM
 force_output (SCM p) ///((arity . n))
 {
@@ -1254,6 +1240,24 @@ peekchar ()
   return c;
 }
 
+SCM
+peek_byte ()
+{
+  return make_number (peekchar ());
+}
+
+SCM
+read_byte ()
+{
+  return make_number (getchar ());
+}
+
+SCM
+unread_byte (SCM i)
+{
+  return ungetchar (VALUE (i));
+}
+
 SCM
 peek_char ()
 {
@@ -1266,6 +1270,12 @@ read_char ()
   return make_char (getchar ());
 }
 
+SCM
+unread_char (SCM c)
+{
+  return ungetchar (VALUE (c));
+}
+
 SCM
 write_char (SCM x) ///((arity . n))
 {
@@ -1294,6 +1304,20 @@ symbol_to_list (SCM x)
   return STRING (x);
 }
 
+SCM
+char_to_integer (SCM x)
+{
+  assert (TYPE (x) == CHAR);
+  return make_number (VALUE (x));
+}
+
+SCM
+integer_to_char (SCM x)
+{
+  assert (TYPE (x) == NUMBER);
+  return make_char (VALUE (x));
+}
+
 int
 readcomment (int c)
 {
@@ -1316,7 +1340,7 @@ readword (int c, SCM w, SCM a)
   if (c == '\n' && VALUE (car (w)) == '.' && cdr (w) == cell_nil) return cell_dot;
   if (c == EOF || c == '\n') return lookup (w, a);
   if (c == ' ') return readword ('\n', w, a);
-  if (c == '"' && w == cell_nil) return readstring ();
+  if (c == '"' && w == cell_nil) return read_string ();
   if (c == '"') {ungetchar (c); return lookup (w, a);}
   if (c == '(' && w == cell_nil) return readlist (a);
   if (c == '(') {ungetchar (c); return lookup (w, a);}
@@ -1346,29 +1370,10 @@ readword (int c, SCM w, SCM a)
   if (c == '#' && peekchar () == 'x') {getchar (); return read_hex ();}
   if (c == '#' && peekchar () == '\\') {getchar (); return read_character ();}
   if (c == '#' && w == cell_nil && peekchar () == '(') {getchar (); return list_to_vector (readlist (a));}
-  if (c == '#' && peekchar () == '(') {ungetchar (c); return lookup (w, a);}
   if (c == '#' && peekchar () == '!') {getchar (); readblock (getchar ()); return readword (getchar (), w, a);}
   return readword (getchar (), append2 (w, cons (make_char (c), cell_nil)), a);
 }
 
-SCM
-read_hex ()
-{
-  int n = 0;
-  int c = peekchar ();
-  while ((c >= '0' && c <= '9')
-         || (c >= 'A' && c <= 'F')
-         || (c >= 'a' && c <= 'f')) {
-    n <<= 4;
-    if (c >= 'a') n += c - 'a' + 10;
-    else if (c >= 'A') n += c - 'A' + 10;
-    else n+= c - '0';
-    getchar ();
-    c = peekchar ();
-  }
-  return make_number (n);
-}
-
 SCM
 read_character ()
 {
@@ -1406,6 +1411,24 @@ read_character ()
   return make_char (c);
 }
 
+SCM
+read_hex ()
+{
+  int n = 0;
+  int c = peekchar ();
+  while ((c >= '0' && c <= '9')
+         || (c >= 'A' && c <= 'F')
+         || (c >= 'a' && c <= 'f')) {
+    n <<= 4;
+    if (c >= 'a') n += c - 'a' + 10;
+    else if (c >= 'A') n += c - 'A' + 10;
+    else n+= c - '0';
+    getchar ();
+    c = peekchar ();
+  }
+  return make_number (n);
+}
+
 SCM
 append_char (SCM x, int i)
 {
@@ -1413,7 +1436,7 @@ append_char (SCM x, int i)
 }
 
 SCM
-readstring ()
+read_string ()
 {
   SCM p = cell_nil;
   int c = getchar ();
@@ -1467,110 +1490,72 @@ add_environment (SCM a, char const *name, SCM x)
   return acons (make_symbol (cstring_to_list (name)), x, a);
 }
 
+void
+print_f (scm *f)
+{
+  fprintf (stderr, "  g_function=%d; //%s\n", f->function, f->name);
+}
+
 SCM
-mes_environment () ///((internal))
+mes_symbols () ///((internal))
 {
-  // setup GC
   g_cells = (scm *)malloc (ARENA_SIZE*sizeof(scm));
   g_cells[0].type = VECTOR;
-  g_cells[0].length = ARENA_SIZE - 1;
-  g_cells[0].length = 10;
+  g_cells[0].length = 1000;
   g_cells[0].vector = 0;
   g_cells++;
-  // a = add_environment (a, "%free", &g_free); hihi, gets <3 moved
-  // a = add_environment (a, "%the-cells", g_cells);
-  // a = add_environment (a, "%new-cells", g_news);
-
-//#include "mes.symbols.i"
 
   g_cells[0].type = CHAR;
   g_cells[0].value = 'c';
   g_free.value = 1; // 0 is tricky
 
-#if !MES_MINI
 #include "mes.symbols.i"
-#else // MES_MINI
-  cell_nil = g_free.value++;
-  g_cells[cell_nil] = scm_nil;
-  cell_f = g_free.value++;
-  g_cells[cell_f] = scm_f;
-  cell_t = g_free.value++;
-  g_cells[cell_t] = scm_t;
-  cell_undefined = g_free.value++;
-  g_cells[cell_undefined] = scm_undefined;
-  cell_unspecified = g_free.value++;
-  g_cells[cell_unspecified] = scm_unspecified;
-  cell_closure = g_free.value++;
-  g_cells[cell_closure] = scm_closure;
-  cell_begin = g_free.value++;
-  g_cells[cell_begin] = scm_begin;
-
-  cell_symbol_begin = g_free.value++;
-  g_cells[cell_symbol_begin] = scm_symbol_begin;
-
-  cell_symbol_sc_expander_alist = g_free.value++;
-  g_cells[cell_symbol_sc_expander_alist] = scm_symbol_sc_expander_alist;
-  cell_symbol_sc_expand = g_free.value++;
-  g_cells[cell_symbol_sc_expand] = scm_symbol_sc_expand;
-
-  // cell_dot = g_free.value++;
-  // g_cells[cell_dot] = scm_dot;
-  // cell_circular = g_free.value++;
-  // g_cells[cell_circular] = scm_circular;
-  // cell_symbol_lambda = g_free.value++;
-  // g_cells[cell_symbol_lambda] = scm_symbol_lambda;
-  // cell_symbol_if = g_free.value++;
-  // g_cells[cell_symbol_if] = scm_symbol_if;
-  // cell_symbol_define = g_free.value++;
-  // g_cells[cell_symbol_define] = scm_symbol_define;
-  // cell_symbol_define_macro = g_free.value++;
-  // g_cells[cell_symbol_define_macro] = scm_symbol_define_macro;
-  
-#endif // MES_MINI
-  
-  SCM symbol_max = g_free.value;
-
-#if MES_FULL
-#include "define.i"
-#include "lib.i"
-#include "math.i"
-#include "mes.i"
-#include "posix.i"
-#include "quasiquote.i"
-#include "string.i"
-#include "type.i"
-#else
 
-  cell_cons = g_free.value++;
-  cell_display = g_free.value++;
-  cell_eq_p = g_free.value++;
-  cell_newline = g_free.value++;
-
-  g_cells[cell_cons] = scm_cons;
-  g_cells[cell_display] = scm_display;
-  g_cells[cell_eq_p] = scm_eq_p;
-  g_cells[cell_newline] = scm_newline;
-
-  cell_make_vector = g_free.value++;
-  g_cells[cell_make_vector] = scm_make_vector;
+  SCM symbol_max = g_free.value;
 
-#endif
-  
   tmp = g_free.value++;
   tmp_num = g_free.value++;
   g_cells[tmp_num].type = NUMBER;
   tmp_num2 = g_free.value++;
   g_cells[tmp_num2].type = NUMBER;
+  tmp_num3 = g_free.value++;
+  g_cells[tmp_num3].type = NUMBER;
+  tmp_num4 = g_free.value++;
+  g_cells[tmp_num4].type = NUMBER;
 
   g_start = g_free.value;
 
   symbols = 0;
   for (int i=1; i<symbol_max; i++)
     symbols = cons (i, symbols);
-  
+
   SCM a = cell_nil;
 
-#if MES_FULL
+#if BOOT
+  a = acons (cell_symbol_label, cell_t, a);
+#endif
+  a = acons (cell_symbol_begin, cell_begin, a);
+  a = add_environment (a, "sc-expand", cell_f);
+  a = acons (cell_closure, a, a);
+
+  internal_lookup_symbol (cell_nil);
+
+  return a;
+}
+
+SCM
+mes_builtins (SCM a)
+{
+#include "mes.i"
+
+#include "define.i"
+#include "lib.i"
+#include "math.i"
+#include "posix.i"
+#include "quasiquote.i"
+#include "string.i"
+#include "type.i"
+
 #include "define.environment.i"
 #include "lib.environment.i"
 #include "math.environment.i"
@@ -1579,52 +1564,35 @@ mes_environment () ///((internal))
   //#include "quasiquote.environment.i"
 #include "string.environment.i"
 #include "type.environment.i"
-#else // !MES_FULL
-
-  a = add_environment (a, "cons", cell_cons);
-  a = add_environment (a, "display", cell_display);
-  a = add_environment (a, "eq?", cell_eq_p);
-  a = add_environment (a, "newline", cell_newline);
-
-  a = add_environment (a, "make-vector", cell_make_vector);
-
-#if !MES_MINI
-   a = add_environment (a, "*", cell_multiply);
-   a = add_environment (a, "list", cell_list);
-   //
-   a = add_environment (a, "car", cell_car);
-   a = add_environment (a, "cdr", cell_cdr);
-   a = add_environment (a, "+", cell_plus);
-   a = add_environment (a, "quote", cell_quote);
-   a = add_environment (a, "null?", cell_null_p);
-   a = add_environment (a, "=", cell_is_p);
-
-   // a = add_environment (a, "gc", cell_gc);
-   // a = add_environment (a, "apply-env", cell_apply_env);
-   // a = add_environment (a, "eval-env", cell_eval_env);
-   // a = add_environment (a, "cadr", cell_cadr);
-#endif // !MES_MINI
-#endif // !MES_FULL
 
-#if BOOT
-  ////symbols = cons (cell_symbol_label, symbols);
-  a = cons (cons (cell_symbol_label, cell_t), a);
-#endif
-  a = cons (cons (cell_symbol_begin, cell_begin), a);
+  SCM cell_unquote = assq_ref_cache (cell_symbol_unquote, a);
+  SCM cell_unquote_splicing = assq_ref_cache (cell_symbol_unquote_splicing, a);
+  SCM the_unquoters = cons (cons (cell_symbol_unquote, cell_unquote),
+                            cons (cons (cell_symbol_unquote_splicing, cell_unquote_splicing),
+                                  cell_nil));
+  a = acons (cell_symbol_the_unquoters, the_unquoters, a);
 
-  a = add_environment (a, "sc-expand", cell_f);
-
-  a = cons (cons (cell_closure, a), a);
+  a = add_environment (a, "*foo-bar-baz*", cell_nil); // FIXME: some off-by one?
 
-  internal_lookup_symbol (cell_nil);
+  return a;
+}
 
+SCM
+mes_stack (SCM a) ///((internal))
+{
   r0 = a;
   r1 = make_char (0);
   r2 = make_char (0);
   r3 = make_char (0);
   stack = cons (cell_nil, cell_nil);
+  return r0;
+}
 
-  return a;
+SCM
+mes_environment () ///((internal))
+{
+  SCM a = mes_symbols ();
+  return mes_stack (a);
 }
 
 SCM
@@ -1649,17 +1617,71 @@ lookup_macro (SCM x, SCM a)
 }
 
 SCM
-read_input_file_env (SCM e, SCM a)
+read_input_file_env_ (SCM e, SCM a)
 {
   if (e == cell_nil) return e;
-  return cons (e, read_input_file_env (read_env (a), a));
+  return cons (e, read_input_file_env_ (read_env (a), a));
+}
+
+SCM
+read_input_file_env (SCM a)
+{
+  gc_stack (stack);
+  return read_input_file_env_ (read_env (r0), r0);
 }
 
+bool g_dump_p = false;
+
 SCM
 load_env (SCM a)
 {
-  SCM p = read_input_file_env (read_env (a), a);
-  return begin_env (p, a);
+  r3 = read_input_file_env (r0);
+  if (g_dump_p && !g_function)
+    {
+      r1 = symbols;
+      SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cell_nil))));
+      stack = cons (frame, stack);
+      stack = gc (stack);
+      gc_frame (stack);
+      char *p = (char*)g_cells;
+      fputc ('M', stdout);
+      fputc ('E', stdout);
+      fputc ('S', stdout);
+      fputc (stack >> 8, stdout);
+      fputc (stack % 256, stdout);
+      for (int i=0; i<g_free.value * sizeof(scm); i++)
+        fputc (*p++, stdout);
+      return 0;
+    }
+  if (!g_function)
+    r0 = mes_builtins (r0);
+  return begin_env (r3, r0);
+}
+
+SCM
+bload_env (SCM a)
+{
+  g_stdin = fopen ("read-0.mo", "r");
+  char *p = (char*)g_cells;
+  assert (getchar () == 'M');
+  assert (getchar () == 'E');
+  assert (getchar () == 'S');
+  stack = getchar () << 8;
+  stack += getchar ();
+  int c = getchar ();
+  while (c != EOF)
+    {
+      *p++ = c;
+      c = getchar ();
+    }
+  g_free.value = (p-(char*)g_cells) / sizeof (scm);
+  gc_frame (stack);
+  symbols = r1;
+  g_stdin = stdin;
+
+  r0 = mes_builtins (r0);
+
+  return begin_env (r3, r0);
 }
 
 #include "type.c"
@@ -1673,12 +1695,17 @@ load_env (SCM a)
 int
 main (int argc, char *argv[])
 {
+  if (argc > 1 && !strcmp (argv[1], "--dump")) g_dump_p = true;
   if (argc > 1 && !strcmp (argv[1], "--help")) return puts ("Usage: mes < FILE\n");
   if (argc > 1 && !strcmp (argv[1], "--version")) return puts ("Mes 0.2\n");
   g_stdin = stdin;
   SCM a = mes_environment ();
-  display_ (stderr, load_env (a));
+  if (argc > 1 && !strcmp (argv[1], "--load"))
+    display_ (stderr, bload_env (a));
+  else
+    display_ (stderr, load_env (a));
   fputs ("", stderr);
+  gc (stack);
   fprintf (stderr, "\nstats: [%d]\n", g_free.value);
   return 0;
 }
index f589c3cb39368ca677ac4be33e263812245200d2..8bba7ff925e8fd0413731b70f82ce44a37cf3c60 100644 (file)
@@ -26,6 +26,7 @@
 
 ;;; Code:
 
+#f ;; FIXME -- needed for --dump, then --load
 (define (primitive-eval e) (eval-env e (current-module)))
 (define eval eval-env)
 (define (expand-macro e) (expand-macro-env e (current-module)))
diff --git a/module/mes/read-0.mes b/module/mes/read-0.mes
new file mode 100644 (file)
index 0000000..1a7d76a
--- /dev/null
@@ -0,0 +1,145 @@
+;;; -*-scheme-*-
+
+;;; Mes --- Maxwell Equations of Software
+;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
+;;;
+;;; This file is part of Mes.
+;;;
+;;; 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.
+;;;
+;;; 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 Mes.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; read-0.mes - bootstrap reader from Scheme.  Use
+;;;    ./mes --dump < module/mes/read-0.mes > read-0.mo
+;;; to read, garbage collect, and dump this reader; then
+;;;    ./mes --load < tests/gc-3.test
+;;; to use this reader to read and run the minimal gc-3.test
+;;; TODO: complete this reader, remove reader from C.
+
+;;; Code:
+
+(begin
+
+  ;; (define car (make-function 'car 0))
+  ;; (define cdr (make-function 'cdr 1))
+  ;; (define cons (make-function 'cons 1))
+
+  ;; TODO:
+  ;; * use case/cond, expand
+  ;; * etc int/char?
+  ;; * lookup in Scheme
+  ;; * read characters, quote, strings
+
+  (define (read)
+    (read-word (read-byte) '() (current-module)))
+
+  (define (read-input-file)
+    (define (helper x)
+      (if (null? x) x
+          (cons x (helper (read)))))
+    (helper (read)))
+
+  (define-macro (cond . clauses)
+    (list 'if (null? clauses) *unspecified*
+          (if (null? (cdr clauses))
+              (list 'if (car (car clauses))
+                    (list (cons 'lambda (cons '() (cons (car (car clauses)) (cdr (car clauses))))))
+                    *unspecified*)
+              (if (eq? (car (cadr clauses)) 'else)
+                  (list 'if (car (car clauses))
+                        (list (cons 'lambda (cons '() (car clauses))))
+                        (list (cons 'lambda (cons '() (cons *unspecified* (cdr (cadr clauses)))))))
+                  (list 'if (car (car clauses))
+                        (list (cons 'lambda (cons '() (car clauses))))
+                        (cons 'cond (cdr clauses)))))))
+
+  (define (eat-whitespace)
+    (cond
+     ((eq? (peek-byte) 9) (read-byte) (eat-whitespace))
+     ((eq? (peek-byte) 10) (read-byte) (eat-whitespace))
+     ((eq? (peek-byte) 13) (read-byte) (eat-whitespace))
+     ((eq? (peek-byte) 32) (read-byte) (eat-whitespace))
+     ((eq? (peek-byte) 59) (begin (read-line-comment (read-byte))
+                                  (eat-whitespace)))
+     ((eq? (peek-byte) 35) (begin (read-byte)
+                                  (if (eq? (peek-byte) 33) (begin (read-byte)
+                                                                  (read-block-comment (read-byte))
+                                                                  (eat-whitespace))
+                                      (unread-byte 35))))))
+
+  (define (read-block-comment c)
+    (if (eq? c 33) (if (eq? (peek-byte) 35) (read-byte)
+                       (read-block-comment (read-byte)))
+        (read-block-comment (read-byte))))
+
+  ;; (define (read-hex c)
+  ;;   (if (eq? c 10) c
+  ;;       (read-line-comment (read-byte))))
+
+  (define (read-line-comment c)
+    (if (eq? c 10) c
+        (read-line-comment (read-byte))))
+
+  (define (read-list a)
+    (eat-whitespace)
+    (if (eq? (peek-byte) 41) (begin (read-byte) '())
+        ((lambda (w)
+           (if (eq? w '.) (car (read-list a))
+               (cons w (read-list a))))
+         (read-word (read-byte) '() a))))
+
+  ;;(define (read-string))
+
+  (define (lookup-char c a)
+    (lookup (cons (integer->char c) '()) a))
+
+  (define (read-word c w a)
+    (cond
+      ((eq? c -1) '())
+      ((eq? c 10) (if (null? w) (read-word (read-byte) '() a)
+                      (lookup w a)))
+      ((eq? c 32) (read-word 10 w a))
+      ((eq? c 34) (if (null? w) (read-string)
+                      (begin (unread-byte c) (lookup w a))))
+      ((eq? c 35) (cond
+                   ((eq? (peek-byte) 33) (begin (read-byte)
+                                                (read-block-comment (read-byte))
+                                                (read-word (read-byte) w a)))
+                   ((eq? (peek-byte) 40) (read-byte) (list->vector (read-list a)))
+                   ((eq? (peek-byte) 92) (read-byte) (read-character))
+                   ((eq? (peek-byte) 120) (read-byte) (read-hex))
+                   (else (read-word (read-byte) (append w (cons (integer->char c) '())) a))))
+      ((eq? c 39) (if (null? w) (cons (lookup (cons (integer->char c) '()) a)
+                                      (cons (read-word (read-byte) w a) '()))
+                      (begin (unread-byte c)) (lookup w a)))
+      ((eq? c 40) (if (null? w) (read-list a)
+                      (begin (unread-byte c) (lookup w a))))
+      ((eq? c 41) (if (null? w) (cons (lookup (cons (integer->char c) '()) a)
+                                      (cons (read-word (read-byte) w a) '()))
+                      (begin (unread-byte c) (lookup w a))))
+      ((eq? c 44) (cond
+                   ((eq? (peek-byte) 64) (begin (read-byte)
+                                                (cons
+                                                 (lookup (symbol->list 'unquote-splicing) a)
+                                                 (cons (read-word (read-byte) w a) '()))))
+                   (else  (cons (lookup-char c a) (cons (read-word (read-byte) w a)
+                                                        '())))))
+      ((eq? c 96) (cons (lookup-char c a) (cons (read-word (read-byte) w a) '())))
+      ((eq? c 59) (read-line-comment c) (read-word 10 w a))
+      (else (read-word (read-byte) (append w (cons (integer->char c) '())) a))))
+
+  ((lambda (p)
+     ;;(display 'program=) (display p) (newline)
+     (begin-env p (current-module)))
+   (read-input-file)))
index 00eb72d801585a75b854d990f89188d068253795..6230f0873d47cfeb45bd16954949853e0150bdd0 100644 (file)
@@ -19,8 +19,6 @@
  */
 
 #if QUASIQUOTE
-SCM add_environment (SCM a, char const *name, SCM x);
-
 SCM
 unquote (SCM x) ///((no-environment))
 {
@@ -56,17 +54,11 @@ vm_eval_quasiquote ()
   return cons (r2, eval_quasiquote (cdr (r1), r0));
 }
 
-SCM
-the_unquoters = 0;
-
 SCM
 add_unquoters (SCM a)
 {
-  if (the_unquoters == 0)
-    the_unquoters = cons (cons (cell_symbol_unquote, cell_unquote),
-                          cons (cons (cell_symbol_unquote_splicing, cell_unquote_splicing),
-                                cell_nil));
-  return append2 (the_unquoters, a);
+  SCM q = assq_ref_cache (cell_symbol_the_unquoters, a);
+  return append2 (q, a);
 }
 #else // !QUASIQUOTE
 
index 9d7a3233aa4b2a9587bcb9dd96efbc3c385b291a..f021a8e41913c112abc46b406695b8f2ea30ac0c 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes "$@" > a.out
+cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes $MES_FLAGS "$@" > a.out
 #paredit:|
 chmod +x a.out
 exit $?
index 4fc2c205a315813c4e652f97f5cc86be7bfefcd8..fe74f808fbc7524df5fecf79920fe36b8257c138 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-cat ${1-$(dirname $(dirname $0))/share/doc/mes/examples/main.c} | cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes "$@" > a.out
+cat ${1-$(dirname $(dirname $0))/share/doc/mes/examples/main.c} | cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes $MES_FLAGS "$@" > a.out
 chmod +x a.out
 exit $?
 !#
index 41c8d13631b284aab11a402d34d8e9e41105e121..ce3bc70c79b968fe91636f4363f6fed1433753bd 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo -e 'EOF\n___P((()))' | cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes "$@"
+echo -e 'EOF\n___P((()))' | cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes $MES_FLAGS "$@"
 chmod +x a.out
 exit $?
 !#
index 38ce8467bfdac3e3081251df39cb6796eefaf149..d2e6317ccee24224b5d59685afbb9e3706ce4632 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes "$@"
+cat $($(dirname $0)/include.mes $0) $0 /dev/stdin | $(dirname $0)/mes $MES_FLAGS "$@"
 #paredit:|
 exit $?
 !#
index 4cf14190417b36755368f768a3a50b827cea1545..fffcb778c3bdf65cd149bdd58355c1ceeb2b7294 100755 (executable)
@@ -1,7 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-set -x
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
@@ -76,7 +75,7 @@ exit $?
   (define local-answer 41))
 (pass-if-equal "begin 2" 41 (begin local-answer))
 
-(if (not guile?)
-  (pass-if-equal "load" 42 (begin (load "tests/data/load.scm") the-answer)))
+;; (if (not guile?)
+;;   (pass-if-equal "load" 42 (begin (load "tests/data/load.scm") the-answer)))
 
 (result 'report)
index 59baf5ff2dca3b234cbe987abeecd3e564c3e7f4..f2dcadb360249c9844e1a9d25ac7fd64f05e359c 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 113645e6a81a9fe35959b2077d8fa4bcb0563cd9..0fc380258f808279701768e091989bb4ae2d0588 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
@@ -43,6 +43,13 @@ exit $?
                                     (lambda (a b c) (+ a b c)))
                                   6))
 
+(pass-if-equal "lambda"
+               '(1 2 3 4 5)
+               ((lambda (x)
+                  (x 1 2 3 4 5))
+                (lambda (one two three four five)
+                  (list one two three four five))))
+
 (pass-if-equal "values 5"
     '(1 2 3 4 5)
     (call-with-values
index db90afffee7bb0da0c616ba5ab8b24326c3c540e..bfa5440b717e97c676cdaf6271bc0459bcf1c583 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 7f3f6b201ef6735177df8404fac2c8f7e7e87e08..2e19696b958fa9a4730debdb12d2f2c0b508be48 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index c2103926eb2297197fe7231c2a3c23a0e1fa80b4..c1e9f98593e09688f22d223a08871fd9a73286a4 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 40826b4b8552e22a20e94e54fb8427f75dc98d41..4b8d21f64c55b1c57742be976e759a8033866ef4 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 756452bfafbc4ab713a3813acc28d1da208643ef..bf65af7bf565d21341a563733537f01be73758c2 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
diff --git a/tests/read.test b/tests/read.test
new file mode 100755 (executable)
index 0000000..6ae3718
--- /dev/null
@@ -0,0 +1,45 @@
+#! /bin/sh
+# -*-scheme-*-
+# ***REMOVE THIS BLOCK COMMENT INITIALLY***
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
+#paredit:||
+exit $?
+!#
+
+;; FIXME
+(gc)
+
+
+0
+cons
+(cons 0 1)
+(display 0) (newline)
+#t
+#f
+(display #t) (newline)
+(display #f) (newline)
+'foo
+(display 'foo) (newline)
+(display #x16) (newline)
+(display #\A) (newline)
+(display #\newline) (newline)
+(display 'foo)(newline)
+(display '(foo))(newline)
+(display '('foo))(newline)
+(display (cdr '(car . cdr))) (newline)
+(display "foo bar") (newline)
+;;barf
+#!
+barf
+!#
+(display `(display ,display)) (newline)
+(display `(display ,@'(string port))) (newline)
+(display #(0 1 2)) (newline)
+(display (list '(foo
+            #! boo !#
+            ;;(bb 4)
+            )
+          ))
+(newline)
+
+;; TODO: syntax, unsyntax, unsyntax-splicing
index c107c158672957f10eb74b53752df32b588a0cb8..9b872f6f6634193756706ae0c9bce7ba89198acf 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 8388f1b7b73977943534d806607e7ec20b0153aa..0eb6f6e8d67eba6dc6ca9b613ea386b9cbf6016c 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
index 6280ea0f63b968e75a6fdd23d14f659e0e9a126a..e40ba2d2616b41a56dba50e8bfeb7ce505d65586 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # -*-scheme-*-
-echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes "$@"
+echo ' ()' | cat $($(dirname $0)/../scripts/include.mes $0) $0 /dev/stdin | $(dirname $0)/../scripts/mes $MES_FLAGS "$@"
 #paredit:||
 exit $?
 !#
diff --git a/type.c b/type.c
index 61c3b57830c311028443be4f276e7a4242f10f08..50b00673f7018f68df0d222fed9104e30152ff6c 100644 (file)
--- a/type.c
+++ b/type.c
@@ -75,11 +75,6 @@ builtin_p (SCM x)
 }
 
 // Non-types
-SCM
-null_p (SCM x)
-{
-  return x == cell_nil ? cell_t : cell_f;
-}
 
 SCM
 atom_p (SCM x)