parser: generate all flagged enum functions, no matter what the backend is; tag them with @[flag_enum_fn], and let the backends filter them out, if they do not support them (#22543)

This commit is contained in:
Delyan Angelov 2024-10-16 23:09:22 +03:00 committed by GitHub
parent 3326392ce2
commit 5f413f48f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 24 additions and 7 deletions

View File

@ -3082,6 +3082,10 @@ fn (mut c Amd64) infloop() {
}
fn (mut c Amd64) fn_decl(node ast.FnDecl) {
if node.attrs.contains('flag_enum_fn') {
// TODO: remove, when the native backend can process all flagged enum generated functions
return
}
c.push(Amd64Register.rbp)
c.mov_reg(Amd64Register.rbp, Amd64Register.rsp)
local_alloc_pos := c.g.pos()

View File

@ -109,6 +109,10 @@ fn (mut c Arm64) sub_sp(v i32) {
}
pub fn (mut c Arm64) fn_decl(node ast.FnDecl) {
if node.attrs.contains('flag_enum_fn') {
// TODO: remove, when the native backend can process all flagged enum generated functions
return
}
c.g.gen_arm64_helloworld()
/*
0x100003f6c ff8300d1 sub sp, sp, 0x20 ; [00] -r-x section size 52 named 0.__TEXT.__text

View File

@ -53,6 +53,10 @@ fn (mut g Gen) comptime_is_truthy(cond ast.Expr) bool {
.ne {
return g.comptime_is_truthy(cond.left) != g.comptime_is_truthy(cond.right)
}
.key_is {
// TODO: implement properly, to support @[flag_enum_fn] functions
return true
}
else {
g.n_error('Compile time infix expr `${cond}` is not handled by the native backend.')
}

View File

@ -1035,6 +1035,11 @@ fn (mut g Gen) delay_fn_call(name string) {
}
fn (mut g Gen) fn_decl(node ast.FnDecl) {
if node.attrs.contains('flag_enum_fn') {
// TODO: remove, when the native backend can process all flagged enum generated functions
return
}
name := if node.is_method {
'${g.table.get_type_name(node.receiver.typ)}.${node.name}'
} else {

View File

@ -179,6 +179,11 @@ pub fn (mut g Gen) fn_decl(node ast.FnDecl) {
return
}
if node.attrs.contains('flag_enum_fn') {
// TODO: remove, when support for fn results is done
return
}
name := if node.is_method {
'${g.table.get_type_name(node.receiver.typ)}.${node.name}'
} else {

View File

@ -4241,7 +4241,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
p.check(.rcbr)
is_flag := p.attrs.contains('flag')
is_multi_allowed := p.attrs.contains('_allow_multiple_values')
pubfn := if p.mod == 'main' { 'fn' } else { 'pub fn' }
pubfn := if p.mod == 'main' { '@[flag_enum_fn] fn' } else { '@[flag_enum_fn] pub fn' }
if is_flag {
if fields.len > 64 {
p.error('when an enum is used as bit field, it must have a max of 64 fields')
@ -4317,12 +4317,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
}
}
if enum_name[0].is_capital() && fields.len > 0 {
// TODO: this check is to prevent avoidable later stage checker errors for generated code,
// since currently there is no way to show the proper source context :-|.
if p.pref.backend == .c {
// TODO: improve the other backends, to the point where they can handle generics or comptime checks too
p.codegen(code_for_from_fn)
}
p.codegen(code_for_from_fn)
}
idx := p.table.register_sym(ast.TypeSymbol{