shithub: MicroHs

Download patch

ref: 7df2ea1db57da7525c242edecf8ad06d26cf5b28
parent: 8c1aa2102608014b1f88aeba30c78e1f7bf40f67
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Mon Jan 1 13:35:09 EST 2024

Start of execio conversion

--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -674,7 +674,7 @@
 /* Needed during reduction */
 NODEPTR intTable[HIGH_INT - LOW_INT];
 NODEPTR combFalse, combTrue, combUnit, combCons, combPair;
-NODEPTR combCC, combZ, combIOBIND;
+NODEPTR combCC, combZ, combIOBIND, combIORETURN;
 NODEPTR combLT, combEQ, combGT;
 
 /* One node of each kind for primitives, these are never GCd. */
@@ -824,6 +824,7 @@
     case T_CC: combCC = n; break;
     case T_Z: combZ = n; break;
     case T_IO_BIND: combIOBIND = n; break;
+    case T_IO_RETURN: combIORETURN = n; break;
 #if WANT_STDIO
     case T_IO_STDIN:  SETTAG(n, T_PTR); PTR(n) = stdin;  break;
     case T_IO_STDOUT: SETTAG(n, T_PTR); PTR(n) = stdout; break;
@@ -846,6 +847,7 @@
     case T_CC: combCC = n; break;
     case T_Z: combZ = n; break;
     case T_IO_BIND: combIOBIND = n; break;
+    case T_IO_RETURN: combIORETURN = n; break;
 #if WANT_STDIO
     case T_IO_STDIN:  SETTAG(n, T_PTR); PTR(n) = stdin;  break;
     case T_IO_STDOUT: SETTAG(n, T_PTR); PTR(n) = stdout; break;
@@ -2066,7 +2068,7 @@
   FREE(rnf_bits);
 }
 
-NODEPTR execio(NODEPTR n);
+void execio(NODEPTR *);
 
 /* Evaluate a node, returns when the node is in WHNF. */
 void
@@ -2348,8 +2350,15 @@
       rnf(xi, ARG(TOP(1))); POP(2); n = TOP(-1); GOIND(combUnit);
 
     case T_IO_PERFORMIO:
+      CHECK(1);
       if (doing_rnf) RET;
-      CHKARGEV1(x = execio(x)); GOIND(x);
+      execio(&ARG(TOP(0)));       /* run IO action */
+      x = ARG(TOP(0));           /* should be RETURN e */
+      if (GETTAG(x) != T_AP || GETTAG(FUN(x)) != T_IO_RETURN)
+        ERR("PERFORMIO");
+      POP(1);
+      n = TOP(-1);
+      GOIND(ARG(x));
 
     case T_IO_BIND:
     case T_IO_THEN:
@@ -2396,7 +2405,7 @@
 /* This is the interpreter for the IO monad operations. */
 /* It takes a monadic expression and returns the unwrapped expression (unevaluated). */
 NODEPTR
-execio(NODEPTR n)
+execio1(NODEPTR n)
 {
   stackptr_t stk = stack_ptr;
   NODEPTR f, x;
@@ -2455,7 +2464,7 @@
         }
       }
 
-      x = execio(ARG(TOP(1)));  /* first argument, unwrapped */
+      x = execio1(ARG(TOP(1)));  /* first argument, unwrapped */
 
       /* Do a GC check, make sure we keep the x live */
       GCCHECKSAVE(x, 1);
@@ -2466,7 +2475,7 @@
       goto top;
     case T_IO_THEN:
       CHECKIO(2);
-      (void)execio(ARG(TOP(1))); /* first argument, unwrapped, ignored */
+      (void)execio1(ARG(TOP(1))); /* first argument, unwrapped, ignored */
       n = ARG(TOP(2));          /* second argument, the continuation */
       POP(3);
       goto top;
@@ -2588,7 +2597,7 @@
           goto top;
         } else {
           /* Normal execution: */
-          n = execio(ARG(TOP(1))); /* execute first argument */
+          n = execio1(ARG(TOP(1))); /* execute first argument */
           cur_handler = h->hdl_old; /* restore old handler */
           FREE(h);
           RETIO(n);             /* return result */
@@ -2670,6 +2679,16 @@
   }
 }
 
+void
+execio(NODEPTR *np)
+{
+  NODEPTR n = execio1(*np);
+  GCCHECKSAVE(n, 1);
+  *np = alloc_node(T_AP);
+  FUN(*np) = combIORETURN;
+  ARG(*np) = n;
+}
+
 heapoffs_t
 memsize(const char *p)
 {
@@ -2803,15 +2822,12 @@
   }
 #endif
   run_time -= GETTIMEMILLI();
-  NODEPTR res = execio(prog);
-  res = evali(res);
+  execio(&prog);
+  if (GETTAG(prog) != T_AP || GETTAG(FUN(prog)) != T_IO_RETURN)
+    ERR("main execio");
+  NODEPTR res = evali(ARG(prog));
   run_time += GETTIMEMILLI();
 #if WANT_STDIO
-  if (0) {
-    FILE *out = fopen("prog.comb", "w");
-    print(out, prog, 1);
-    fclose(out);
-  }
   if (verbose) {
     if (verbose > 1) {
       PRINT("\nmain returns ");
--