beginnings of REPL
[muddle-interpreter.git] / src / main.c
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..b57ee6d
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2017 Keziah Wesley
+
+You can redistribute and/or modify this file under the terms of the
+GNU Affero General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+This file 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
+Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public
+License along with this file. If not, see
+<http://www.gnu.org/licenses/>.
+*/
+
+#include "read.h"
+#include "eval.h"
+#include "print.h"
+#include "object.h"
+
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+// TODO: put these in interpreter-wide ctx object
+char *pool;
+char *vhp_base;
+char *vhp;
+
+// TODO: store these in current PROCESS
+frame *cf;
+object ret;
+object *cst;
+
+// Define the address spaces.
+enum
+{
+  // Max objects that can be in linked lists (must be < 2^32).
+  POOL_OBJCT = 1024,
+  // Max size, in objects, of control stack segment.
+  STACK_OBJCT = 256,
+  // Max size, in objects, of VECTOR heap.
+  VECTOR_OBJCT = 1024,
+  // Max objects reader can handle at once.
+  // TODO: allocate as VECTOR and eliminate this arbitrary limit
+  READER_OBJCT = 64
+};
+
+int
+main ()
+{
+  // The REST pool (in low mem).
+  char *pool_base =
+    mmap (0, POOL_OBJCT * sizeof (object), PROT_READ | PROT_WRITE,
+         MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
+  pool = pool_base;
+
+  // The CONTROL STACKs (TODO: per-PROCESS).
+  object *cst_base =
+    mmap (0, STACK_OBJCT * sizeof (object), PROT_READ | PROT_WRITE,
+         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  cst = cst_base;
+  cf = (frame *) cst;
+  cst += sizeof (frame) / sizeof (object);
+
+  // The VECTOR heap.
+  vhp_base =
+    mmap (0, VECTOR_OBJCT * sizeof (object), PROT_READ | PROT_WRITE,
+         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  vhp = vhp_base;
+
+  // Reader stack (TODO: dynamically allocate as VECTOR).
+  object rst_base[READER_OBJCT];
+  object *rst = rst_base + READER_OBJCT;
+
+  // TODO: push frames for `<REPEAT <PRINT <EVAL <READ>>>>`.
+  // Entire toplevel becomes `for (;;) cf->cont.fn();`
+  char buf[512];
+  ssize_t n;
+  while ((n = read (STDIN_FILENO, buf, sizeof (buf))) > 0)
+    {
+      // mock GC (no object persistence)
+      pool = pool_base;
+      vhp = vhp_base;
+      // terminate input
+      assert (buf[n - 1] == '\n');
+      buf[n - 1] = '\0';
+      // Read a thing
+      reader_stack st;
+      st.pos = rst;
+      st.framelen = 0;
+      const char *p = buf;
+      while (p && p[0])
+       {
+         p = read_token (p, &st);
+       }
+      assert (p);
+      if (!st.framelen)
+        continue;
+      assert (st.framelen == 1);
+      /*
+      // Eval the thing
+      push_frame (eval, new_tuple (st.pos, 1), 0);
+      while (cf->cont.fn)
+       {
+         cf->cont.fn ();
+       }
+      // Print the thing
+      print_object (&ret);
+      */
+      // debugging: print without eval
+      print_object (st.pos);
+      printf ("\n");
+      // Loop!
+    }
+
+  munmap (cst_base, STACK_OBJCT * sizeof (object));
+  munmap (vhp_base, VECTOR_OBJCT * sizeof (object));
+  munmap (pool_base, POOL_OBJCT * sizeof (object));
+  return 0;
+}