Add support for subscript operations on objects
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
kayomn 2023-08-12 15:10:46 +01:00
parent 6c0e3477c2
commit 66df9e3a1e
3 changed files with 61 additions and 4 deletions

View File

@ -8,9 +8,14 @@ options = {
.tick_rate = 60, .tick_rate = 60,
["foo"] = "bar", ["foo"] = "bar",
[42] = 42, [42] = "42",
} }
options["foo"] = "rab"
options[42] = "24"
@log_info(options.title) @log_info(options.title)
@log_info(options["foo"])
@log_info(options[42])
return options return options

View File

@ -222,6 +222,19 @@ pub const RuntimeEnv = struct {
try self.compile_expression(chunk, field_set.value_expression.*); try self.compile_expression(chunk, field_set.value_expression.*);
try chunk.opcodes.push_one(.object_set); try chunk.opcodes.push_one(.object_set);
}, },
.subscript_get => |subscript_get| {
try self.compile_expression(chunk, subscript_get.object_expression.*);
try self.compile_expression(chunk, subscript_get.subscript_expression.*);
try chunk.opcodes.push_one(.object_get);
},
.subscript_set => |subscript_set| {
try self.compile_expression(chunk, subscript_set.object_expression.*);
try self.compile_expression(chunk, subscript_set.subscript_expression.*);
try self.compile_expression(chunk, subscript_set.value_expression.*);
try chunk.opcodes.push_one(.object_set);
},
} }
} }

View File

@ -33,6 +33,17 @@ pub const Expression = union (enum) {
value_expression: *Expression, value_expression: *Expression,
}, },
subscript_get: struct {
object_expression: *Expression,
subscript_expression: *Expression,
},
subscript_set: struct {
object_expression: *Expression,
subscript_expression: *Expression,
value_expression: *Expression,
},
binary_operation: struct { binary_operation: struct {
operator: BinaryOperator, operator: BinaryOperator,
lhs_expression: *Expression, lhs_expression: *Expression,
@ -266,6 +277,14 @@ pub fn parse_expression(self: *Self) ParseError!Expression {
}, },
}, },
.subscript_get => |subscript_get| .{
.subscript_set = .{
.object_expression = subscript_get.object_expression,
.subscript_expression = subscript_get.subscript_expression,
.value_expression = try coral.io.allocate_one(allocator, try self.parse_expression()),
},
},
else => self.report("expected local or field on left-hand side of expression"), else => self.report("expected local or field on left-hand side of expression"),
}; };
} }
@ -388,10 +407,10 @@ fn parse_factor(self: *Self) ParseError!Expression {
.symbol_bracket_left => { .symbol_bracket_left => {
self.tokenizer.step(); self.tokenizer.step();
const index_expression = try self.parse_expression(); const subscript_expression = try self.parse_expression();
if (self.tokenizer.token != .symbol_bracket_right) { if (self.tokenizer.token != .symbol_bracket_right) {
return self.report("expected `]` expression"); return self.report("expected `]` after subscript expression");
} }
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
@ -404,7 +423,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
try table_literal.push_one(.{ try table_literal.push_one(.{
.value_expression = try self.parse_expression(), .value_expression = try self.parse_expression(),
.key_expression = index_expression, .key_expression = subscript_expression,
}); });
switch (self.tokenizer.token) { switch (self.tokenizer.token) {
@ -481,6 +500,26 @@ fn parse_factor(self: *Self) ParseError!Expression {
self.tokenizer.skip_newlines(); self.tokenizer.skip_newlines();
}, },
.symbol_bracket_left => {
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 = .{
.subscript_get = .{
.subscript_expression = try coral.io.allocate_one(allocator, try self.parse_expression()),
.object_expression = unnecessary_temp,
},
};
if (self.tokenizer.token != .symbol_bracket_right) {
return self.report("expected `]` subscript expression");
}
self.tokenizer.skip_newlines();
},
.symbol_paren_left => { .symbol_paren_left => {
var argument_expressions = Expression.List.make(allocator); var argument_expressions = Expression.List.make(allocator);