fix: content behavior bugs

This commit is contained in:
Brett Broadhurst 2026-03-29 06:21:53 -06:00
parent 2260ccda25
commit 11d99fba38
Failed to generate hash of commit
59 changed files with 243 additions and 31 deletions

View file

@ -24,6 +24,7 @@ const InnerError = error{
pub const ValueInfo = union(enum) {
none,
stack,
value: InternPool.Index,
variable: InternPool.Index,
knot: InternPool.Index,
@ -288,6 +289,7 @@ pub const Builder = struct {
fn ensureLoad(self: *Builder, info: ValueInfo) InnerError!void {
switch (info) {
.none => unreachable, // caller should never load .none
.stack => {},
.value => |index| {
const local_index = try self.getOrPutConstantIndex(index);
try self.addConstOp(.load_const, @intCast(local_index));
@ -451,7 +453,7 @@ fn irUnaryOp(
try builder.ensureLoad(lhs);
try builder.addByteOp(op);
return .none;
return .stack;
}
fn irBinaryOp(
@ -485,7 +487,7 @@ fn irBinaryOp(
try builder.ensureLoad(lhs);
try builder.ensureLoad(rhs);
try builder.addByteOp(op);
return .none;
return .stack;
}
fn irLogicalOp(
@ -567,8 +569,16 @@ fn irStore(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void
try builder.ensureLoad(rhs);
switch (lhs) {
.none => unreachable,
.stack => {},
.value => |_| return sema.fail(src, "could not assign to constant value", .{}),
else => unreachable,
.variable => |index| {
const local_index = try builder.getOrPutConstantIndex(index);
try builder.addConstOp(.store_global, @intCast(local_index));
},
.temp => |temp| try builder.addConstOp(.store, @intCast(temp)),
.stitch => |_| return sema.fail(src, "could not assign to stitch", .{}),
.knot => |_| return sema.fail(src, "could not assign to knot", .{}),
}
try builder.addByteOp(.pop);
@ -577,8 +587,10 @@ fn irStore(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void
fn irLoad(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
const lhs = sema.resolveInst(data.lhs);
if (lhs == .value) return lhs;
try builder.ensureLoad(lhs);
return .none;
return .stack;
}
fn irCondBr(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!ValueInfo {
@ -670,9 +682,8 @@ fn irSwitchBr(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!vo
fn irContentPush(sema: *Sema, builder: *Builder, inst: Ir.Inst.Index) InnerError!void {
const data = sema.ir.instructions[@intFromEnum(inst)].data.un;
const lhs = sema.resolveInst(data.lhs);
if (lhs != .none) {
try builder.ensureLoad(lhs);
}
if (lhs == .none) return error.AnalysisFail;
if (lhs != .stack) try builder.ensureLoad(lhs);
try builder.addByteOp(.stream_push);
}
@ -820,6 +831,16 @@ fn irParam(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
return .{ .temp = builder.addParameter() };
}
fn irDone(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
try builder.addByteOp(.done);
return .none;
}
fn irExit(_: *Sema, builder: *Builder, _: Ir.Inst.Index) !ValueInfo {
try builder.addByteOp(.exit);
return .none;
}
fn analyzeArithmeticArg(
sema: *Sema,
builder: *Builder,
@ -939,6 +960,8 @@ fn analyzeBodyInner(
},
.field_ptr => try irFieldPtr(sema, builder, inst),
.param => try irParam(sema, builder, inst),
.done => try irDone(sema, builder, inst),
.exit => try irExit(sema, builder, inst),
};
try sema.inst_map.put(sema.gpa, inst, result);
}