about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-05-18 19:48:41 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-05-18 20:01:11 -0700
commit837926751a5bc1abe60cb49e8b5243705c6591da (patch)
tree65171df0bbb9e5007fa586d501c64528defc1bcc
parent6934436de9ba93eb27a9101bc61c85cbb814f776 (diff)
downloadmu-837926751a5bc1abe60cb49e8b5243705c6591da.tar.gz
shell: add a lot of error-checking
-rw-r--r--shell/evaluate.mu145
-rw-r--r--shell/print.mu8
-rw-r--r--shell/sandbox.mu6
3 files changed, 158 insertions, 1 deletions
diff --git a/shell/evaluate.mu b/shell/evaluate.mu
index 839aa6b5..5b58fc08 100644
--- a/shell/evaluate.mu
+++ b/shell/evaluate.mu
@@ -237,6 +237,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "Q", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     trace-text trace, "eval", "saving global binding"
     var first-arg/eax: (addr cell) <- lookup *first-arg-ah
     var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
@@ -282,6 +292,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "Q", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     trace-text trace, "eval", "mutating binding"
     var first-arg/eax: (addr cell) <- lookup *first-arg-ah
     var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
@@ -308,6 +328,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "S2", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     # if first arg is nil, short-circuit
     var out-ah/eax: (addr handle cell) <- copy _out-ah
     var out/eax: (addr cell) <- lookup *out-ah
@@ -346,6 +376,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "S2", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     # if first arg is not nil, short-circuit
     var out-ah/eax: (addr handle cell) <- copy _out-ah
     var out/eax: (addr cell) <- lookup *out-ah
@@ -363,6 +403,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate second-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "U2", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     trace-higher trace
     return
   }
@@ -387,6 +437,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "S", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     rest-ah <- get rest, right
     rest <- lookup *rest-ah
     var branch-ah/edi: (addr handle cell) <- get rest, left
@@ -443,11 +503,31 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
       increment call-number
       evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
       debug-print "W", 4/fg, 0/bg
+      # errors? skip
+      {
+        compare trace, 0
+        break-if-=
+        var error?/eax: boolean <- has-errors? trace
+        compare error?, 0/false
+        break-if-=
+        trace-higher trace
+        return
+      }
       var guard-a/eax: (addr cell) <- lookup *guard-ah
       var done?/eax: boolean <- nil? guard-a
       compare done?, 0/false
       break-if-!=
       evaluate-exprs rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
+      # errors? skip
+      {
+        compare trace, 0
+        break-if-=
+        var error?/eax: boolean <- has-errors? trace
+        compare error?, 0/false
+        break-if-=
+        trace-higher trace
+        return
+      }
       loop
     }
     trace-text trace, "eval", "loop terminated"
@@ -474,6 +554,16 @@ fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (han
     increment call-number
     evaluate left-ah, left-out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
     debug-print "B", 4/fg, 0/bg
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     # a trip wire in case we're running without a trace (e.g. when loading the initial state from disk)
     {
       compare trace, 0
@@ -572,6 +662,15 @@ fn apply-function params-ah: (addr handle cell), args-ah: (addr handle cell), bo
   var new-env-h: (handle cell)
   var new-env-ah/esi: (addr handle cell) <- address new-env-h
   push-bindings params-ah, args-ah, env-h, new-env-ah, trace
+  # errors? skip
+  {
+    compare trace, 0
+    break-if-=
+    var error?/eax: boolean <- has-errors? trace
+    compare error?, 0/false
+    break-if-=
+    return
+  }
   #
   evaluate-exprs body-ah, out, new-env-h, globals, trace, screen-cell, keyboard-cell, call-number
 }
@@ -594,6 +693,15 @@ fn evaluate-exprs _exprs-ah: (addr handle cell), out: (addr handle cell), env-h:
       increment call-number
       evaluate curr-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
       debug-print "X", 7/fg, 0/bg
+      # errors? skip
+      {
+        compare trace, 0
+        break-if-=
+        var error?/eax: boolean <- has-errors? trace
+        compare error?, 0/false
+        break-if-=
+        return
+      }
     }
     #
     exprs-ah <- get exprs, right
