Documentation
¶
Overview ¶
Package lower transforms Core IR into Statement IR.
This is a PROJECTION, not a translation: information is deliberately lost (type variables, effects, row polymorphism) because target languages cannot express these concepts. The loss is explicit and controlled.
No file in this package may import internal/gen/golang/.
Index ¶
- func FlattenBlock(e core.CoreExpr, cti types.CoreTypeInfo) ([]stmt.Stmt, stmt.Expr)
- func LowerExpr(e core.CoreExpr, cti types.CoreTypeInfo) stmt.Expr
- func LowerMatchExpr(m *core.Match, cti types.CoreTypeInfo) stmt.Expr
- func LowerMatchStmt(m *core.Match, cti types.CoreTypeInfo) stmt.Stmt
- func LowerMultiModule(modules map[string]*ModuleInput, pkgName string) (*stmt.Program, error)
- func LowerProgram(coreProg *core.Program, cti types.CoreTypeInfo, astFile *ast.File, ...) (*stmt.Program, error)
- func LowerTypeDecl(td *ast.TypeDecl) stmt.TypeDecl
- func ProjectASTType(t ast.Type) stmt.ResolvedType
- func ProjectType(t types.Type) stmt.ResolvedType
- func QualifyFuncRefs(prog *stmt.Program)
- type ModuleInput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FlattenBlock ¶
FlattenBlock converts a Core expression (typically a let-chain) into a sequence of statements plus a final return expression.
Core IR uses nested Let/LetRec for sequential computation:
Let("a", e1,
Let("b", e2,
body))
This flattens to:
var a = e1 var b = e2 return body
This is the heart of the Statement IR lowering — it bridges the gap between functional let-chains and imperative statement sequences.
func LowerExpr ¶
LowerExpr converts a Core expression into a Statement IR expression. For complex expressions (Let, Match, If-as-statement), it may also produce statements that must be prepended to the enclosing block. Use LowerBlock for let-chain flattening; this function handles the expression-level conversion.
func LowerMatchExpr ¶
LowerMatchExpr converts a Core Match into a Statement IR expression.
In practice this is only reachable for non-tail-position matches (e.g. `1 + match x { ... }`). Tail-position matches are intercepted by FlattenBlock and routed to LowerMatchStmt, which produces a proper SwitchStmt or if-chain. The Phase 2C corpus does not exercise non-tail-position matches.
For the one supported shape — a 2-arm match where the first arm is a LitPattern and both bodies are simple expressions — we emit an IfExpr. Anything else PANICS rather than silently producing a lossy approximation (the previous behavior was to return `lowerExpr(arms[0].Body)`, which produced a wrong-but-running result for any match it didn't recognize).
If you hit this panic, the right fix is usually to (a) refactor the AILANG source so the match is in tail position, or (b) extend FlattenBlock to bind the match's result into a temp via a hoisted SwitchStmt and then reference that temp.
func LowerMatchStmt ¶
LowerMatchStmt converts a Core Match into a Statement IR SwitchStmt. This handles all 7 pattern types by dispatching to the appropriate Statement IR construct:
- ConstructorPattern → SwitchStmt with tag-based cases
- LitPattern → SwitchStmt or if-chain
- VarPattern/WildcardPattern → default case
- ListPattern, TuplePattern, RecordPattern → if-chain with destructuring
func LowerMultiModule ¶
LowerMultiModule handles multi-module compilation by lowering each module and merging the results into a single Program.
func LowerProgram ¶
func LowerProgram( coreProg *core.Program, cti types.CoreTypeInfo, astFile *ast.File, pkgName string, ) (*stmt.Program, error)
LowerProgram converts a Core program + AST (for type declarations) into a Statement IR Program ready for emission.
This is the main entry point for the lowering pipeline:
pipeline.Run(ModeCheck) → Core + CoreTypeInfo + AST lower.LowerProgram(core, cti, ast) → stmt.Program emitter.Emit(program) → Go/Rust/etc. source code
func LowerTypeDecl ¶
LowerTypeDecl converts an AST type declaration into a Statement IR TypeDecl.
func ProjectASTType ¶
func ProjectASTType(t ast.Type) stmt.ResolvedType
ProjectASTType converts an ast.Type (from surface syntax) into a stmt.ResolvedType. Used for type declarations where we have AST types rather than inferred types.Type.
func ProjectType ¶
func ProjectType(t types.Type) stmt.ResolvedType
ProjectType converts a types.Type (from the type checker) into a stmt.ResolvedType (for the emitter). This is the semantic boundary where AILANG's rich type system is projected into target-language types.
Rules:
- Primitive types (int, float, bool, string, ()) → PrimitiveType
- Named types (ADTs, records) → NamedType with Pointer=true for ADTs
- List/Array → SliceType
- Tuple → TupleType
- Function → FuncType
- Type variables → InterfaceType (erased — the type was polymorphic)
- Unknown/nil → InterfaceType (defensive)
func QualifyFuncRefs ¶
QualifyFuncRefs rewrites VarRef nodes that reference top-level functions to use the full module-prefixed name that matches the Go function definition. Core IR uses bare Var references for same-module calls; we rewrite those to include the module__name prefix (matching what funcName() produces in the emitter).
Types ¶
type ModuleInput ¶
ModuleInput bundles the artifacts needed to lower one module.