diff --git a/debug/app.ona b/debug/app.ona index 6f78ba6..dad79ec 100644 --- a/debug/app.ona +++ b/debug/app.ona @@ -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 diff --git a/source/ona/kym.zig b/source/ona/kym.zig index fb4b6f1..179eaa3 100644 --- a/source/ona/kym.zig +++ b/source/ona/kym.zig @@ -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); + }, } } diff --git a/source/ona/kym/Ast.zig b/source/ona/kym/Ast.zig index cf2b6f7..f286ab7 100755 --- a/source/ona/kym/Ast.zig +++ b/source/ona/kym/Ast.zig @@ -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);