Closed inkytonik closed 3 years ago
Actually this requires a full audit, since I just fixed a bug in the writerWrite capability (as part of the prelude addition). Previously, if the thing that provides the string to write errors out (e.g., because we try to read the string from a non-existent file) then the writerWrite would crash. It now checks for an error.
I suspect there are other places where this can happen, either in the main interpreters or in the primitives, so we should check properly.
In the case of the reference interpreter it may be useful to move to a more monadic approach that threads the environment state and tracks errors.
We also need more tests of this kind of thing, such as
ExecTestError(
“vector with internal error”,
“[prim IntAdd(1,1), prim IntDiv(1, 0)]”,
“cooma: Error executing integer div: BigInteger divide by zero”
),
Another example: in the RecConcat
primitive, if one of the arguments is an error we don't pass that up the chain. In fact, we return some strange error runtime value that is based on the two values, even if only one of them is an error.
After consideration we've decided to go with exceptions for reporting these errors instead of propagating error values.
One thing to bear in mind for this design: if an error occurs when executing a particular IR node, you can pass the node itself back as part of the error/exception. The frontend/driver has access to positions, so this should mean that the error can be reported using Kiama's messaging module. That will allow the output to include the location of the error in terms of the source code.
E.g.,
{ a = 1, b = prim IntDiv(1,0) }
should error.See approach used in vectors implementation which returns the first such error if there is one.