Dynamic Object Indexing for Kym #31
|
@ -8,9 +8,14 @@ options = {
|
|||
.tick_rate = 60,
|
||||
|
||||
["foo"] = "bar",
|
||||
[42] = 42,
|
||||
[42] = "42",
|
||||
}
|
||||
|
||||
options["foo"] = "rab"
|
||||
options[42] = "24"
|
||||
|
||||
@log_info(options.title)
|
||||
@log_info(options["foo"])
|
||||
@log_info(options[42])
|
||||
|
||||
return options
|
||||
|
|
|
@ -222,6 +222,19 @@ pub const RuntimeEnv = struct {
|
|||
try self.compile_expression(chunk, field_set.value_expression.*);
|
||||
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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,17 @@ pub const Expression = union (enum) {
|
|||
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 {
|
||||
operator: BinaryOperator,
|
||||
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"),
|
||||
};
|
||||
}
|
||||
|
@ -388,10 +407,10 @@ fn parse_factor(self: *Self) ParseError!Expression {
|
|||
.symbol_bracket_left => {
|
||||
self.tokenizer.step();
|
||||
|
||||
const index_expression = try self.parse_expression();
|
||||
const subscript_expression = try self.parse_expression();
|
||||
|
||||
if (self.tokenizer.token != .symbol_bracket_right) {
|
||||
return self.report("expected `]` expression");
|
||||
return self.report("expected `]` after subscript expression");
|
||||
}
|
||||
|
||||
self.tokenizer.skip_newlines();
|
||||
|
@ -404,7 +423,7 @@ fn parse_factor(self: *Self) ParseError!Expression {
|
|||
|
||||
try table_literal.push_one(.{
|
||||
.value_expression = try self.parse_expression(),
|
||||
.key_expression = index_expression,
|
||||
.key_expression = subscript_expression,
|
||||
});
|
||||
|
||||
switch (self.tokenizer.token) {
|
||||
|
@ -481,6 +500,26 @@ fn parse_factor(self: *Self) ParseError!Expression {
|
|||
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 => {
|
||||
var argument_expressions = Expression.List.make(allocator);
|
||||
|
||||
|
|
Loading…
Reference in New Issue