diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 15545dca1..3f81cb61d 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1146,7 +1146,7 @@ token_precedence :: proc(p: ^Parser, kind: tokenizer.Token_Kind) -> int { .Lt, .Gt, .Lt_Eq, .Gt_Eq: return 5; - case .In, .Notin: + case .In, .Not_In: if p.expr_level < 0 && !p.allow_in_expr { return 0; } @@ -1390,7 +1390,7 @@ check_field_flag_prefixes :: proc(p: ^Parser, name_count: int, allowed_flags, se } for flag in ast.Field_Flag { - if flag notin allowed_flags && flag in flags { + if flag not_in allowed_flags && flag in flags { switch flag { case .Using: error(p, p.curr_tok.pos, "'using' is not allowed within this field list"); @@ -1557,7 +1557,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags if allow_token(p, .Eq) { default_value = parse_expr(p, false); - if ast.Field_Flag.Default_Parameters notin allowed_flags { + if ast.Field_Flag.Default_Parameters not_in allowed_flags { error(p, p.curr_tok.pos, "default parameters are only allowed for procedures"); default_value = nil; } @@ -1585,7 +1585,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags if type != nil && default_value == nil { if p.curr_tok.kind == .String { tag = expect_token(p, .String); - if .Tags notin allowed_flags { + if .Tags not_in allowed_flags { error(p, tag.pos, "Field tags are only allowed within structures"); } } @@ -1644,7 +1644,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags type := eaf.expr; tok: tokenizer.Token; tok.pos = type.pos; - if ast.Field_Flag.Results notin allowed_flags { + if ast.Field_Flag.Results not_in allowed_flags { tok.text = "_"; } diff --git a/core/odin/tokenizer/token.odin b/core/odin/tokenizer/token.odin index 8ec873a59..c5f0247f4 100644 --- a/core/odin/tokenizer/token.odin +++ b/core/odin/tokenizer/token.odin @@ -124,7 +124,7 @@ Token_Kind :: enum u32 { For, Switch, In, - Notin, + Not_In, Do, Case, Break, @@ -259,7 +259,7 @@ tokens := [Token_Kind.COUNT]string { "for", "switch", "in", - "notin", + "not_in", "do", "case", "break", @@ -316,7 +316,7 @@ is_operator :: proc(kind: Token_Kind) -> bool { #partial switch kind { case .B_Operator_Begin .. .B_Operator_End: return true; - case .In, .Notin: + case .In, .Not_In: return true; } return false; diff --git a/core/odin/tokenizer/tokenizer.odin b/core/odin/tokenizer/tokenizer.odin index 26aab7c1c..f7c25f7cf 100644 --- a/core/odin/tokenizer/tokenizer.odin +++ b/core/odin/tokenizer/tokenizer.odin @@ -501,6 +501,9 @@ scan :: proc(t: ^Tokenizer) -> Token { break check_keyword; } } + if kind == .Ident && lit == "notin" { + kind = .Not_In; + } } case '0' <= ch && ch <= '9': kind, lit = scan_number(t, false); @@ -575,12 +578,6 @@ scan :: proc(t: ^Tokenizer) -> Token { } case '>': kind = switch4(t, .Gt, .Gt_Eq, '>', .Shr,.Shr_Eq); - case '≠': kind = .Not_Eq; - case '≤': kind = .Lt_Eq; - case '≥': kind = .Gt_Eq; - case '∈': kind = .In; - case '∉': kind = .Notin; - case '.': if '0' <= t.ch && t.ch <= '9' { kind, lit = scan_number(t, true); diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 935b24286..a6b7e44f5 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1363,7 +1363,7 @@ bit_set_type :: proc() { incl(&x, 'F'); assert('F' in x); excl(&x, 'F'); - assert('F' notin x); + assert('F' not_in x); y |= {1, 4, 2}; assert(2 in y); diff --git a/examples/hms2019/hms2019.odin b/examples/hms2019/hms2019.odin index 2c4712631..5c2e836f8 100644 --- a/examples/hms2019/hms2019.odin +++ b/examples/hms2019/hms2019.odin @@ -1271,7 +1271,7 @@ bit_set_type :: proc() { incl(&x, 'F'); assert('F' in x); excl(&x, 'F'); - assert('F' notin x); + assert('F' not_in x); y |= {1, 4, 2}; assert(2 in y); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c29325ea0..4f1aed898 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2397,7 +2397,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint } case Token_in: - case Token_notin: + case Token_not_in: // IMPORTANT NOTE(bill): This uses right-left evaluation in type checking only no in check_expr(c, y, be->right); @@ -2426,7 +2426,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint if (op.kind == Token_in) { check_assignment(c, x, yt->Map.key, str_lit("map 'in'")); } else { - check_assignment(c, x, yt->Map.key, str_lit("map 'notin'")); + check_assignment(c, x, yt->Map.key, str_lit("map 'not_in'")); } add_package_dependency(c, "runtime", "__dynamic_map_get"); @@ -2436,7 +2436,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint if (op.kind == Token_in) { check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'in'")); } else { - check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'notin'")); + check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'not_in'")); } if (x->mode == Addressing_Constant && y->mode == Addressing_Constant) { ExactValue k = exact_value_to_integer(x->value); diff --git a/src/ir.cpp b/src/ir.cpp index 04c57c37b..b23c81e78 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7302,7 +7302,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { case Token_in: - case Token_notin: { + case Token_not_in: { irValue *left = ir_build_expr(proc, be->left); Type *type = default_type(tv.type); irValue *right = ir_build_expr(proc, be->right); @@ -7313,7 +7313,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { if (be->op.kind == Token_in) { ir_emit_comment(proc, str_lit("map in")); } else { - ir_emit_comment(proc, str_lit("map notin")); + ir_emit_comment(proc, str_lit("map not_in")); } irValue *addr = ir_address_from_load_or_generate_local(proc, right); @@ -7337,7 +7337,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { if (be->op.kind == Token_in) { ir_emit_comment(proc, str_lit("bit_set in")); } else { - ir_emit_comment(proc, str_lit("bit_set notin")); + ir_emit_comment(proc, str_lit("bit_set not_in")); } Type *key_type = rt->BitSet.elem; diff --git a/src/parser.cpp b/src/parser.cpp index 5ba18d4a1..ecb02c803 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1196,7 +1196,7 @@ bool is_token_range(Token tok) { Token expect_operator(AstFile *f) { Token prev = f->curr_token; - if ((prev.kind == Token_in || prev.kind == Token_notin) && (f->expr_level >= 0 || f->allow_in_expr)) { + if ((prev.kind == Token_in || prev.kind == Token_not_in) && (f->expr_level >= 0 || f->allow_in_expr)) { // okay } else if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) { syntax_error(f->curr_token, "Expected an operator, got '%.*s'", @@ -2515,7 +2515,7 @@ i32 token_precedence(AstFile *f, TokenKind t) { return 5; case Token_in: - case Token_notin: + case Token_not_in: if (f->expr_level < 0 && !f->allow_in_expr) { return 0; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index caf93a97a..19cb9b9aa 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -92,7 +92,7 @@ TOKEN_KIND(Token__KeywordBegin, ""), \ TOKEN_KIND(Token_for, "for"), \ TOKEN_KIND(Token_switch, "switch"), \ TOKEN_KIND(Token_in, "in"), \ - TOKEN_KIND(Token_notin, "notin"), \ + TOKEN_KIND(Token_not_in, "not_in"), \ TOKEN_KIND(Token_do, "do"), \ TOKEN_KIND(Token_case, "case"), \ TOKEN_KIND(Token_break, "break"), \ @@ -902,6 +902,10 @@ Token tokenizer_get_token(Tokenizer *t) { break; } } + + if (token.kind == Token_Ident && token.string == "notin") { + token.kind = Token_not_in; + } } } else if (gb_is_between(curr_rune, '0', '9')) { @@ -1029,11 +1033,11 @@ Token tokenizer_get_token(Tokenizer *t) { case '}': token.kind = Token_CloseBrace; break; case '\\': token.kind = Token_BackSlash; break; - case 0x2260: token.kind = Token_NotEq; break; // '≠' - case 0x2264: token.kind = Token_LtEq; break; // '≤' - case 0x2265: token.kind = Token_GtEq; break; // '≥' - case 0x2208: token.kind = Token_in; break; // '∈' - case 0x2209: token.kind = Token_notin; break; // '∉' + // case 0x2260: token.kind = Token_NotEq; break; // '≠' + // case 0x2264: token.kind = Token_LtEq; break; // '≤' + // case 0x2265: token.kind = Token_GtEq; break; // '≥' + // case 0x2208: token.kind = Token_in; break; // '∈' + // case 0x2209: token.kind = Token_not_in; break; // '∉' case '%': token.kind = token_kind_dub_eq(t, '%', Token_Mod, Token_ModEq, Token_ModMod, Token_ModModEq); break;