mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Allow not_in as keyword over notin, but still allow notin to work
This commit is contained in:
@@ -1146,7 +1146,7 @@ token_precedence :: proc(p: ^Parser, kind: tokenizer.Token_Kind) -> int {
|
|||||||
.Lt, .Gt,
|
.Lt, .Gt,
|
||||||
.Lt_Eq, .Gt_Eq:
|
.Lt_Eq, .Gt_Eq:
|
||||||
return 5;
|
return 5;
|
||||||
case .In, .Notin:
|
case .In, .Not_In:
|
||||||
if p.expr_level < 0 && !p.allow_in_expr {
|
if p.expr_level < 0 && !p.allow_in_expr {
|
||||||
return 0;
|
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 {
|
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 {
|
switch flag {
|
||||||
case .Using:
|
case .Using:
|
||||||
error(p, p.curr_tok.pos, "'using' is not allowed within this field list");
|
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) {
|
if allow_token(p, .Eq) {
|
||||||
default_value = parse_expr(p, false);
|
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");
|
error(p, p.curr_tok.pos, "default parameters are only allowed for procedures");
|
||||||
default_value = nil;
|
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 type != nil && default_value == nil {
|
||||||
if p.curr_tok.kind == .String {
|
if p.curr_tok.kind == .String {
|
||||||
tag = expect_token(p, .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");
|
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;
|
type := eaf.expr;
|
||||||
tok: tokenizer.Token;
|
tok: tokenizer.Token;
|
||||||
tok.pos = type.pos;
|
tok.pos = type.pos;
|
||||||
if ast.Field_Flag.Results notin allowed_flags {
|
if ast.Field_Flag.Results not_in allowed_flags {
|
||||||
tok.text = "_";
|
tok.text = "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ Token_Kind :: enum u32 {
|
|||||||
For,
|
For,
|
||||||
Switch,
|
Switch,
|
||||||
In,
|
In,
|
||||||
Notin,
|
Not_In,
|
||||||
Do,
|
Do,
|
||||||
Case,
|
Case,
|
||||||
Break,
|
Break,
|
||||||
@@ -259,7 +259,7 @@ tokens := [Token_Kind.COUNT]string {
|
|||||||
"for",
|
"for",
|
||||||
"switch",
|
"switch",
|
||||||
"in",
|
"in",
|
||||||
"notin",
|
"not_in",
|
||||||
"do",
|
"do",
|
||||||
"case",
|
"case",
|
||||||
"break",
|
"break",
|
||||||
@@ -316,7 +316,7 @@ is_operator :: proc(kind: Token_Kind) -> bool {
|
|||||||
#partial switch kind {
|
#partial switch kind {
|
||||||
case .B_Operator_Begin .. .B_Operator_End:
|
case .B_Operator_Begin .. .B_Operator_End:
|
||||||
return true;
|
return true;
|
||||||
case .In, .Notin:
|
case .In, .Not_In:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -501,6 +501,9 @@ scan :: proc(t: ^Tokenizer) -> Token {
|
|||||||
break check_keyword;
|
break check_keyword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if kind == .Ident && lit == "notin" {
|
||||||
|
kind = .Not_In;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case '0' <= ch && ch <= '9':
|
case '0' <= ch && ch <= '9':
|
||||||
kind, lit = scan_number(t, false);
|
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 = 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 '.':
|
case '.':
|
||||||
if '0' <= t.ch && t.ch <= '9' {
|
if '0' <= t.ch && t.ch <= '9' {
|
||||||
kind, lit = scan_number(t, true);
|
kind, lit = scan_number(t, true);
|
||||||
|
|||||||
@@ -1363,7 +1363,7 @@ bit_set_type :: proc() {
|
|||||||
incl(&x, 'F');
|
incl(&x, 'F');
|
||||||
assert('F' in x);
|
assert('F' in x);
|
||||||
excl(&x, 'F');
|
excl(&x, 'F');
|
||||||
assert('F' notin x);
|
assert('F' not_in x);
|
||||||
|
|
||||||
y |= {1, 4, 2};
|
y |= {1, 4, 2};
|
||||||
assert(2 in y);
|
assert(2 in y);
|
||||||
|
|||||||
@@ -1271,7 +1271,7 @@ bit_set_type :: proc() {
|
|||||||
incl(&x, 'F');
|
incl(&x, 'F');
|
||||||
assert('F' in x);
|
assert('F' in x);
|
||||||
excl(&x, 'F');
|
excl(&x, 'F');
|
||||||
assert('F' notin x);
|
assert('F' not_in x);
|
||||||
|
|
||||||
y |= {1, 4, 2};
|
y |= {1, 4, 2};
|
||||||
assert(2 in y);
|
assert(2 in y);
|
||||||
|
|||||||
+3
-3
@@ -2397,7 +2397,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Token_in:
|
case Token_in:
|
||||||
case Token_notin:
|
case Token_not_in:
|
||||||
// IMPORTANT NOTE(bill): This uses right-left evaluation in type checking only no in
|
// IMPORTANT NOTE(bill): This uses right-left evaluation in type checking only no in
|
||||||
|
|
||||||
check_expr(c, y, be->right);
|
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) {
|
if (op.kind == Token_in) {
|
||||||
check_assignment(c, x, yt->Map.key, str_lit("map 'in'"));
|
check_assignment(c, x, yt->Map.key, str_lit("map 'in'"));
|
||||||
} else {
|
} 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");
|
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) {
|
if (op.kind == Token_in) {
|
||||||
check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'in'"));
|
check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'in'"));
|
||||||
} else {
|
} 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) {
|
if (x->mode == Addressing_Constant && y->mode == Addressing_Constant) {
|
||||||
ExactValue k = exact_value_to_integer(x->value);
|
ExactValue k = exact_value_to_integer(x->value);
|
||||||
|
|||||||
+3
-3
@@ -7302,7 +7302,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
|||||||
|
|
||||||
|
|
||||||
case Token_in:
|
case Token_in:
|
||||||
case Token_notin: {
|
case Token_not_in: {
|
||||||
irValue *left = ir_build_expr(proc, be->left);
|
irValue *left = ir_build_expr(proc, be->left);
|
||||||
Type *type = default_type(tv.type);
|
Type *type = default_type(tv.type);
|
||||||
irValue *right = ir_build_expr(proc, be->right);
|
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) {
|
if (be->op.kind == Token_in) {
|
||||||
ir_emit_comment(proc, str_lit("map in"));
|
ir_emit_comment(proc, str_lit("map in"));
|
||||||
} else {
|
} 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);
|
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) {
|
if (be->op.kind == Token_in) {
|
||||||
ir_emit_comment(proc, str_lit("bit_set in"));
|
ir_emit_comment(proc, str_lit("bit_set in"));
|
||||||
} else {
|
} 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;
|
Type *key_type = rt->BitSet.elem;
|
||||||
|
|||||||
+2
-2
@@ -1196,7 +1196,7 @@ bool is_token_range(Token tok) {
|
|||||||
|
|
||||||
Token expect_operator(AstFile *f) {
|
Token expect_operator(AstFile *f) {
|
||||||
Token prev = f->curr_token;
|
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
|
// okay
|
||||||
} else if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
|
} else if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
|
||||||
syntax_error(f->curr_token, "Expected an operator, got '%.*s'",
|
syntax_error(f->curr_token, "Expected an operator, got '%.*s'",
|
||||||
@@ -2515,7 +2515,7 @@ i32 token_precedence(AstFile *f, TokenKind t) {
|
|||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
case Token_in:
|
case Token_in:
|
||||||
case Token_notin:
|
case Token_not_in:
|
||||||
if (f->expr_level < 0 && !f->allow_in_expr) {
|
if (f->expr_level < 0 && !f->allow_in_expr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-6
@@ -92,7 +92,7 @@ TOKEN_KIND(Token__KeywordBegin, ""), \
|
|||||||
TOKEN_KIND(Token_for, "for"), \
|
TOKEN_KIND(Token_for, "for"), \
|
||||||
TOKEN_KIND(Token_switch, "switch"), \
|
TOKEN_KIND(Token_switch, "switch"), \
|
||||||
TOKEN_KIND(Token_in, "in"), \
|
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_do, "do"), \
|
||||||
TOKEN_KIND(Token_case, "case"), \
|
TOKEN_KIND(Token_case, "case"), \
|
||||||
TOKEN_KIND(Token_break, "break"), \
|
TOKEN_KIND(Token_break, "break"), \
|
||||||
@@ -902,6 +902,10 @@ Token tokenizer_get_token(Tokenizer *t) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token.kind == Token_Ident && token.string == "notin") {
|
||||||
|
token.kind = Token_not_in;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (gb_is_between(curr_rune, '0', '9')) {
|
} 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_CloseBrace; break;
|
||||||
case '\\': token.kind = Token_BackSlash; break;
|
case '\\': token.kind = Token_BackSlash; break;
|
||||||
|
|
||||||
case 0x2260: token.kind = Token_NotEq; break; // '≠'
|
// case 0x2260: token.kind = Token_NotEq; break; // '≠'
|
||||||
case 0x2264: token.kind = Token_LtEq; break; // '≤'
|
// case 0x2264: token.kind = Token_LtEq; break; // '≤'
|
||||||
case 0x2265: token.kind = Token_GtEq; break; // '≥'
|
// case 0x2265: token.kind = Token_GtEq; break; // '≥'
|
||||||
case 0x2208: token.kind = Token_in; break; // '∈'
|
// case 0x2208: token.kind = Token_in; break; // '∈'
|
||||||
case 0x2209: token.kind = Token_notin; 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;
|
case '%': token.kind = token_kind_dub_eq(t, '%', Token_Mod, Token_ModEq, Token_ModMod, Token_ModModEq); break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user