Add parser support for table literals
This commit is contained in:
parent
a8104308a6
commit
1fb5fc6048
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue