added '#not' to interface constraints
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 6 May 2022 03:11:53 +0000 (22:11 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 6 May 2022 03:11:53 +0000 (22:11 -0500)
include/astnodes.h
src/checker.c
src/parser.c

index b209ce0e764d5452bda6bf6fb220d3b436c9d9e3..2fac9425015f8530ed460345ef0b3c6122417ac8 100644 (file)
@@ -1049,6 +1049,8 @@ typedef struct InterfaceConstraint {
     AstTyped *expr;
     AstType  *expected_type_expr;
     Type     *expected_type;
+
+    b32 invert_condition: 1;
 } InterfaceConstraint;
 
 struct AstInterface {
index 5ca6d15ecaad207d8fa3fc307579bcbe731277eb..8a8fd1c75e6cd08fed4d2a032b581dfc2ee20536 100644 (file)
@@ -2754,6 +2754,7 @@ CheckStatus check_constraint(AstConstraint *constraint) {
                 InterfaceConstraint new_ic = {0};
                 new_ic.expr = (AstTyped *) ast_clone(context.ast_alloc, (AstNode *) ic->expr);
                 new_ic.expected_type_expr = (AstType *) ast_clone(context.ast_alloc, (AstNode *) ic->expected_type_expr);
+                new_ic.invert_condition = ic->invert_condition;
                 bh_arr_push(constraint->exprs, new_ic);
             }
 
@@ -2793,7 +2794,11 @@ CheckStatus check_constraint(AstConstraint *constraint) {
                     return cs;
                 }
 
-                if (cs == Check_Error) {
+                if (cs == Check_Error && !ic->invert_condition) {
+                    goto constraint_error;
+                }
+
+                if (cs == Check_Success && ic->invert_condition) {
                     goto constraint_error;
                 }
 
@@ -2809,7 +2814,8 @@ CheckStatus check_constraint(AstConstraint *constraint) {
                     }
 
                     TYPE_CHECK(&ic->expr, ic->expected_type) {
-                        goto constraint_error;
+                        if (!ic->invert_condition)
+                            goto constraint_error;
                     }
                 }
 
@@ -2819,11 +2825,12 @@ CheckStatus check_constraint(AstConstraint *constraint) {
               constraint_error:
                 // HACK HACK HACK
                 onyx_clear_errors();
-
                 *constraint->report_status = Constraint_Check_Status_Failed;
                 return Check_Failed;
             }
 
+            // HACK HACK HACK
+            onyx_clear_errors();
             *constraint->report_status = Constraint_Check_Status_Success;
             return Check_Complete;
         }
index 2797244585274d059cf1ce7ea427a82e4ee16f60..d0537d5b80cd04c2517a45fbffc3ce9d0fe88673 100644 (file)
@@ -2141,6 +2141,10 @@ static AstInterface* parse_interface(OnyxParser* parser) {
         if (parser->hit_unexpected_token) return interface;
 
         InterfaceConstraint ic = {0};
+        if (parse_possible_directive(parser, "not")) {
+            ic.invert_condition = 1;
+        }
+
         if (consume_token_if_next(parser, '{')) {
             ic.expr = parse_expression(parser, 0);