You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The compiler's intermediate representation for compiled expressions is a tree of objects derived from an abstract base class IR.Values.Value. Various subclasses of Value represent individual CIL instructions or occasionally a short fixed sequence of CIL instructions.
When a value needs to be composed from the result of executing a list of Value, the compiler uses an IR.Values.BLOCK, which represents the single value result of executing a list of instructions. However, BLOCK doesn't actually hold a list of Values. Instead, it holds the CIL assembly language text that resulted from generating those Value.
This representation doesn't work well with the more complex code now being generated for expressions, where expressions can contain entire trees and lists of statements, including loops and exception handling - we don't necessarily always have the contents of a block when we want to add it as a child of some Value that will eventually consume it, and we'd potentially need to fold the entire generate-IL pass into the compile-expressions pass to get it (if anything we want to do the opposite and push more work from compile-expressions into generate-IL, where it's not in the edit loop of the VSCE)
For example, we might need to generate a block to hold the operations needed to destructure a tuple, and if that tuple is the result of an if expression, that is also a block. However, the if expression's block won't have instructions added to it to compute its result until the generate-IL pass, but the destructure wants it in the compile-expressions pass. This results in garbled IL code or an empty block exception when the incomplete block is consumed before it's filled with code.
IR.Values.BLOCK should be reworked to actually hold a list of Value, so when we have statements nested in expressions and vice versa, we're using a single IR representation that always nests cleanly. We'll be able to create blocks in the compile-expressions pass and reference them for type information, even if they won't acquire any actual instructions until the generate-IL pass. And when the generate-IL pass fills in those instructions, they'll be correctly picked up by any parent IR.Value that references them.
The text was updated successfully, but these errors were encountered:
The compiler's intermediate representation for compiled expressions is a tree of objects derived from an abstract base class
IR.Values.Value
. Various subclasses ofValue
represent individual CIL instructions or occasionally a short fixed sequence of CIL instructions.When a value needs to be composed from the result of executing a list of
Value
, the compiler uses anIR.Values.BLOCK
, which represents the single value result of executing a list of instructions. However,BLOCK
doesn't actually hold a list ofValue
s. Instead, it holds the CIL assembly language text that resulted from generating thoseValue
.This representation doesn't work well with the more complex code now being generated for expressions, where expressions can contain entire trees and lists of statements, including loops and exception handling - we don't necessarily always have the contents of a block when we want to add it as a child of some Value that will eventually consume it, and we'd potentially need to fold the entire generate-IL pass into the compile-expressions pass to get it (if anything we want to do the opposite and push more work from compile-expressions into generate-IL, where it's not in the edit loop of the VSCE)
For example, we might need to generate a block to hold the operations needed to destructure a tuple, and if that tuple is the result of an if expression, that is also a block. However, the if expression's block won't have instructions added to it to compute its result until the generate-IL pass, but the destructure wants it in the compile-expressions pass. This results in garbled IL code or an empty block exception when the incomplete block is consumed before it's filled with code.
IR.Values.BLOCK
should be reworked to actually hold a list ofValue
, so when we have statements nested in expressions and vice versa, we're using a single IR representation that always nests cleanly. We'll be able to create blocks in the compile-expressions pass and reference them for type information, even if they won't acquire any actual instructions until the generate-IL pass. And when the generate-IL pass fills in those instructions, they'll be correctly picked up by any parentIR.Value
that references them.The text was updated successfully, but these errors were encountered: