Documentation
¶
Overview ¶
Package construct is the single authoritative description of which HowlFrame language constructs the standalone bytecode target can actually execute.
It exists because internal/bytecode's compileNode switch used to have no default case: any head symbol it did not recognize compiled to zero instructions, silently, with exit code 0 (bugs.md #45). Nothing downstream could catch that - the VM's opcode dispatch fails closed, but no instruction was ever emitted to dispatch on.
This package is deliberately backend-independent, exactly like internal/capability (the precedent established by improvements.md #94): it imports only internal/ast, and nothing here may import internal/bytecode, internal/hfir, or any backend. Consumers wire it in themselves - internal/hfir/constructs.go turns Scan's violations into HFIR diagnostics, and internal/bytecode keeps an independent fail-closed default as a backstop.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SupportedNames ¶
func SupportedNames() []string
SupportedNames returns every construct classified Supported, in name order. internal/bytecode's drift test uses it to prove the registry and compileNode's switch cannot diverge silently.
Types ¶
type Entry ¶
type Entry struct {
// Name is the canonical HowlFrame head symbol.
Name string
// Support is the classification.
Support Support
// Tracker names the backlog item that owns closing this gap, for
// Unsupported entries that have one. Empty when no item owns it.
Tracker string
// Note is the one-line evidence for the classification.
Note string
// Opaque reports that this construct's children are not compiled as
// nested constructs, so Scan must not descend into them. Verified
// against compileNode: achieve stringifies its operands via
// ast.Stringify, and the others read child .Value fields directly.
Opaque bool
}
Entry is one construct's classification for the bytecode target.
type SubForm ¶
SubForm is a head symbol that only carries meaning as a child of a specific parent construct, and that the parent's own compileNode case destructures rather than dispatching on. These are why the support check has to run over the AST and not over HFIR node kinds: hfir.LowerAST names a node's Kind after the head of *every* list, so a catch clause becomes a node with Kind "catch" even though it never reaches compileNode in head position, and a deny-list over HFIR kinds would reject every try_let program (bugs.md #45's implementation caveat).
type Support ¶
type Support int
Support is how the standalone bytecode target handles a construct.
const ( // Supported means internal/bytecode's compileNode has a real case for // this head and emits instructions the VM can execute. Supported Support = iota // CompileTimeOnly means the construct legitimately emits no // instructions: it is either a pure annotation with no runtime meaning, // or a form that an earlier pass consumes before lowering ever sees it. // These must keep compiling and running unchanged. CompileTimeOnly // Unsupported means the construct has real runtime meaning that the // bytecode target cannot express. Compiling it must fail closed rather // than silently drop it. Unsupported )
type Violation ¶
type Violation struct {
// Name is the offending head symbol.
Name string
// Tracker names the backlog item that owns the gap, when one exists.
Tracker string
// Reason states why the construct cannot be compiled.
Reason string
Line int
Column int
}
Violation is one construct the bytecode target cannot execute, located in the source that declared it.
func Scan ¶
Scan walks a checked AST and reports every construct the bytecode target cannot execute, in source order.
It is context-aware on purpose. A list's head is only classified when the list actually sits in construct position - not when it is a let binding, a parameter list, a dict pair, or a sub-form its parent destructures itself. Scan stops descending at the first offending construct so one unsupported form does not cascade into a violation for every identifier inside it.