Skip to content

Commit

Permalink
feat: Immutability by default
Browse files Browse the repository at this point in the history
closes #139
  • Loading branch information
giann committed Dec 11, 2024
1 parent eacfc9f commit 9595460
Show file tree
Hide file tree
Showing 17 changed files with 878 additions and 382 deletions.
56 changes: 41 additions & 15 deletions src/Codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1328,7 +1328,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj

if (callee_def_type == .ObjectInstance) {
const fields = type_defs[node_components[components.callee].Dot.callee].?
.resolved_type.?.ObjectInstance
.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.fields;

const field = fields.get(member_lexeme).?;
Expand Down Expand Up @@ -1493,8 +1493,9 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
.ForeignContainer, .ObjectInstance, .Object => {
const field_name = self.ast.tokens.items(.lexeme)[components.identifier];
const field = switch (callee_type.def_type) {
.ObjectInstance => callee_type.resolved_type.?.ObjectInstance
.resolved_type.?.Object.fields
.ObjectInstance => callee_type.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object
.fields
.get(field_name),
.Object => callee_type.resolved_type.?.Object.fields
.get(field_name),
Expand Down Expand Up @@ -1538,7 +1539,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
{
self.reporter.reportErrorFmt(
.assignable,
self.ast.tokens.get(locations[value]),
self.ast.tokens.get(locations[components.callee]),
"`{s}` is not assignable",
.{
field_name,
Expand All @@ -1547,12 +1548,25 @@ fn generateDot(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
} else if (field.?.final) {
self.reporter.reportErrorFmt(
.constant_property,
self.ast.tokens.get(locations[value]),
self.ast.tokens.get(locations[components.callee]),
"`{s}` is final",
.{
field_name,
},
);
} else if (callee_type.def_type == .ObjectInstance and !callee_type.resolved_type.?.ObjectInstance.mutable) {
self.reporter.reportWithOrigin(
.not_mutable,
self.ast.tokens.get(locations[components.callee]),
callee_type.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.location,
"Instance of `{s}` is not mutable",
.{
callee_type.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.qualified_name.string,
},
"declared here",
);
}

if (!field.?.type_def.eql(value_type_def)) {
Expand Down Expand Up @@ -1758,11 +1772,15 @@ fn generateEnum(self: *Self, node: Ast.Node.Index, _: ?*Breaks) Error!?*obj.ObjF
if (case_type_def) |case_type| {
if (case_type.def_type == .Placeholder) {
self.reporter.reportPlaceholder(self.ast, case_type.resolved_type.?.Placeholder);
} else if (!((try enum_type.toInstance(self.gc.allocator, &self.gc.type_registry))).eql(case_type)) {
} else if (!((try enum_type.toInstance(self.gc.allocator, &self.gc.type_registry, false))).eql(case_type)) {
self.reporter.reportTypeCheck(
.enum_case_type,
self.ast.tokens.get(locations[node]),
(try enum_type.toInstance(self.gc.allocator, &self.gc.type_registry)),
(try enum_type.toInstance(
self.gc.allocator,
&self.gc.type_registry,
false,
)),
self.ast.tokens.get(locations[case.value.?]),
case_type,
"Bad enum case type",
Expand Down Expand Up @@ -2078,7 +2096,11 @@ fn generateForEach(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*
}
},
.Enum => {
const iterable_type = try iterable_type_def.toInstance(self.gc.allocator, &self.gc.type_registry);
const iterable_type = try iterable_type_def.toInstance(
self.gc.allocator,
&self.gc.type_registry,
false,
);
if (!iterable_type.strictEql(value_type_def)) {
self.reporter.reportTypeCheck(
.foreach_value_type,
Expand All @@ -2094,6 +2116,7 @@ fn generateForEach(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*
const iterable_type = try iterable_type_def.resolved_type.?.Fiber.yield_type.toInstance(
self.gc.allocator,
&self.gc.type_registry,
false,
);
if (!iterable_type.strictEql(value_type_def)) {
self.reporter.reportTypeCheck(
Expand Down Expand Up @@ -3120,7 +3143,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
);

var fields = if (node_type_def.def_type == .ObjectInstance) inst: {
const fields = node_type_def.resolved_type.?.ObjectInstance.resolved_type.?.Object.fields;
const fields = node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields;
var fields_type_defs = std.StringArrayHashMap(*obj.ObjTypeDef).init(self.gc.allocator);
var it = fields.iterator();
while (it.next()) |kv| {
Expand All @@ -3137,7 +3160,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
};

const object_location = if (node_type_def.def_type == .ObjectInstance)
node_type_def.resolved_type.?.ObjectInstance.resolved_type.?.Object.location
node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.location
else
node_type_def.resolved_type.?.ForeignContainer.location;

Expand All @@ -3148,7 +3171,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
for (components.properties) |property| {
const property_name = lexemes[property.name];
const property_idx = if (node_type_def.def_type == .ObjectInstance)
if (node_type_def.resolved_type.?.ObjectInstance
if (node_type_def.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object
.fields.get(property_name)) |field|
field.index
Expand Down Expand Up @@ -3180,7 +3203,8 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
self.reporter.reportTypeCheck(
.property_type,
if (node_type_def.def_type == .ObjectInstance)
node_type_def.resolved_type.?.ObjectInstance.resolved_type.?.Object.fields.get(property_name).?.location
node_type_def.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.fields.get(property_name).?.location
else
object_location,
prop,
Expand Down Expand Up @@ -3219,7 +3243,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
// If union we're statisfied with only on field initialized
if (node_type_def.def_type != .ForeignContainer or node_type_def.resolved_type.?.ForeignContainer.zig_type != .Union or init_properties.count() == 0) {
const field_defs = if (node_type_def.def_type == .ObjectInstance)
node_type_def.resolved_type.?.ObjectInstance.resolved_type.?.Object.fields
node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields
else
null;

Expand Down Expand Up @@ -3915,11 +3939,13 @@ fn generateVarDeclaration(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) E
self.reporter.reportPlaceholder(self.ast, value_type_def.?.resolved_type.?.Placeholder);
} else if (type_def.def_type == .Placeholder) {
self.reporter.reportPlaceholder(self.ast, type_def.resolved_type.?.Placeholder);
} else if (!(try type_def.toInstance(self.gc.allocator, &self.gc.type_registry)).eql(value_type_def.?) and !(try (try type_def.toInstance(self.gc.allocator, &self.gc.type_registry)).cloneNonOptional(&self.gc.type_registry)).eql(value_type_def.?)) {
} else if (!(try type_def.toInstance(self.gc.allocator, &self.gc.type_registry, type_def.isMutable())).eql(value_type_def.?) and
!(try (try type_def.toInstance(self.gc.allocator, &self.gc.type_registry, type_def.isMutable())).cloneNonOptional(&self.gc.type_registry)).eql(value_type_def.?))
{
self.reporter.reportTypeCheck(
.assignment_value_type,
self.ast.tokens.get(location),
try type_def.toInstance(self.gc.allocator, &self.gc.type_registry),
try type_def.toInstance(self.gc.allocator, &self.gc.type_registry, type_def.isMutable()),
self.ast.tokens.get(locations[value]),
value_type_def.?,
"Wrong variable type",
Expand Down
32 changes: 16 additions & 16 deletions src/FFI.zig
Original file line number Diff line number Diff line change
Expand Up @@ -509,24 +509,24 @@ fn unionContainer(self: *Self, name: []const u8, container: Ast.full.ContainerDe
},
);

const foreign_def = o.ObjForeignContainer.ContainerDef{
.location = self.state.?.source,
.name = try self.gc.copyString(name),
// FIXME
.qualified_name = try self.gc.copyString(qualified_name.items),
.zig_type = zig_type,
.buzz_type = buzz_fields,
.fields = get_set_fields,
};

const type_def = o.ObjTypeDef{
.def_type = .ForeignContainer,
.resolved_type = .{ .ForeignContainer = foreign_def },
};

const zdef = try self.gc.allocator.create(Zdef);
zdef.* = .{
.type_def = try self.gc.type_registry.getTypeDef(type_def),
.type_def = try self.gc.type_registry.getTypeDef(
.{
.def_type = .ForeignContainer,
.resolved_type = .{
.ForeignContainer = .{
.location = self.state.?.source,
.name = try self.gc.copyString(name),
// FIXME
.qualified_name = try self.gc.copyString(qualified_name.items),
.zig_type = zig_type,
.buzz_type = buzz_fields,
.fields = get_set_fields,
},
},
},
),
.zig_type = zig_type,
.name = name,
};
Expand Down
10 changes: 5 additions & 5 deletions src/Jit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
),
.ObjectInstance => instance: {
const field = type_defs[node_components[components.callee].Dot.callee].?
.resolved_type.?.ObjectInstance
.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object
.fields.get(member_lexeme).?;

Expand Down Expand Up @@ -3127,7 +3127,7 @@ fn generateList(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
new_list,
&[_]m.MIR_op_t{
m.MIR_new_reg_op(self.ctx, self.state.?.vm_reg.?),
m.MIR_new_uint_op(self.ctx, type_def.?.resolved_type.?.List.item_type.toValue().val),
m.MIR_new_uint_op(self.ctx, type_def.?.toValue().val),
},
);

Expand Down Expand Up @@ -3387,7 +3387,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
(try self.generateNode(components.callee)).?,
m.MIR_new_uint_op(
self.ctx,
callee_type.resolved_type.?.ObjectInstance
callee_type.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.fields
.get(member_lexeme).?.index,
),
Expand All @@ -3400,7 +3400,7 @@ fn generateDot(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
},
else => {
const field = if (callee_type.def_type == .ObjectInstance)
callee_type.resolved_type.?.ObjectInstance
callee_type.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.fields
.get(member_lexeme)
else
Expand Down Expand Up @@ -4102,7 +4102,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t {
instance,
m.MIR_new_uint_op(
self.ctx,
type_def.?.resolved_type.?.ObjectInstance
type_def.?.resolved_type.?.ObjectInstance.of
.resolved_type.?.Object.fields
.get(lexemes[property.name]).?.index,
),
Expand Down
Loading

0 comments on commit 9595460

Please sign in to comment.