Add parser support for table literals

This commit is contained in:
kayomn 2023-05-28 20:23:13 +00:00
parent a8104308a6
commit 1fb5fc6048
1 changed files with 89 additions and 9 deletions

View File

@ -321,12 +321,92 @@ pub const ParsedExpression = union (enum) {
defer _ = tokenizer.step();
return ParsedExpression{
.valid = .{
.string_literal = value,
},
.valid = .{.string_literal = value},
};
},
.symbol_brace_left => {
if (tokenizer.step()) {
return ParsedExpression{.invalid = "unexpected end of table literal"};
}
var is_invalid = true;
var table_fields = try TableFields.init(allocator, 0);
defer if (is_invalid) {
table_fields.deinit(allocator);
};
while (true) {
switch (tokenizer.current_token) {
.symbol_brace_right => {
_ = tokenizer.step();
is_invalid = false;
return ParsedExpression{
.valid = .{.table_literal = table_fields},
};
},
.local => |identifier| {
const key = identifier;
if (!tokenizer.step() or tokenizer.current_token != .symbol_equals) {
return ParsedExpression{.invalid = "expected `=` after identifier"};
}
if (!tokenizer.step()) {
return ParsedExpression{.invalid = "unexpected end after `=`"};
}
var parsed_expression = try init(allocator, tokenizer);
switch (parsed_expression) {
.valid => |*expression| {
errdefer expression.deinit(allocator);
try table_fields.push_one(allocator, .{
.identifier = key,
.expression = expression,
});
},
.invalid => |details| return ParsedExpression{.invalid = details},
}
},
.string => |identifier| {
const key = identifier;
if (!tokenizer.step() or tokenizer.current_token != .symbol_equals) {
return ParsedExpression{.invalid = "expected `=` after identifier"};
}
if (!tokenizer.step()) {
return ParsedExpression{.invalid = "unexpected end after `=`"};
}
var parsed_expression = try init(allocator, tokenizer);
switch (parsed_expression) {
.valid => |*expression| {
errdefer expression.deinit(allocator);
try table_fields.push_one(allocator, .{
.identifier = key,
.expression = expression,
});
},
.invalid => |details| return ParsedExpression{.invalid = details},
}
},
else => return ParsedExpression{.invalid = "expected `}` or fields in table expression"}
}
}
},
.symbol_minus => {
if (!tokenizer.step()) {
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
@ -519,7 +599,7 @@ pub const Expression = union (enum) {
integer_literal: types.Integer,
float_literal: types.Float,
string_literal: []const u8,
table_literal: TableLiteral,
table_literal: TableFields,
grouped_expression: *Expression,
binary_operation: struct {
@ -533,11 +613,6 @@ pub const Expression = union (enum) {
expression: *Expression,
},
const TableLiteral = coral.list.Stack(struct {
identifier: []const u8,
expression: *Expression,
});
fn deinit(self: *Expression, allocator: coral.io.Allocator) void {
switch (self.*) {
.nil_literal, .true_literal, .false_literal, .integer_literal, .float_literal, .string_literal => {},
@ -639,6 +714,11 @@ pub const Statements = struct {
}
};
const TableFields = coral.list.Stack(struct {
identifier: []const u8,
expression: *Expression,
});
pub const UnaryOperation = enum {
boolean_negation,
numeric_negation,