about summary refs log tree commit diff
path: root/boot/tree.c
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-06-03 01:46:34 +0200
committerMel <mel@rnrd.eu>2025-06-03 01:46:34 +0200
commitf4bcdb0373ac34349c6ecdb9a894c561e0cd419c (patch)
treeada9099eec92d0824b1943ff4ec453cc9682c2bd /boot/tree.c
parenta9b5fef2eb126500974a1cfe9ce4a8f7cc6e0490 (diff)
downloadcatskill-f4bcdb0373ac34349c6ecdb9a894c561e0cd419c.tar.zst
catskill-f4bcdb0373ac34349c6ecdb9a894c561e0cd419c.zip
Parse and lex ++, --, ** operators, with prefix and postfix handling
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/tree.c')
-rw-r--r--boot/tree.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/boot/tree.c b/boot/tree.c
index 3ae90b8..2d49a2c 100644
--- a/boot/tree.c
+++ b/boot/tree.c
@@ -54,6 +54,7 @@ enum Binary_Operation
     BINARY_MULTIPLY,
     BINARY_DIVIDE,
     BINARY_MODULO,
+    BINARY_POWER,
 
     BINARY_EQUAL,
     BINARY_NOT_EQUAL,
@@ -99,6 +100,8 @@ binary_operation_from_token(const struct Token* token)
         return BINARY_DIVIDE;
     case TOKEN_PERCENT:
         return BINARY_MODULO;
+    case TOKEN_STAR_STAR:
+        return BINARY_POWER;
 
     case TOKEN_EQUAL:
         return BINARY_EQUAL;
@@ -210,6 +213,8 @@ binary_operation_precedence(enum Binary_Operation operation)
     case BINARY_DIVIDE:
     case BINARY_MODULO:
         return 11;
+    case BINARY_POWER:
+        return 12;
         // strongest
 
     default:
@@ -241,6 +246,7 @@ binary_operation_associativity(enum Binary_Operation operation)
     case BINARY_ASSIGN_BITWISE_OR:
     case BINARY_ASSIGN_BITWISE_XOR:
     case BINARY_ASSIGN_BITWISE_LEFT_SHIFT:
+    case BINARY_POWER:
         return BINARY_ASSOCIATIVITY_RIGHT;
     default:
         return BINARY_ASSOCIATIVITY_LEFT;
@@ -261,6 +267,8 @@ binary_operation_to_string(enum Binary_Operation operation)
         return "/";
     case BINARY_MODULO:
         return "%";
+    case BINARY_POWER:
+        return "**";
 
     case BINARY_EQUAL:
         return "==";
@@ -323,6 +331,43 @@ binary_operation_to_string(enum Binary_Operation operation)
     }
 }
 
+enum Increment_Decrement_Operation
+{
+    INCREMENT_DECREMENT_NONE,
+    INCREMENT_DECREMENT_INCREMENT,
+    INCREMENT_DECREMENT_DECREMENT,
+};
+
+enum Increment_Decrement_Operation
+increment_decrement_operation_from_token(const struct Token* token)
+{
+    switch (token->kind) {
+    case TOKEN_PLUS_PLUS:
+        return INCREMENT_DECREMENT_INCREMENT;
+    case TOKEN_MINUS_MINUS:
+        return INCREMENT_DECREMENT_DECREMENT;
+
+    default:
+        return INCREMENT_DECREMENT_NONE;
+    }
+}
+
+const ascii*
+increment_decrement_operation_to_string(enum Increment_Decrement_Operation operation)
+{
+    switch (operation) {
+    case INCREMENT_DECREMENT_INCREMENT:
+        return "++";
+    case INCREMENT_DECREMENT_DECREMENT:
+        return "--";
+
+    default:
+        failure("unexpected increment/decrement operation passed to "
+                "`increment_decrement_operation_to_string`");
+        return nil;
+    }
+}
+
 // nodes are parts of the syntax tree that are reused often
 // and in different places.
 
@@ -372,6 +417,7 @@ enum Expression_Kind
     EXPRESSION_CALL,
     EXPRESSION_SUBSCRIPT,
     EXPRESSION_MEMBER,
+    EXPRESSION_INCREMENT_DECREMENT,
 
     EXPRESSION_FUNCTION,
 };
@@ -437,6 +483,14 @@ struct Expression_Member
     struct String name;
 };
 
+struct Expression_Increment_Decrement
+{
+    // whether the increment/decrement is a prefix or postfix operation.
+    bool prefix;
+    struct Expression* subject;
+    enum Increment_Decrement_Operation operation;
+};
+
 #define EXPRESSION_FUNCTION_MAX_PARAMS 32
 
 struct Expression_Function
@@ -465,6 +519,7 @@ union Expression_Value
     struct Expression_Call call;
     struct Expression_Subscript subscript;
     struct Expression_Member member;
+    struct Expression_Increment_Decrement increment_decrement;
     struct Expression_Function function;
 };
 
@@ -563,6 +618,15 @@ expression_print(const struct Expression* expression)
         expression_print(expression->value.member.subject);
         printf(")");
         break;
+    case EXPRESSION_INCREMENT_DECREMENT: {
+        const struct Expression_Increment_Decrement* inc_dec =
+            &expression->value.increment_decrement;
+        const ascii* prefix_or_postfix = inc_dec->prefix ? "prefix" : "postfix";
+        printf("(increment/decrement %s %s ",
+               increment_decrement_operation_to_string(inc_dec->operation), prefix_or_postfix);
+        expression_print(inc_dec->subject);
+        break;
+    }
     case EXPRESSION_FUNCTION: {
         const struct Expression_Function* fun = &expression->value.function;
         printf("(function");