Jelajahi Sumber

introduce the paragraph about trapped errors in the python version

Jeremy Siek 2 tahun lalu
induk
melakukan
a415bfe787
1 mengubah file dengan 29 tambahan dan 5 penghapusan
  1. 29 5
      book.tex

+ 29 - 5
book.tex

@@ -1591,6 +1591,20 @@ same input $i$ yields the same output $o$.
  \path[->] (p1) edge [left]  node {interp\_$\mathcal{L}_1$($i$)} (o);
 \end{tikzpicture}
 \end{equation}
+
+\python{We establish the convention that if running the definitional
+  interpreter on a program produces an error, then the meaning of that
+  program is \emph{unspecified}\index{subject}{unspecified behavior}
+  unless the exception raised is a \code{TrappedError}. A compiler for
+  the language is under no obligation regarding programs with
+  unspecified behavior; it does not have to produce an executable, and
+  if it does, that executable can do anything.  On the other hand, if
+  the error is a \code{TrappedError}, then the compiler must produce
+  an executable and it is required to report that an error
+  occurred. To signal an error, exit with a return code of \code{255}.
+  The interpreters in chapters \ref{ch:Ldyn} and \ref{ch:Lgrad} and in
+  section \ref{sec:arrays} use \code{TrappedError}.}
+
 In the next section we see our first example of a compiler.
 
 
@@ -14190,15 +14204,25 @@ class InterpLarray(InterpLtup):
       case BinOp(left, Mult(), right):
           l = self.interp_exp(left, env); r = self.interp_exp(right, env)
           return l * r
+      case Subscript(tup, index, Load()):
+        t = self.interp_exp(tup, env)
+        n = self.interp_exp(index, env)
+        if n < len(t):
+          return t[n]
+        else:
+          raise TrappedError('array index out of bounds')
       case _:
         return super().interp_exp(e, env)
 
   def interp_stmt(self, s, env, cont):
     match s:
       case Assign([Subscript(tup, index)], value):
-        tup = self.interp_exp(tup, env)
-        index = self.interp_exp(index, env)
-        tup[index] = self.interp_exp(value, env)
+        t = self.interp_exp(tup, env)
+        n = self.interp_exp(index, env)
+        if n < len(t):
+          t[n] = self.interp_exp(value, env)
+        else:
+          raise TrappedError('array index out of bounds')
         return self.interp_stmts(cont, env)
       case _:
         return super().interp_stmt(s, env, cont)
@@ -18531,8 +18555,8 @@ class InterpLdyn(InterpLlambda):
         case Tagged(val, tag) if tag == expected_tag:
           return val
         case _:
-          raise Exception('expected Tagged value with '
-                          + expected_tag + ', not ' + ' ' + repr(v))
+          raise TrappedError('expected Tagged value with '
+                             + expected_tag + ', not ' + ' ' + repr(v))
 
   def apply_fun(self, fun, args, e):
       f = self.untag(fun, 'function', e)