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();
|
defer _ = tokenizer.step();
|
||||||
|
|
||||||
return ParsedExpression{
|
return ParsedExpression{
|
||||||
.valid = .{
|
.valid = .{.string_literal = value},
|
||||||
.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 => {
|
.symbol_minus => {
|
||||||
if (!tokenizer.step()) {
|
if (!tokenizer.step()) {
|
||||||
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
|
return ParsedExpression{.invalid = "expected expression after numeric negation (`-`)"};
|
||||||
|
@ -519,7 +599,7 @@ pub const Expression = union (enum) {
|
||||||
integer_literal: types.Integer,
|
integer_literal: types.Integer,
|
||||||
float_literal: types.Float,
|
float_literal: types.Float,
|
||||||
string_literal: []const u8,
|
string_literal: []const u8,
|
||||||
table_literal: TableLiteral,
|
table_literal: TableFields,
|
||||||
grouped_expression: *Expression,
|
grouped_expression: *Expression,
|
||||||
|
|
||||||
binary_operation: struct {
|
binary_operation: struct {
|
||||||
|
@ -533,11 +613,6 @@ pub const Expression = union (enum) {
|
||||||
expression: *Expression,
|
expression: *Expression,
|
||||||
},
|
},
|
||||||
|
|
||||||
const TableLiteral = coral.list.Stack(struct {
|
|
||||||
identifier: []const u8,
|
|
||||||
expression: *Expression,
|
|
||||||
});
|
|
||||||
|
|
||||||
fn deinit(self: *Expression, allocator: coral.io.Allocator) void {
|
fn deinit(self: *Expression, allocator: coral.io.Allocator) void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.nil_literal, .true_literal, .false_literal, .integer_literal, .float_literal, .string_literal => {},
|
.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 {
|
pub const UnaryOperation = enum {
|
||||||
boolean_negation,
|
boolean_negation,
|
||||||
numeric_negation,
|
numeric_negation,
|
||||||
|
|
Loading…
Reference in New Issue