aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/parse.c33
-rw-r--r--boot/tests/parse/try_must.cskt0
-rw-r--r--boot/tree.c14
-rw-r--r--boot/visit.c34
4 files changed, 81 insertions, 0 deletions
diff --git a/boot/parse.c b/boot/parse.c
index 7b40fb1..c08d247 100644
--- a/boot/parse.c
+++ b/boot/parse.c
@@ -896,6 +896,34 @@ parser_expression_postfix_subscript(
}
struct Expression*
+parser_expression_postfix_try(
+ struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+{
+ while (parser_probe(p, TOKEN_QUESTION)) {
+ struct Token question_token = parser_next(p);
+
+ struct Span span = span_merge(subject->span, question_token.span);
+ union Expression_Value value = { .try = { subject } };
+ subject = expression_new(EXPRESSION_TRY, value, span, subject->location);
+ }
+ return subject;
+}
+
+struct Expression*
+parser_expression_postfix_must(
+ struct Parser* p, struct Expression* subject, struct Parser_Error* error)
+{
+ while (parser_probe(p, TOKEN_BANG)) {
+ struct Token bang_token = parser_next(p);
+
+ struct Span span = span_merge(subject->span, bang_token.span);
+ union Expression_Value value = { .try = { subject } };
+ subject = expression_new(EXPRESSION_MUST, value, span, subject->location);
+ }
+ return subject;
+}
+
+struct Expression*
parser_expression_postfix(struct Parser* p, struct Parser_Error* error)
{
struct Expression* expression = CHECK(parser_expression_member(p, error));
@@ -906,6 +934,11 @@ parser_expression_postfix(struct Parser* p, struct Parser_Error* error)
return parser_expression_postfix_call_or_construct(p, expression, error);
case TOKEN_SQUARE_OPEN:
return parser_expression_postfix_subscript(p, expression, error);
+
+ case TOKEN_QUESTION:
+ return parser_expression_postfix_try(p, expression, error);
+ case TOKEN_BANG:
+ return parser_expression_postfix_must(p, expression, error);
default:;
}
diff --git a/boot/tests/parse/try_must.cskt b/boot/tests/parse/try_must.cskt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/boot/tests/parse/try_must.cskt
diff --git a/boot/tree.c b/boot/tree.c
index dc22bfd..3c808f8 100644
--- a/boot/tree.c
+++ b/boot/tree.c
@@ -688,6 +688,8 @@ enum Expression_Kind
EXPRESSION_SUBSCRIPT,
EXPRESSION_MEMBER,
EXPRESSION_INCREMENT_DECREMENT,
+ EXPRESSION_TRY,
+ EXPRESSION_MUST,
EXPRESSION_FUNCTION,
EXPRESSION_TYPE,
@@ -766,6 +768,16 @@ struct Expression_Increment_Decrement
enum Increment_Decrement_Operation operation;
};
+struct Expression_Try
+{
+ struct Expression* expression;
+};
+
+struct Expression_Must
+{
+ struct Expression* expression;
+};
+
struct Expression_Function
{
struct Function_Header_Node header;
@@ -791,6 +803,8 @@ union Expression_Value
struct Expression_Subscript subscript;
struct Expression_Member member;
struct Expression_Increment_Decrement increment_decrement;
+ struct Expression_Try try;
+ struct Expression_Must must;
struct Expression_Function function;
struct Expression_Type type;
};
diff --git a/boot/visit.c b/boot/visit.c
index 3cc3e55..c1dd797 100644
--- a/boot/visit.c
+++ b/boot/visit.c
@@ -45,6 +45,8 @@ struct Visit_Table
void (*visit_expression_subscript)(struct Visit* visitor, struct Expression* expr);
void (*visit_expression_member)(struct Visit* visitor, struct Expression* expr);
void (*visit_expression_increment_decrement)(struct Visit* visitor, struct Expression* expr);
+ void (*visit_expression_try)(struct Visit* visitor, struct Expression* expr);
+ void (*visit_expression_must)(struct Visit* visitor, struct Expression* expr);
void (*visit_expression_function)(struct Visit* visitor, struct Expression* expr);
void (*visit_type_node)(struct Visit* visitor, struct Type_Node* node);
@@ -219,6 +221,12 @@ walk_expression(struct Visit* visit, struct Expression* expression)
case EXPRESSION_INCREMENT_DECREMENT:
VISIT(visit_expression_increment_decrement, expression);
break;
+ case EXPRESSION_TRY:
+ VISIT(visit_expression_try, expression);
+ break;
+ case EXPRESSION_MUST:
+ VISIT(visit_expression_must, expression);
+ break;
case EXPRESSION_FUNCTION:
VISIT(visit_expression_function, expression);
break;
@@ -286,6 +294,10 @@ walk_expression_increment_decrement(struct Visit* visit, struct Expression* expr
VISIT(visit_expression, expression->value.increment_decrement.subject);
}
+WALK_LEAF_FUNCTION(walk_expression_try, struct Expression*);
+
+WALK_LEAF_FUNCTION(walk_expression_must, struct Expression*);
+
void
walk_expression_function(struct Visit* visit, struct Expression* expression)
{
@@ -815,6 +827,26 @@ printer_visit_expression_increment_decrement(struct Visit* visit, struct Express
}
void
+printer_visit_expression_try(struct Visit* visit, struct Expression* expr)
+{
+ TREE_PRINTER_PREAMBLE
+
+ PRINT("(try ");
+ VISIT(visit_expression, expr->value.try.expression);
+ PRINT(")");
+}
+
+void
+printer_visit_expression_must(struct Visit* visit, struct Expression* expr)
+{
+ TREE_PRINTER_PREAMBLE
+
+ PRINT("(must ");
+ VISIT(visit_expression, expr->value.must.expression);
+ PRINT(")");
+}
+
+void
printer_visit_expression_function(struct Visit* visit, struct Expression* expr)
{
TREE_PRINTER_PREAMBLE
@@ -1064,6 +1096,8 @@ struct Visit_Table printer_visit_functions = {
.visit_expression_subscript = printer_visit_expression_subscript,
.visit_expression_member = printer_visit_expression_member,
.visit_expression_increment_decrement = printer_visit_expression_increment_decrement,
+ .visit_expression_try = printer_visit_expression_try,
+ .visit_expression_must = printer_visit_expression_must,
.visit_expression_function = printer_visit_expression_function,
.visit_type_node = printer_visit_type_node,