aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/lex.c14
-rw-r--r--boot/tree.c34
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: