Apply workaround for Zig struct re-assign miscompilation

This commit is contained in:
kayomn 2023-07-31 00:12:16 +01:00
parent 3173dd52fe
commit 9435348877
1 changed files with 166 additions and 155 deletions

View File

@ -270,6 +270,7 @@ pub fn parse_expression(self: *Self) ParseError!Expression {
fn parse_factor(self: *Self) ParseError!Expression { fn parse_factor(self: *Self) ParseError!Expression {
const allocator = self.arena.as_allocator(); const allocator = self.arena.as_allocator();
var expression = @as(Expression, parse: {
switch (self.tokenizer.token) { switch (self.tokenizer.token) {
.symbol_paren_left => { .symbol_paren_left => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
@ -286,62 +287,43 @@ fn parse_factor(self: *Self) ParseError!Expression {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return Expression{.grouped_expression = try coral.io.allocate_one(allocator, expression)}; break: parse .{.grouped_expression = try coral.io.allocate_one(allocator, expression)};
}, },
.keyword_nil => { .keyword_nil => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .nil_literal; break: parse .nil_literal;
}, },
.keyword_true => { .keyword_true => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .true_literal; break: parse .true_literal;
}, },
.keyword_false => { .keyword_false => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .false_literal; break: parse .false_literal;
}, },
.number => |value| { .number => |value| {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .{.number_literal = value}; break: parse .{.number_literal = value};
}, },
.string => |value| { .string => |value| {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .{.string_literal = value}; break: parse .{.string_literal = value};
}, },
.identifier => |local_identifier| { .identifier => |local_identifier| {
var expression = Expression{.get_local = local_identifier};
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
while (self.tokenizer.token == .symbol_period) { break: parse .{.get_local = local_identifier};
self.tokenizer.skip_newlines();
expression = .{
.get_field = .{
.identifier = switch (self.tokenizer.token) {
.identifier => |field_identifier| field_identifier,
else => return self.report("expected identifier after `.`"),
},
.object_expression = try coral.io.allocate_one(allocator, expression),
},
};
self.tokenizer.skip_newlines();
}
return expression;
}, },
.symbol_brace_left => { .symbol_brace_left => {
@ -354,7 +336,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
.symbol_brace_right => { .symbol_brace_right => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .{.table_literal = table_literal}; break: parse .{.table_literal = table_literal};
}, },
.symbol_bracket_left => { .symbol_bracket_left => {
@ -396,7 +378,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
.symbol_brace_right => { .symbol_brace_right => {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
return .{.table_literal = table_literal}; break: parse .{.table_literal = table_literal};
}, },
else => return self.report("expected `,` or `}` after expression"), else => return self.report("expected `,` or `}` after expression"),
@ -415,7 +397,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
return self.report("expected expression after numeric negation (`-`)"); return self.report("expected expression after numeric negation (`-`)");
} }
return .{ break: parse .{
.unary_operation = .{ .unary_operation = .{
.expression = try coral.io.allocate_one(allocator, try self.parse_factor()), .expression = try coral.io.allocate_one(allocator, try self.parse_factor()),
.operator = .numeric_negation, .operator = .numeric_negation,
@ -430,7 +412,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
return self.report("expected expression after boolean negation (`!`)"); return self.report("expected expression after boolean negation (`!`)");
} }
return .{ break: parse .{
.unary_operation = .{ .unary_operation = .{
.expression = try coral.io.allocate_one(allocator, try self.parse_factor()), .expression = try coral.io.allocate_one(allocator, try self.parse_factor()),
.operator = .boolean_negation, .operator = .boolean_negation,
@ -440,6 +422,35 @@ fn parse_factor(self: *Self) ParseError!Expression {
else => return self.report("unexpected token in expression"), else => return self.report("unexpected token in expression"),
} }
});
while (true) {
switch (self.tokenizer.token) {
.symbol_period => {
self.tokenizer.skip_newlines();
// TODO: Remove when Zig fixes miscompilation with in-place struct re-assignment.
const unnecessary_temp = try coral.io.allocate_one(allocator, expression);
expression = .{
.get_field = .{
.identifier = switch (self.tokenizer.token) {
.identifier => |field_identifier| field_identifier,
else => return self.report("expected identifier after `.`"),
},
.object_expression = unnecessary_temp,
},
};
self.tokenizer.skip_newlines();
},
else => break,
}
}
return expression;
} }
const parse_term = binary_operation_parser(parse_factor, &.{ const parse_term = binary_operation_parser(parse_factor, &.{