feat: assignment operations

This commit is contained in:
Brett Broadhurst 2026-04-03 11:24:47 -06:00
parent ecd6017673
commit f82b361005
Failed to generate hash of commit
9 changed files with 79 additions and 48 deletions

View file

@ -783,44 +783,8 @@ fn expr(gi: *GenIr, scope: *Scope, optional_node: ?*const Ast.Node) InnerError!I
.logical_lesser_expr => return binaryOp(gi, scope, node, .cmp_lt),
.logical_lesser_or_equal_expr => return binaryOp(gi, scope, node, .cmp_lte),
.call_expr => return callExpr(gi, scope, node, .call),
.choice_expr => unreachable,
.divert_expr => unreachable,
.selector_expr => return fieldAccess(gi, scope, node),
.assign_stmt => unreachable,
.block_stmt => unreachable,
.content_stmt => unreachable,
.divert_stmt => unreachable,
.return_stmt => unreachable,
.expr_stmt => unreachable,
.choice_stmt => unreachable,
.choice_star_stmt => unreachable,
.choice_plus_stmt => unreachable,
.gather_point_stmt => unreachable,
.gathered_stmt => unreachable,
.function_prototype => unreachable,
.stitch_prototype => unreachable,
.knot_prototype => unreachable,
.function_decl => unreachable,
.stitch_decl => unreachable,
.knot_decl => unreachable,
.const_decl => unreachable,
.var_decl => unreachable,
.list_decl => unreachable,
.temp_decl => unreachable,
.parameter_decl => unreachable,
.ref_parameter_decl => unreachable,
.argument_list => unreachable,
.parameter_list => unreachable,
.switch_stmt => unreachable, // Handled in switchStmt
.switch_case => unreachable, // Handled in switchStmt
.if_stmt => unreachable, // Handled in ifStmt
.multi_if_stmt => unreachable, // Handled in multiIfStmt
.if_branch => unreachable, // Handled in ifStmt and multiIfStmt
.else_branch => unreachable, // Handled in switchStmt, multiIfStmt, and ifStmt
.content => unreachable,
.inline_logic_expr => unreachable,
.inline_if_stmt => unreachable,
.invalid => unreachable,
inline else => |_| unreachable,
}
}
@ -1164,7 +1128,7 @@ fn contentStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) !void {
}
}
fn assignStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
fn assign(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
const astgen = gi.astgen;
const identifier_node = node.data.bin.lhs.?;
const expr_node = node.data.bin.rhs.?;
@ -1178,6 +1142,32 @@ fn assignStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void
return fail(astgen, identifier_node, "unknown identifier", .{});
}
fn assignOp(
gi: *GenIr,
scope: *Scope,
node: *const Ast.Node,
op_inst_tag: Ir.Inst.Tag,
) InnerError!void {
const astgen = gi.astgen;
const identifier_node = node.data.bin.lhs.?;
const expr_node = node.data.bin.rhs.?;
const name_str = try astgen.strFromNode(identifier_node);
if (scope.lookup(name_str.index)) |decl| {
const lhs = try gi.addUnaryNode(.load, decl.inst_index.toRef());
const rhs = try expr(gi, scope, expr_node);
const result = switch (op_inst_tag) {
.add => try gi.addBinaryNode(.add, lhs, rhs),
.sub => try gi.addBinaryNode(.sub, lhs, rhs),
else => unreachable,
};
_ = try gi.addBinaryNode(.store, decl.inst_index.toRef(), result);
return;
}
return fail(astgen, identifier_node, "unknown identifier", .{});
}
fn choiceStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
const astgen = gi.astgen;
const gpa = astgen.gpa;
@ -1540,7 +1530,9 @@ fn blockInner(gi: *GenIr, parent_scope: *Scope, stmt_list: []*Ast.Node) !void {
.var_decl => try varDecl(gi, &child_scope, node),
.const_decl => try varDecl(gi, &child_scope, node),
.temp_decl => try tempDecl(gi, &child_scope, node),
.assign_stmt => try assignStmt(gi, &child_scope, node),
.assign_stmt => try assign(gi, &child_scope, node),
.assign_add_stmt => try assignOp(gi, &child_scope, node, .add),
.assign_sub_stmt => try assignOp(gi, &child_scope, node, .sub),
.content_stmt => try contentStmt(gi, &child_scope, node),
.choice_stmt => try choiceStmt(gi, &child_scope, node),
.expr_stmt => try exprStmt(gi, &child_scope, node),