lang: struct consts migrate to const globals, inline fallback (PLAN-CONST-AGG step 4)
A struct constant whose every field serializes — literals, enum tags,
nested aggregates, and (new) const EXPRESSIONS over named consts /
const-aggregate leaves ('r = K + 1', 'g = LIT.r', 'b = A[1]') — becomes
an immutable global: one storage, reads load/GEP it, '@LIT' is
addressable, dead-global elimination drops unused ones. constExprValue
gained a fold-through tail (evalConstIntExpr/evalConstFloatExpr,
source-aware), which also enables const-expression ELEMENTS in array
consts.
A const with a NON-serializable field (a call, a runtime read) keeps
inline re-lowering, and that per-use evaluation is now the documented
contract for the class (pinned: 'CALL.r' reads 1 then 2, side effects
run per use; '#run' is the evaluate-once tool).
Examples: 0180 (migrated shapes + @ptr + copy independence),
0181 (the inline-fallback contract). m3te (23/23) + game rebuilt green.
This commit is contained in:
@@ -91,7 +91,23 @@ pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ?
|
||||
// an enum field inside a global struct) serializes to its tag int
|
||||
// against the leaf's declared enum type.
|
||||
.enum_literal => |el| self.constEnumLiteral(&el, expected_ty, expr.span),
|
||||
else => null,
|
||||
// Any other shape: a compile-time CONST EXPRESSION over named consts
|
||||
// and const-aggregate leaves (`r = K + 1`, `g = LIT.r`, `b = K[1]`)
|
||||
// serializes through the shared folders — source-aware, like every
|
||||
// const fold. A non-foldable expression (a call, a runtime read)
|
||||
// stays null: the caller keeps its fallback (inline re-lowering for
|
||||
// struct consts, a loud diagnostic for globals/array consts).
|
||||
else => blk: {
|
||||
const ctx = SourceConstCtx{ .lowering = self, .frame = null };
|
||||
if (self.isIntEx(expected_ty)) {
|
||||
if (program_index_mod.evalConstIntExpr(expr, ctx)) |v| break :blk inst_mod.ConstantValue{ .int = v };
|
||||
}
|
||||
if (isFloat(expected_ty)) {
|
||||
if (program_index_mod.evalConstFloatExpr(expr, ctx)) |v| break :blk inst_mod.ConstantValue{ .float = v };
|
||||
if (program_index_mod.evalConstIntExpr(expr, ctx)) |v| break :blk inst_mod.ConstantValue{ .float = @floatFromInt(v) };
|
||||
}
|
||||
break :blk null;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user