File tree Expand file tree Collapse file tree 3 files changed +31
-6
lines changed Expand file tree Collapse file tree 3 files changed +31
-6
lines changed Original file line number Diff line number Diff line change @@ -829,10 +829,11 @@ fn (mut g Gen) stmt(node ast.Stmt) {
829
829
}
830
830
ast.EnumDecl {
831
831
enum_name := util.no_dots (node.name)
832
+ is_flag := node.is_flag
832
833
g.enum_typedefs.writeln ('typedef enum {' )
833
834
mut cur_enum_expr := ''
834
835
mut cur_enum_offset := 0
835
- for field in node.fields {
836
+ for i, field in node.fields {
836
837
g.enum_typedefs.write ('\t ${enum_name} _$field.name ' )
837
838
if field.has_expr {
838
839
g.enum_typedefs.write (' = ' )
@@ -843,6 +844,11 @@ fn (mut g Gen) stmt(node ast.Stmt) {
843
844
g.enum_typedefs.write (expr_str)
844
845
cur_enum_expr = expr_str
845
846
cur_enum_offset = 0
847
+ } else if is_flag {
848
+ g.enum_typedefs.write (' = ' )
849
+ cur_enum_expr = '1 << $i '
850
+ g.enum_typedefs.write ((1 << i).str ())
851
+ cur_enum_offset = 0
846
852
}
847
853
cur_value := if cur_enum_offset > 0 { '$cur_enum_expr +$cur_enum_offset ' } else { cur_enum_expr }
848
854
g.enum_typedefs.writeln (', // $cur_value ' )
Original file line number Diff line number Diff line change @@ -1869,13 +1869,19 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
1869
1869
if fields.len > 32 {
1870
1870
p.error ('when an enum is used as bit field, it must have a max of 32 fields' )
1871
1871
}
1872
+ for f in fields {
1873
+ if f.has_expr {
1874
+ p.error_with_pos ('when an enum is used as a bit field, you can not assign custom values' ,
1875
+ f.pos)
1876
+ }
1877
+ }
1872
1878
pubfn := if p.mod == 'main' { 'fn' } else { 'pub fn' }
1873
1879
p.scanner.codegen ('
1874
1880
//
1875
- $pubfn ( e &$enum_name ) has(flag $enum_name ) bool { return (int(*e) & (1 << int(flag))) != 0 }
1876
- $pubfn (mut e $enum_name ) set(flag $enum_name ) { unsafe{ *e = int(*e) | (1 << int(flag)) } }
1877
- $pubfn (mut e $enum_name ) clear(flag $enum_name ) { unsafe{ *e = int(*e) & ~(1 << int(flag)) } }
1878
- $pubfn (mut e $enum_name ) toggle(flag $enum_name ) { unsafe{ *e = int(*e) ^ (1 << int(flag)) } }
1881
+ $pubfn ( e &$enum_name ) has(flag $enum_name ) bool { return (int(*e) & (int(flag))) != 0 }
1882
+ $pubfn (mut e $enum_name ) set(flag $enum_name ) { unsafe{ *e = int(*e) | (int(flag)) } }
1883
+ $pubfn (mut e $enum_name ) clear(flag $enum_name ) { unsafe{ *e = int(*e) & ~(int(flag)) } }
1884
+ $pubfn (mut e $enum_name ) toggle(flag $enum_name ) { unsafe{ *e = int(*e) ^ (int(flag)) } }
1879
1885
//
1880
1886
' )
1881
1887
}
Original file line number Diff line number Diff line change 13
13
14
14
fn test_enum_bitfield () {
15
15
mut a := BfFile{}
16
+ assert 1 == int (BfPermission.read)
17
+ assert 2 == int (BfPermission.write)
18
+ assert 4 == int (BfPermission.execute)
19
+ assert 8 == int (BfPermission.other)
16
20
a.perm.set (.read)
17
21
a.perm.set (.write)
18
22
a.perm.toggle (.execute)
@@ -22,11 +26,20 @@ fn test_enum_bitfield() {
22
26
assert a.perm.has (.execute)
23
27
assert ! a.perm.has (.write)
24
28
assert ! a.perm.has (.other)
25
- mut b := BfPermission.read // TODO: this does nothing currenty just sets the type
29
+ mut b := BfPermission.read | BfPermission.execute
30
+ assert int (b) == 1 + 0 + 4 + 0
31
+ assert b.has (.read)
32
+ assert b.has (.execute)
26
33
b.set (.write)
34
+ assert int (b) == 1 + 2 + 4 + 0
27
35
b.set (.other)
36
+ assert int (b) == 1 + 2 + 4 + 8
28
37
assert b.has (.write)
29
38
assert b.has (.other)
39
+ b.toggle (.read)
40
+ assert int (b) == 0 + 2 + 4 + 8
41
+ b.toggle (.execute)
42
+ assert int (b) == 0 + 2 + 0 + 8
30
43
assert ! b.has (.read)
31
44
assert ! b.has (.execute)
32
45
}
You can’t perform that action at this time.
0 commit comments