@@ -669,6 +777,13 @@ fn push-bindings _params-ah: (addr handle cell), _args-ah: (addr handle cell), o
   var _args/eax: (addr cell) <- lookup *args-ah
   var args/edi: (addr cell) <- copy _args
   # params is now a pair, so args must be also
+  {
+    var args-nil?/eax: boolean <- nil? args
+    compare args-nil?, 0/false
+    break-if-=
+    error trace, "not enough args to bind"
+    return
+  }
   var args-type/eax: (addr int) <- get args, type
   compare *args-type, 0/pair
   {
@@ -682,6 +797,16 @@ fn push-bindings _params-ah: (addr handle cell), _args-ah: (addr handle cell), o
   var first-param-ah/eax: (addr handle cell) <- get params, left
   var first-arg-ah/ecx: (addr handle cell) <- get args, left
   push-bindings first-param-ah, first-arg-ah, old-env-h, intermediate-env-ah, trace
+  # errors? skip
+  {
+    compare trace, 0
+    break-if-=
+    var error?/eax: boolean <- has-errors? trace
+    compare error?, 0/false
+    break-if-=
+    trace-higher trace
+    return
+  }
   var remaining-params-ah/eax: (addr handle cell) <- get params, right
   var remaining-args-ah/ecx: (addr handle cell) <- get args, right
   push-bindings remaining-params-ah, remaining-args-ah, *intermediate-env-ah, env-ah, trace
@@ -1512,6 +1637,16 @@ fn evaluate-backquote _in-ah: (addr handle cell), _out-ah: (addr handle cell), e
     var in-unquote-payload-ah/eax: (addr handle cell) <- get in-left, right
     increment call-number
     evaluate in-unquote-payload-ah, out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
+    # errors? skip
+    {
+      compare trace, 0
+      break-if-=
+      var error?/eax: boolean <- has-errors? trace
+      compare error?, 0/false
+      break-if-=
+      trace-higher trace
+      return
+    }
     # while (*out-ah != null) out-ah = cdr(out-ah)
     {
       var out/eax: (addr cell) <- lookup *out-ah
@@ -1540,6 +1675,16 @@ fn evaluate-backquote _in-ah: (addr handle cell), _out-ah: (addr handle cell), e
   debug-print "`(l", 3/fg, 0/bg
   evaluate-backquote in-left-ah, out-left-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
   debug-print "`r)", 3/fg, 0/bg
+  # errors? skip
+  {
+    compare trace, 0
+    break-if-=
+    var error?/eax: boolean <- has-errors? trace
+    compare error?, 0/false
+    break-if-=
+    trace-higher trace
+    return
+  }
   var in-right-ah/ecx: (addr handle cell) <- get in, right
   var out-right-ah/edx: (addr handle cell) <- get out, right
   debug-print "`r(", 3/fg, 0/bg
diff --git a/shell/print.mu b/shell/print.mu
index 542c59a4..1658ec07 100644
--- a/shell/print.mu
+++ b/shell/print.mu
@@ -205,7 +205,13 @@ fn print-pair _in: (addr cell), out: (addr stream byte), trace: (addr trace) {
     {
       compare right-addr, 0
       break-if-!=
-      abort "null encountered"
+      # This shouldn't ever happen in a regular REPL cycle.
+      # However, we also use print-cell when emitting the trace. And that can
+      # happen after there's been an error in the trace.
+      write out, "...NULL!"
+      error trace, "right is NULL"
+      trace-higher trace
+      return
     }
     {
       var right-nil?/eax: boolean <- nil? right-addr
diff --git a/shell/sandbox.mu b/shell/sandbox.mu
index 737723b9..1625125d 100644
--- a/shell/sandbox.mu
+++ b/shell/sandbox.mu
@@ -610,6 +610,12 @@ fn run _in-ah: (addr handle gap-buffer), out: (addr stream byte), globals: (addr
     return
   }
   macroexpand read-result-ah, globals, trace
+  var error?/eax: boolean <- has-errors? trace
+  {
+    compare error?, 0/false
+    break-if-=
+    return
+  }
   var nil-h: (handle cell)
   var nil-ah/eax: (addr handle cell) <- address nil-h
   allocate-pair nil-ah