Browse Source

Minor sanity features for `bit_set`

gingerBill 7 years ago
parent
commit
71f94bff76
5 changed files with 72 additions and 47 deletions
  1. 5 4
      core/fmt/fmt.odin
  2. 8 7
      core/strconv/strconv.odin
  3. 52 23
      examples/demo/demo.odin
  4. 6 12
      src/check_expr.cpp
  5. 1 1
      src/check_stmt.cpp

+ 5 - 4
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 {

+ 8 - 7
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] = ' ';
 	}
 

+ 52 - 23
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,
-	}
-
-	Days :: distinct bit_set[Day];
-	WEEKEND :: Days{Sunday, Saturday};
-
-	d: Days;
-	d = Days{Sunday} | Days{Monday};
-	x := Tuesday;
-	e := d | WEEKEND;
-	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 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,
+		}
+
+		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);
+		}
 	}
 }
 

+ 6 - 12
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) {

+ 1 - 1
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;
 			}