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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user