Minor sanity features for bit_set

This commit is contained in:
gingerBill
2018-08-14 19:22:48 +01:00
parent c7d6467cfa
commit 71f94bff76
5 changed files with 68 additions and 43 deletions
+5 -4
View File
@@ -471,10 +471,11 @@ _fmt_int :: proc(fi: ^Fmt_Info, u: u64, base: int, is_signed: bool, bit_size: in
buf: [256]byte; buf: [256]byte;
start := 0; start := 0;
flags: strconv.Int_Flag; using strconv.Int_Flag;
if fi.hash && !fi.zero do flags |= strconv.Int_Flag.Prefix; flags: strconv.Int_Flags;
if fi.plus do flags |= strconv.Int_Flag.Plus; if fi.hash && !fi.zero do flags |= {Prefix};
if fi.space do flags |= strconv.Int_Flag.Space; 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); s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags);
if fi.hash && fi.zero { if fi.hash && fi.zero {
+8 -7
View File
@@ -3,10 +3,11 @@ package strconv
using import "core:decimal" using import "core:decimal"
Int_Flag :: enum { Int_Flag :: enum {
Prefix = 1<<0, Prefix,
Plus = 1<<1, Plus,
Space = 1<<2, Space,
} }
Int_Flags :: bit_set[Int_Flag];
parse_bool :: proc(s: string) -> (result: bool = false, ok: bool) { 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; 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 { if base < 2 || base > MAX_BASE {
panic("strconv: illegal base passed to append_bits"); 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]; i-=1; a[i] = digits[u % b];
if flags&Int_Flag.Prefix != nil { if Int_Flag.Prefix in flags {
ok := true; ok := true;
switch base { switch base {
case 2: i-=1; a[i] = 'b'; 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 { switch {
case neg: case neg:
i-=1; a[i] = '-'; i-=1; a[i] = '-';
case flags&Int_Flag.Plus != nil: case Int_Flag.Plus in flags:
i-=1; a[i] = '+'; i-=1; a[i] = '+';
case flags&Int_Flag.Space != nil: case Int_Flag.Space in flags:
i-=1; a[i] = ' '; i-=1; a[i] = ' ';
} }
+29
View File
@@ -713,6 +713,7 @@ deprecated_attribute :: proc() {
} }
bit_set_type :: proc() { bit_set_type :: proc() {
{
using Day :: enum { using Day :: enum {
Sunday, Sunday,
Monday, Monday,
@@ -730,6 +731,7 @@ bit_set_type :: proc() {
d = Days{Sunday} | Days{Monday}; d = Days{Sunday} | Days{Monday};
x := Tuesday; x := Tuesday;
e := d | WEEKEND; e := d | WEEKEND;
e |= {Monday};
fmt.println(d, e); fmt.println(d, e);
ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types
@@ -738,6 +740,33 @@ bit_set_type :: proc() {
fmt.println("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);
}
}
}
main :: proc() { main :: proc() {
when true { when true {
+5 -11
View File
@@ -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)) { if (is_type_bit_field_value(operand->type) && is_type_integer(type)) {
Type *bfv = base_type(operand->type); Type *bfv = base_type(operand->type);
i32 bits = bfv->BitFieldValue.bits; 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); GB_ASSERT(node->kind == Ast_BinaryExpr);
Operand y_ = {}, *y = &y_; Operand y_ = {}, *y = &y_;
@@ -2065,7 +2055,11 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node) {
default: default:
check_expr(c, x, be->left); check_expr(c, x, be->left);
if (use_lhs_as_type_hint) {
check_expr_with_type_hint(c, y, be->right, x->type);
} else {
check_expr(c, y, be->right); check_expr(c, y, be->right);
}
break; break;
} }
if (x->mode == Addressing_Invalid) { if (x->mode == Addressing_Invalid) {
+1 -1
View File
@@ -1163,7 +1163,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
be->right = as->rhs[0]; be->right = as->rhs[0];
check_expr(ctx, &lhs, as->lhs[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) { if (rhs.mode == Addressing_Invalid) {
return; return;
} }