mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-18 00:48:23 +00:00
Allow ..= alongside .. as a "full range" operator; Update core:odin/parser etc
This commit is contained in:
@@ -5940,8 +5940,9 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu
|
||||
|
||||
TokenKind op = Token_Lt;
|
||||
switch (ie->op.kind) {
|
||||
case Token_Ellipsis: op = Token_LtEq; break;
|
||||
case Token_RangeHalf: op = Token_Lt; break;
|
||||
case Token_Ellipsis: op = Token_LtEq; break; // ..
|
||||
case Token_RangeFull: op = Token_LtEq; break; // ..=
|
||||
case Token_RangeHalf: op = Token_Lt; break; // ..<
|
||||
default: error(ie->op, "Invalid range operator"); break;
|
||||
}
|
||||
bool ok = compare_exact_values(op, a, b);
|
||||
@@ -5952,7 +5953,7 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu
|
||||
}
|
||||
|
||||
ExactValue inline_for_depth = exact_value_sub(b, a);
|
||||
if (ie->op.kind == Token_Ellipsis) {
|
||||
if (ie->op.kind != Token_RangeHalf) {
|
||||
inline_for_depth = exact_value_increment_one(inline_for_depth);
|
||||
}
|
||||
|
||||
|
||||
@@ -939,6 +939,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||
TokenKind upper_op = Token_Invalid;
|
||||
switch (be->op.kind) {
|
||||
case Token_Ellipsis: upper_op = Token_GtEq; break;
|
||||
case Token_RangeFull: upper_op = Token_GtEq; break;
|
||||
case Token_RangeHalf: upper_op = Token_Gt; break;
|
||||
default: GB_PANIC("Invalid range operator"); break;
|
||||
}
|
||||
|
||||
@@ -931,6 +931,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no
|
||||
|
||||
switch (be->op.kind) {
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
if (upper - lower >= bits) {
|
||||
error(bs->elem, "bit_set range is greater than %lld bits, %lld bits are required", bits, (upper-lower+1));
|
||||
}
|
||||
|
||||
@@ -4041,6 +4041,7 @@ void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
|
||||
TokenKind op = Token_Lt;
|
||||
switch (node->op.kind) {
|
||||
case Token_Ellipsis: op = Token_LtEq; break;
|
||||
case Token_RangeFull: op = Token_LtEq; break;
|
||||
case Token_RangeHalf: op = Token_Lt; break;
|
||||
default: GB_PANIC("Invalid interval operator"); break;
|
||||
}
|
||||
@@ -4454,7 +4455,7 @@ void lb_build_inline_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s
|
||||
|
||||
ExactValue start = start_expr->tav.value;
|
||||
ExactValue end = end_expr->tav.value;
|
||||
if (op == Token_Ellipsis) { // .. [start, end]
|
||||
if (op != Token_RangeHalf) { // .. [start, end] (or ..=)
|
||||
ExactValue index = exact_value_i64(0);
|
||||
for (ExactValue val = start;
|
||||
compare_exact_values(Token_LtEq, val, end);
|
||||
@@ -4465,7 +4466,7 @@ void lb_build_inline_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s
|
||||
|
||||
lb_build_stmt(p, rs->body);
|
||||
}
|
||||
} else if (op == Token_RangeHalf) { // ..< [start, end)
|
||||
} else { // ..< [start, end)
|
||||
ExactValue index = exact_value_i64(0);
|
||||
for (ExactValue val = start;
|
||||
compare_exact_values(Token_Lt, val, end);
|
||||
@@ -4632,6 +4633,7 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
|
||||
TokenKind op = Token_Invalid;
|
||||
switch (ie->op.kind) {
|
||||
case Token_Ellipsis: op = Token_LtEq; break;
|
||||
case Token_RangeFull: op = Token_LtEq; break;
|
||||
case Token_RangeHalf: op = Token_Lt; break;
|
||||
default: GB_PANIC("Invalid interval operator"); break;
|
||||
}
|
||||
|
||||
@@ -1344,6 +1344,7 @@ Token expect_token_after(AstFile *f, TokenKind kind, char const *msg) {
|
||||
bool is_token_range(TokenKind kind) {
|
||||
switch (kind) {
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
case Token_RangeHalf:
|
||||
return true;
|
||||
}
|
||||
@@ -1574,6 +1575,10 @@ void expect_semicolon(AstFile *f, Ast *s) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->curr_token.kind == Token_EOF) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s != nullptr) {
|
||||
bool insert_semi = (f->tokenizer.flags & TokenizerFlag_InsertSemicolon) != 0;
|
||||
if (insert_semi) {
|
||||
@@ -2315,7 +2320,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
||||
f->expr_level = prev_level;
|
||||
}
|
||||
|
||||
|
||||
skip_possible_newline_for_literal(f);
|
||||
Token open = expect_token_after(f, Token_OpenBrace, "struct");
|
||||
|
||||
isize name_count = 0;
|
||||
@@ -2675,6 +2680,7 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
case Token_RangeHalf:
|
||||
// NOTE(bill): Do not err yet
|
||||
case Token_Colon:
|
||||
@@ -2686,6 +2692,7 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
|
||||
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
case Token_RangeHalf:
|
||||
syntax_error(f->curr_token, "Expected a colon, not a range");
|
||||
/* fallthrough */
|
||||
@@ -2812,6 +2819,7 @@ i32 token_precedence(AstFile *f, TokenKind t) {
|
||||
case Token_when:
|
||||
return 1;
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
case Token_RangeHalf:
|
||||
if (!f->allow_range) {
|
||||
return 0;
|
||||
@@ -3926,12 +3934,6 @@ Ast *parse_return_stmt(AstFile *f) {
|
||||
|
||||
while (f->curr_token.kind != Token_Semicolon) {
|
||||
Ast *arg = parse_expr(f, false);
|
||||
// if (f->curr_token.kind == Token_Eq) {
|
||||
// Token eq = expect_token(f, Token_Eq);
|
||||
// Ast *value = parse_value(f);
|
||||
// arg = ast_field_value(f, arg, value, eq);
|
||||
// }
|
||||
|
||||
array_add(&results, arg);
|
||||
if (f->curr_token.kind != Token_Comma ||
|
||||
f->curr_token.kind == Token_EOF) {
|
||||
@@ -4052,7 +4054,7 @@ Ast *parse_case_clause(AstFile *f, bool is_type) {
|
||||
}
|
||||
f->allow_range = prev_allow_range;
|
||||
f->allow_in_expr = prev_allow_in_expr;
|
||||
expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
|
||||
expect_token(f, Token_Colon);
|
||||
Array<Ast *> stmts = parse_stmt_list(f);
|
||||
|
||||
return ast_case_clause(f, token, list, stmts);
|
||||
|
||||
@@ -76,6 +76,7 @@ TOKEN_KIND(Token__ComparisonEnd, ""), \
|
||||
TOKEN_KIND(Token_Period, "."), \
|
||||
TOKEN_KIND(Token_Comma, ","), \
|
||||
TOKEN_KIND(Token_Ellipsis, ".."), \
|
||||
TOKEN_KIND(Token_RangeFull, "..="), \
|
||||
TOKEN_KIND(Token_RangeHalf, "..<"), \
|
||||
TOKEN_KIND(Token_BackSlash, "\\"), \
|
||||
TOKEN_KIND(Token__OperatorEnd, ""), \
|
||||
@@ -1204,6 +1205,9 @@ void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) {
|
||||
if (t->curr_rune == '<') {
|
||||
advance_to_next_rune(t);
|
||||
token->kind = Token_RangeHalf;
|
||||
} else if (t->curr_rune == '=') {
|
||||
advance_to_next_rune(t);
|
||||
token->kind = Token_RangeFull;
|
||||
}
|
||||
} else if ('0' <= t->curr_rune && t->curr_rune <= '9') {
|
||||
scan_number_to_token(t, token, true);
|
||||
|
||||
Reference in New Issue
Block a user