diff options
| author | Mel <mel@rnrd.eu> | 2025-06-03 22:41:35 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-06-03 22:41:35 +0200 |
| commit | 8b655fe0f1d6589c9216a6244c067aec1d866be7 (patch) | |
| tree | 4e6a9743b1c4a2e339e39fefc08340ed9fd824a0 | |
| parent | 4940b308ca62257acb79dc4a5a240dc76c780a06 (diff) | |
| download | catskill-8b655fe0f1d6589c9216a6244c067aec1d866be7.tar.zst catskill-8b655fe0f1d6589c9216a6244c067aec1d866be7.zip | |
Range binary operation
Signed-off-by: Mel <mel@rnrd.eu>
| -rw-r--r-- | boot/lex.c | 14 | ||||
| -rw-r--r-- | boot/tree.c | 34 |
2 files changed, 35 insertions, 13 deletions
diff --git a/boot/lex.c b/boot/lex.c index 30f4071..6b6badc 100644 --- a/boot/lex.c +++ b/boot/lex.c @@ -111,6 +111,7 @@ enum Token_Kind TOKEN_COMMA, TOKEN_AMPERSAND, TOKEN_DOT, + TOKEN_DOT_DOT, TOKEN_BANG, TOKEN_PERCENT, TOKEN_PIPE, @@ -223,6 +224,8 @@ token_kind_to_string(enum Token_Kind kind) return "AMPERSAND"; case TOKEN_DOT: return "DOT"; + case TOKEN_DOT_DOT: + return "DOT_DOT"; case TOKEN_BANG: return "BANG"; case TOKEN_PERCENT: @@ -551,7 +554,6 @@ lexer_symbol_token(struct Lexer* l, struct Lexer_Char current) case ']': RET{ TOKEN_SQUARE_CLOSE, 1 }; - case ',': RET{ TOKEN_COMMA, 1 }; case '&': { @@ -565,6 +567,8 @@ lexer_symbol_token(struct Lexer* l, struct Lexer_Char current) RET{ TOKEN_AMPERSAND, 1 }; } case '.': + a = lexer_match_char(l, '.'); + if (a.got_match) RET{ TOKEN_DOT_DOT, 2 }; RET{ TOKEN_DOT, 1 }; case '!': { a = lexer_match_char(l, '='); @@ -691,8 +695,14 @@ lexer_number_token(struct Lexer* l) uint buffer_size = 0; for (;;) { struct Lexer_Char c = lexer_peek_char(l); - bool is_number_char = ascii_is_number(c.character) || c.character == '.'; + bool is_dot = c.character == '.'; + bool is_number_char = ascii_is_number(c.character) || is_dot; if (c.eof || !is_number_char) break; + if (is_dot) { + struct Lexer_Char next = lexer_peek_char_further(l); + // two dots in a row means a range, not a number. + if (next.character == '.') break; + } check(buffer_size < MAX_CHAR_BUFFER_SIZE, "number too long to lex"); buffer[buffer_size++] = c.character; diff --git a/boot/tree.c b/boot/tree.c index 6e7fd6a..39a1de4 100644 --- a/boot/tree.c +++ b/boot/tree.c @@ -65,6 +65,8 @@ enum Binary_Operation BINARY_AND, BINARY_OR, + BINARY_RANGE, + BINARY_BITWISE_AND, BINARY_BITWISE_OR, BINARY_BITWISE_XOR, @@ -120,6 +122,9 @@ binary_operation_from_token(const struct Token* token) case TOKEN_OR: return BINARY_OR; + case TOKEN_DOT_DOT: + return BINARY_RANGE; + case TOKEN_AMPERSAND: return BINARY_BITWISE_AND; case TOKEN_PIPE: @@ -185,36 +190,38 @@ binary_operation_precedence(enum Binary_Operation operation) case BINARY_ASSIGN_BITWISE_LEFT_SHIFT: case BINARY_ASSIGN_BITWISE_RIGHT_SHIFT: return 1; - case BINARY_OR: + case BINARY_RANGE: return 2; - case BINARY_AND: + case BINARY_OR: return 3; - case BINARY_BITWISE_OR: + case BINARY_AND: return 4; - case BINARY_BITWISE_XOR: + case BINARY_BITWISE_OR: return 5; - case BINARY_BITWISE_AND: + case BINARY_BITWISE_XOR: return 6; + case BINARY_BITWISE_AND: + return 7; case BINARY_EQUAL: case BINARY_NOT_EQUAL: - return 7; + return 8; case BINARY_GREATER_THAN: case BINARY_GREATER_THAN_EQUAL: case BINARY_LESS_THAN: case BINARY_LESS_THAN_EQUAL: - return 8; + return 9; case BINARY_BITWISE_LEFT_SHIFT: case BINARY_BITWISE_RIGHT_SHIFT: - return 9; + return 10; case BINARY_PLUS: case BINARY_MINUS: - return 10; + return 11; case BINARY_MULTIPLY: case BINARY_DIVIDE: case BINARY_MODULO: - return 11; - case BINARY_POWER: return 12; + case BINARY_POWER: + return 13; // strongest default: @@ -248,6 +255,8 @@ binary_operation_associativity(enum Binary_Operation operation) case BINARY_ASSIGN_BITWISE_LEFT_SHIFT: case BINARY_POWER: return BINARY_ASSOCIATIVITY_RIGHT; + case BINARY_RANGE: + return BINARY_ASSOCIATIVITY_NONE; default: return BINARY_ASSOCIATIVITY_LEFT; } @@ -287,6 +296,9 @@ binary_operation_to_string(enum Binary_Operation operation) case BINARY_OR: return "||"; + case BINARY_RANGE: + return ".."; + case BINARY_BITWISE_AND: return "&"; case BINARY_BITWISE_OR: |
