From f4bcdb0373ac34349c6ecdb9a894c561e0cd419c Mon Sep 17 00:00:00 2001 From: Mel Date: Tue, 3 Jun 2025 01:46:34 +0200 Subject: Parse and lex ++, --, ** operators, with prefix and postfix handling Signed-off-by: Mel --- boot/tree.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'boot/tree.c') 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"); -- cgit 1.4.1