aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-06-15 04:56:16 +0200
committerMel <mel@rnrd.eu>2025-06-15 04:56:16 +0200
commitbf5348ece49e615cc9867d8eed444c0efc11e586 (patch)
tree146b36cce9e6239a50a3d2fc9b251d4423f0a5bf
parent19d2a48bb4034b00d4ffbb51fcc37f55af707e05 (diff)
downloadcatskill-bf5348ece49e615cc9867d8eed444c0efc11e586.tar.zst
catskill-bf5348ece49e615cc9867d8eed444c0efc11e586.zip
Fully parse variant & class types
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--boot/parse.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/boot/parse.c b/boot/parse.c
index 658a522..490995f 100644
--- a/boot/parse.c
+++ b/boot/parse.c
@@ -335,16 +335,11 @@ parser_node_type_structure(struct Parser* p, struct Parser_Error* error)
parser_unglue(p);
- struct Type_Node* head = nil;
- struct Type_Node* current = nil;
+ struct Type_Node *head = nil, *current = nil;
while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
struct Token field_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
struct Type_Node* field_type = CHECK(parser_node_type(p, error));
- if (!field_type) {
- *error = parser_error(PARSER_ERROR_EXPECTED_TYPE);
- return nil;
- }
field_type->value_name = field_name_token.value.name;
if (!head)
@@ -369,8 +364,48 @@ parser_node_type_structure(struct Parser* p, struct Parser_Error* error)
struct Type_Node*
parser_node_type_variant(struct Parser* p, struct Parser_Error* error)
{
- // TODO
- return nil;
+ struct Token variant_token = CHECK(parser_need(p, TOKEN_WORD_VARIANT, error));
+ CHECK(parser_need(p, TOKEN_CURLY_OPEN, error));
+
+ parser_unglue(p);
+
+ struct Type_Node *head = nil, *current = nil;
+ while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
+ struct Token variant_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
+ struct String variant_name = variant_name_token.value.name;
+
+ struct Type_Node* backing_type = nil;
+
+ struct Token next = parser_peek(p);
+ bool has_backing_type =
+ !token_is(&next, TOKEN_NEWLINE) && !token_is(&next, TOKEN_COMMA)
+ && !token_is(&next, TOKEN_CURLY_CLOSE);
+
+ if (has_backing_type) {
+ backing_type = CHECK(parser_node_type(p, error));
+ } else {
+ backing_type = type_node_none(variant_name_token.span, variant_name_token.location);
+ }
+
+ backing_type->value_name = variant_name;
+ if (!head)
+ head = backing_type;
+ else
+ current->next = backing_type;
+ current = backing_type;
+
+ next = parser_peek(p);
+ if (token_is(&next, TOKEN_COMMA) || token_is(&next, TOKEN_NEWLINE)) parser_next(p);
+ }
+
+ parser_unglue(p);
+
+ struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error));
+ struct Span span = span_merge(variant_token.span, close_token.span);
+
+ return type_node_new(
+ TYPE_NODE_VARIANT, (union Type_Node_Value){ .variant = { head } }, span,
+ variant_token.location);
}
struct Type_Node*
@@ -388,8 +423,39 @@ parser_node_type_function(struct Parser* p, struct Parser_Error* error)
struct Type_Node*
parser_node_type_class(struct Parser* p, struct Parser_Error* error)
{
- // TODO
- return nil;
+ struct Token class_token = CHECK(parser_need(p, TOKEN_WORD_CLASS, error));
+ CHECK(parser_need(p, TOKEN_CURLY_OPEN, error));
+
+ parser_unglue(p);
+
+ struct Type_Node *head = nil, *current = nil;
+ while (!parser_probe(p, TOKEN_CURLY_CLOSE)) {
+ struct Token method_name_token = CHECK(parser_need(p, TOKEN_NAME, error));
+ struct String method_name = method_name_token.value.name;
+
+ struct Function_Header_Node header = CHECK(parser_function_header_node(p, error));
+ // allocate a new type node for the method type,
+ // for the sake of consistency and the built-in type node linked list.
+ struct Type_Node* method_type = type_node_new(
+ TYPE_NODE_FUNCTION, (union Type_Node_Value){ .function = { header } }, header.span,
+ header.parameters_type_and_name->location);
+ method_type->value_name = method_name;
+
+ if (!head)
+ head = method_type;
+ else
+ current->next = method_type;
+ current = method_type;
+
+ if (parser_probe(p, TOKEN_COMMA) || parser_probe(p, TOKEN_NEWLINE)) parser_next(p);
+ }
+
+ parser_unglue(p);
+
+ struct Token close_token = CHECK(parser_need(p, TOKEN_CURLY_CLOSE, error));
+ struct Span span = span_merge(class_token.span, close_token.span);
+ return type_node_new(
+ TYPE_NODE_CLASS, (union Type_Node_Value){ .class = { head } }, span, class_token.location);
}
struct Type_Node*
@@ -397,14 +463,9 @@ parser_node_type_tuple(struct Parser* p, struct Parser_Error* error)
{
struct Token open_token = CHECK(parser_need(p, TOKEN_ROUND_OPEN, error));
- struct Type_Node* head = nil;
- struct Type_Node* current = nil;
+ struct Type_Node *head = nil, *current = nil;
while (!parser_probe(p, TOKEN_ROUND_CLOSE)) {
struct Type_Node* type = CHECK(parser_node_type(p, error));
- if (!type) {
- *error = parser_error(PARSER_ERROR_EXPECTED_TYPE);
- return nil;
- }
if (!head)
head = type;