@@ -183,7 +183,9 @@ object Semantic:
183
183
* abstract interpreter, because when an error happens, we always return
184
184
* the bottom value `Hot` for an expression. It is not a threat for
185
185
* termination because when an error happens, we stop the fixed point
186
- * computation at the end of the iteration where the error happens.
186
+ * computation at the end of the iteration where the error happens. Care
187
+ * must be paid to tests of errors, monotonicity will be broken if we simply
188
+ * ignore the test errors (See `TryReporter`).
187
189
*
188
190
* Note: It's tempting to use location of trees as key. That should
189
191
* be avoided as a template may have the same location as its single
@@ -240,7 +242,11 @@ object Semantic:
240
242
/** The immutable wrapper is intended to be stored as key in the heap. */
241
243
private class ImmutableTreeWrapper (val tree : Tree ) extends TreeWrapper
242
244
243
- /** For queries on the heap, reuse the same wrapper to avoid unnecessary allocation. */
245
+ /** For queries on the heap, reuse the same wrapper to avoid unnecessary allocation.
246
+ *
247
+ * A `MutableTreeWrapper` is only ever used temporarily for querying a map,
248
+ * and is never inserted to the map.
249
+ */
244
250
private class MutableTreeWrapper extends TreeWrapper :
245
251
var queryTree : Tree | Null = null
246
252
def tree : Tree = queryTree match
@@ -251,9 +257,13 @@ object Semantic:
251
257
/** The cache for expression values from last iteration */
252
258
private var last : ExprValueCache = Map .empty
253
259
254
- /** The updated cache for expression values based on the cache values from the last iteration
260
+ /** The output cache for expression values
261
+ *
262
+ * The output cache is computed based on the cache values `last` from the
263
+ * last iteration.
255
264
*
256
- * Both `last` and `current` are required to make sure an expression is evaluated once in each iteration.
265
+ * Both `last` and `current` are required to make sure an encountered
266
+ * expression is evaluated once in each iteration.
257
267
*/
258
268
private var current : ExprValueCache = Map .empty
259
269
@@ -473,8 +483,15 @@ object Semantic:
473
483
/** A TryReporter cannot be simply thrown away
474
484
*
475
485
* Either `abort` should be called or the errors be reported.
486
+ *
487
+ * If errors are ignored and `abort` is not called, the monotonicity of the
488
+ * computation function is not guaranteed, thus termination of fixed-point
489
+ * computation becomes a problem.
476
490
*/
477
491
trait TryReporter extends Reporter :
492
+ /**
493
+ * Revert the cache to previous state.
494
+ */
478
495
def abort ()(using Cache ): Unit
479
496
def errors : List [Error ]
480
497
0 commit comments