about summary refs log tree commit diff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/lex.c5
-rw-r--r--boot/parse.c19
2 files changed, 22 insertions, 2 deletions
diff --git a/boot/lex.c b/boot/lex.c
index 30ccd85..f210abd 100644
--- a/boot/lex.c
+++ b/boot/lex.c
@@ -116,6 +116,7 @@ enum Token_Kind
     TOKEN_DOT,
     TOKEN_DOT_DOT,
     TOKEN_BANG,
+    TOKEN_QUESTION,
     TOKEN_PERCENT,
     TOKEN_PIPE,
     TOKEN_TILDE,
@@ -237,6 +238,8 @@ token_kind_to_string(enum Token_Kind kind)
         return "DOT_DOT";
     case TOKEN_BANG:
         return "BANG";
+    case TOKEN_QUESTION:
+        return "QUESTION";
     case TOKEN_PERCENT:
         return "PERCENT";
     case TOKEN_PIPE:
@@ -616,6 +619,8 @@ lexer_symbol_token(struct Lexer* l, struct Lexer_Char current)
         if (a.got_match) RET{ TOKEN_NOT_EQUAL, 2 };
         RET{ TOKEN_BANG, 1 };
     }
+    case '?':
+        RET{ TOKEN_QUESTION, 1 };
     case '%': {
         a = lexer_match_char(l, '=');
         if (a.got_match) RET{ TOKEN_ASSIGN_PERCENT, 2 };
diff --git a/boot/parse.c b/boot/parse.c
index ac324f9..976bc4b 100644
--- a/boot/parse.c
+++ b/boot/parse.c
@@ -546,9 +546,8 @@ parser_node_type_reference(struct Parser* p, struct Parser_Error* error)
 }
 
 struct Type_Node*
-parser_node_type(struct Parser* p, struct Parser_Error* error)
+parser_node_type_inner(struct Parser* p, struct Parser_Error* error)
 {
-    // TODO: maybe, variant, class
     struct Token token = parser_peek(p);
     switch (token.kind) {
     case TOKEN_NAME:
@@ -573,6 +572,22 @@ parser_node_type(struct Parser* p, struct Parser_Error* error)
     }
 }
 
+struct Type_Node*
+parser_node_type(struct Parser* p, struct Parser_Error* error)
+{
+    struct Type_Node* type = CHECK(parser_node_type_inner(p, error));
+
+    // check if the type is followed by a `?`, which means it may be nil.
+    if (parser_probe(p, TOKEN_QUESTION)) {
+        parser_next(p); // consume the question mark
+        type = type_node_new(
+            TYPE_NODE_MAYBE, (union Type_Node_Value){ .maybe = { type } }, type->span,
+            type->location);
+    }
+
+    return type;
+}
+
 struct Expression*
 parser_expression_primary_name(struct Parser* p, struct Parser_Error* error)
 {