Skip to content

Commit

Permalink
feat: Composite operators
Browse files Browse the repository at this point in the history
closes #78
  • Loading branch information
giann committed Jan 30, 2025
1 parent 76dcf0a commit e23b930
Show file tree
Hide file tree
Showing 7 changed files with 640 additions and 333 deletions.
1 change: 1 addition & 0 deletions src/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,7 @@ pub const Slot = u32;
pub const NamedVariable = struct {
name: []const TokenIndex,
value: ?Node.Index,
assign_token: ?TokenIndex,
slot: Slot,
slot_type: SlotType,
slot_final: bool,
Expand Down
85 changes: 85 additions & 0 deletions src/Codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2919,6 +2919,7 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Er
const components = self.ast.nodes.items(.components)[node].NamedVariable;
const locations = self.ast.nodes.items(.location);
const type_defs = self.ast.nodes.items(.type_def);
const tags = self.ast.tokens.items(.tag);

var get_op: Chunk.OpCode = undefined;
var set_op: Chunk.OpCode = undefined;
Expand Down Expand Up @@ -2955,8 +2956,92 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Er
);
}

switch (tags[components.assign_token.?]) {
.PlusEqual,
.MinusEqual,
.StarEqual,
.SlashEqual,
.ShiftRightEqual,
.ShiftLeftEqual,
.XorEqual,
.BorEqual,
.BnotEqual,
.AmpersandEqual,
.PercentEqual,
=> try self.emitCodeArg(
locations[node],
get_op,
@intCast(components.slot),
),
else => {},
}

// Type check that operator is allowed
switch (tags[components.assign_token.?]) {
.PlusEqual => switch (type_defs[node].?.def_type) {
.Integer,
.Double,
.List,
.Map,
.String,
=> {},
else => self.reporter.report(
.arithmetic_operand_type,
self.ast.tokens.get(components.assign_token.?),
"Addition is only allowed for types `int`, `double`, list, map and `str`",
),
},
.MinusEqual,
.StarEqual,
.SlashEqual,
.PercentEqual,
=> switch (type_defs[node].?.def_type) {
.Integer, .Double => {},
else => self.reporter.report(
.arithmetic_operand_type,
self.ast.tokens.get(components.assign_token.?),
"Operator is only allowed for types `int`, `double`",
),
},
.ShiftRightEqual,
.ShiftLeftEqual,
.XorEqual,
.BorEqual,
.BnotEqual,
.AmpersandEqual,
=> if (type_defs[node].?.def_type != .Integer) {
self.reporter.report(
.arithmetic_operand_type,
self.ast.tokens.get(components.assign_token.?),
"Operator is only allowed for `int`",
);
},
else => {},
}

_ = try self.generateNode(value, breaks);

switch (tags[components.assign_token.?]) {
.PlusEqual => switch (type_defs[node].?.def_type) {
.Integer => try self.OP_ADD_I(locations[node]),
.Double => try self.OP_ADD_F(locations[node]),
.List => try self.OP_ADD_LIST(locations[node]),
.Map => try self.OP_ADD_MAP(locations[node]),
.String => try self.OP_ADD_STRING(locations[node]),
else => {},
},
.MinusEqual => try self.OP_SUBTRACT(locations[node]),
.StarEqual => try self.OP_MULTIPLY(locations[node]),
.SlashEqual => try self.OP_DIVIDE(locations[node]),
.ShiftRightEqual => try self.OP_SHR(locations[node]),
.ShiftLeftEqual => try self.OP_SHL(locations[node]),
.XorEqual => try self.OP_XOR(locations[node]),
.BorEqual => try self.OP_BOR(locations[node]),
.AmpersandEqual => try self.OP_BAND(locations[node]),
.PercentEqual => try self.OP_MOD(locations[node]),
else => {},
}

try self.emitCodeArg(
locations[node],
set_op,
Expand Down
Loading

0 comments on commit e23b930

Please sign in to comment.