From 62ee85ee5fa3edd6d5ed2cec029f9f66d54a10f6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 16 Jun 2023 14:54:38 -0700 Subject: [PATCH] explain how control flow is not acyclic --- codebase/compiler/Codebase-Compiler-Binder.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/codebase/compiler/Codebase-Compiler-Binder.md b/codebase/compiler/Codebase-Compiler-Binder.md index 7d5a87e..ffcb0f6 100644 --- a/codebase/compiler/Codebase-Compiler-Binder.md +++ b/codebase/compiler/Codebase-Compiler-Binder.md @@ -143,11 +143,14 @@ Containers and declarations are the same as for symbol binding, so those concept Declarations introduce type information; containers form the scope where type information is relevant. Other nodes may narrow, so they also interact with control flow. -The control flow graph is a directed acyclic graph; that means each relevant node points to its antecedents (parents). +The control flow graph is a directed graph; that means each relevant node points to its antecedents (parents)—the nodes that come *before* it in control flow. Specifically, each node can have a `flowNode`; this flow node has a `kind` and one or more `antecedents`. As the binder walks the tree, `bindWorker` assigns the current flow node to specific nodes that can introduce type information. Specific nodes that affect control flow alter the current flow node, such as `bindWhileStatement`. +Notably, loops make the graph cyclic: the pre-while `FlowLabel` points both to the flow node before the loop and also the flow node at the bottom of the loop. +That's because nodes inside loops might introduce type information, and this information should affect the next iteration of the loop. + Here's an example: ```ts @@ -175,7 +178,6 @@ That check narrows `string | number` to `string`. Finally, the last `return x` starts with the post-if flow node, which unions the types that result from the `then` and `else` branches. But because the `then` branch returns, it doesn't contribute anything to the union; the resulting type is just `number`. - ## Emit flags TODO: Missing completely