From 71f94bff76b419b8382ee6f622121e43124427a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 14 Aug 2018 19:22:48 +0100 Subject: [PATCH] Minor sanity features for `bit_set` --- core/fmt/fmt.odin | 9 +++--- core/strconv/strconv.odin | 15 +++++---- examples/demo/demo.odin | 67 ++++++++++++++++++++++++++++----------- src/check_expr.cpp | 18 ++++------- src/check_stmt.cpp | 2 +- 5 files changed, 68 insertions(+), 43 deletions(-) diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 316761010..446f06c9b 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -471,10 +471,11 @@ _fmt_int :: proc(fi: ^Fmt_Info, u: u64, base: int, is_signed: bool, bit_size: in buf: [256]byte; start := 0; - flags: strconv.Int_Flag; - if fi.hash && !fi.zero do flags |= strconv.Int_Flag.Prefix; - if fi.plus do flags |= strconv.Int_Flag.Plus; - if fi.space do flags |= strconv.Int_Flag.Space; + using strconv.Int_Flag; + flags: strconv.Int_Flags; + if fi.hash && !fi.zero do flags |= {Prefix}; + if fi.plus do flags |= {Plus}; + if fi.space do flags |= {Space}; s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags); if fi.hash && fi.zero { diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index b5e57613c..760a45ba7 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -3,10 +3,11 @@ package strconv using import "core:decimal" Int_Flag :: enum { - Prefix = 1<<0, - Plus = 1<<1, - Space = 1<<2, + Prefix, + Plus, + Space, } +Int_Flags :: bit_set[Int_Flag]; parse_bool :: proc(s: string) -> (result: bool = false, ok: bool) { @@ -458,7 +459,7 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned return u, neg; } -append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flag) -> string { +append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: int, digits: string, flags: Int_Flags) -> string { if base < 2 || base > MAX_BASE { panic("strconv: illegal base passed to append_bits"); } @@ -474,7 +475,7 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i } i-=1; a[i] = digits[u % b]; - if flags&Int_Flag.Prefix != nil { + if Int_Flag.Prefix in flags { ok := true; switch base { case 2: i-=1; a[i] = 'b'; @@ -492,9 +493,9 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i switch { case neg: i-=1; a[i] = '-'; - case flags&Int_Flag.Plus != nil: + case Int_Flag.Plus in flags: i-=1; a[i] = '+'; - case flags&Int_Flag.Space != nil: + case Int_Flag.Space in flags: i-=1; a[i] = ' '; } diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 331a1e20d..ce996cd42 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -713,29 +713,58 @@ deprecated_attribute :: proc() { } bit_set_type :: proc() { - using Day :: enum { - Sunday, - Monday, - Tuesday, - Wednesday, - Thursday, - Friday, - Saturday, + { + using Day :: enum { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + } + + Days :: distinct bit_set[Day]; + WEEKEND :: Days{Sunday, Saturday}; + + d: Days; + d = Days{Sunday} | Days{Monday}; + x := Tuesday; + e := d | WEEKEND; + e |= {Monday}; + fmt.println(d, e); + + ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types + fmt.println(ok); + if Saturday in e { + fmt.println("Saturday in", e); + } } + { + using Days :: bit_set { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + } - Days :: distinct bit_set[Day]; - WEEKEND :: Days{Sunday, Saturday}; + WEEKEND :: Days{Sunday, Saturday}; - d: Days; - d = Days{Sunday} | Days{Monday}; - x := Tuesday; - e := d | WEEKEND; - fmt.println(d, e); + d: Days; + d = Days{Sunday} | Days{Monday}; + x := Tuesday; + e := d | WEEKEND; + e |= {Monday}; + fmt.println(d, e); - ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types - fmt.println(ok); - if Saturday in e { - fmt.println("Saturday in", e); + ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types + fmt.println(ok); + if Saturday in e { + fmt.println("Saturday in", e); + } } } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 38a14a8b3..014249747 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -503,16 +503,6 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type } } - // if (is_type_bit_set(dst) && are_types_identical(dst->BitSet.base_type, operand->type)) { - // return 3; - // } - -#if 0 - if (are_types_identical(dst, src) && (!is_type_named(dst) || !is_type_named(src))) { - return 1; - } -#endif - if (is_type_bit_field_value(operand->type) && is_type_integer(type)) { Type *bfv = base_type(operand->type); i32 bits = bfv->BitFieldValue.bits; @@ -2002,7 +1992,7 @@ bool check_binary_array_expr(CheckerContext *c, Token op, Operand *x, Operand *y } -void check_binary_expr(CheckerContext *c, Operand *x, Ast *node) { +void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, bool use_lhs_as_type_hint=false) { GB_ASSERT(node->kind == Ast_BinaryExpr); Operand y_ = {}, *y = &y_; @@ -2065,7 +2055,11 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node) { default: check_expr(c, x, be->left); - check_expr(c, y, be->right); + if (use_lhs_as_type_hint) { + check_expr_with_type_hint(c, y, be->right, x->type); + } else { + check_expr(c, y, be->right); + } break; } if (x->mode == Addressing_Invalid) { diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4a7c6c621..86dd1bd6d 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1163,7 +1163,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { be->right = as->rhs[0]; check_expr(ctx, &lhs, as->lhs[0]); - check_binary_expr(ctx, &rhs, &binary_expr); + check_binary_expr(ctx, &rhs, &binary_expr, true); if (rhs.mode == Addressing_Invalid) { return; }