compiler: add support for `[if myflag]` void fn/methods
parent
945f964c0c
commit
9a19531909
|
@ -211,6 +211,7 @@ pub:
|
||||||
is_js bool
|
is_js bool
|
||||||
no_body bool // just a definition `fn C.malloc()`
|
no_body bool // just a definition `fn C.malloc()`
|
||||||
is_builtin bool // this function is defined in builtin/strconv
|
is_builtin bool // this function is defined in builtin/strconv
|
||||||
|
ctdefine string // has [if myflag] tag
|
||||||
pos token.Position
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +236,7 @@ mut:
|
||||||
left_type table.Type // type of `user`
|
left_type table.Type // type of `user`
|
||||||
receiver_type table.Type // User
|
receiver_type table.Type // User
|
||||||
return_type table.Type
|
return_type table.Type
|
||||||
|
should_be_skipped bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallArg {
|
pub struct CallArg {
|
||||||
|
|
|
@ -120,6 +120,11 @@ fn (c mut Checker) check_file_in_main(file ast.File) bool {
|
||||||
c.warn('function `$it.name` $no_pub_in_main_warning', it.pos)
|
c.warn('function `$it.name` $no_pub_in_main_warning', it.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if it.ctdefine.len > 0 {
|
||||||
|
if it.return_type != table.void_type {
|
||||||
|
c.error('only functions that do NOT return values can have `[if ${it.ctdefine}]` tags', it.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
if it.is_pub {
|
if it.is_pub {
|
||||||
|
@ -497,6 +502,9 @@ pub fn (c mut Checker) call_method(call_expr mut ast.CallExpr) table.Type {
|
||||||
//println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod')
|
//println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod')
|
||||||
c.error('method `${left_type_sym.name}.$method_name` is private', call_expr.pos)
|
c.error('method `${left_type_sym.name}.$method_name` is private', call_expr.pos)
|
||||||
}
|
}
|
||||||
|
if method.return_type == table.void_type && method.ctdefine.len > 0 && method.ctdefine !in c.pref.compile_defines {
|
||||||
|
call_expr.should_be_skipped = true
|
||||||
|
}
|
||||||
nr_args := if method.args.len == 0 { 0 } else {method.args.len - 1}
|
nr_args := if method.args.len == 0 { 0 } else {method.args.len - 1}
|
||||||
min_required_args := method.args.len - if method.is_variadic && method.args.len > 1 { 2 } else { 1 }
|
min_required_args := method.args.len - if method.is_variadic && method.args.len > 1 { 2 } else { 1 }
|
||||||
if call_expr.args.len < min_required_args {
|
if call_expr.args.len < min_required_args {
|
||||||
|
@ -612,6 +620,11 @@ pub fn (c mut Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
call_expr.return_type = f.return_type
|
call_expr.return_type = f.return_type
|
||||||
|
|
||||||
|
if f.return_type == table.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines {
|
||||||
|
call_expr.should_be_skipped = true
|
||||||
|
}
|
||||||
|
|
||||||
if f.is_c || call_expr.is_c || f.is_js || call_expr.is_js {
|
if f.is_c || call_expr.is_c || f.is_js || call_expr.is_js {
|
||||||
for arg in call_expr.args {
|
for arg in call_expr.args {
|
||||||
c.expr(arg.expr)
|
c.expr(arg.expr)
|
||||||
|
|
|
@ -224,6 +224,9 @@ fn (mut g Gen) fn_args(args []table.Arg, is_variadic bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) call_expr(node ast.CallExpr) {
|
fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
|
if node.should_be_skipped {
|
||||||
|
return
|
||||||
|
}
|
||||||
gen_or := !g.is_assign_rhs && node.or_block.stmts.len > 0
|
gen_or := !g.is_assign_rhs && node.or_block.stmts.len > 0
|
||||||
tmp_opt := if gen_or { g.new_tmp_var() } else { '' }
|
tmp_opt := if gen_or { g.new_tmp_var() } else { '' }
|
||||||
if gen_or {
|
if gen_or {
|
||||||
|
|
|
@ -170,6 +170,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
end_pos = p.tok.position()
|
end_pos = p.tok.position()
|
||||||
return_type = p.parse_type()
|
return_type = p.parse_type()
|
||||||
}
|
}
|
||||||
|
ctdefine := p.attr_ctdefine
|
||||||
// Register
|
// Register
|
||||||
if is_method {
|
if is_method {
|
||||||
mut type_sym := p.table.get_type_symbol(rec_type)
|
mut type_sym := p.table.get_type_symbol(rec_type)
|
||||||
|
@ -181,6 +182,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
is_variadic: is_variadic
|
is_variadic: is_variadic
|
||||||
is_generic: is_generic
|
is_generic: is_generic
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
|
ctdefine: ctdefine
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if is_c {
|
if is_c {
|
||||||
|
@ -202,6 +204,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
is_js: is_js
|
is_js: is_js
|
||||||
is_generic: is_generic
|
is_generic: is_generic
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
|
ctdefine: ctdefine
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Body
|
// Body
|
||||||
|
@ -212,6 +215,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
}
|
}
|
||||||
p.close_scope()
|
p.close_scope()
|
||||||
p.attr = ''
|
p.attr = ''
|
||||||
|
p.attr_ctdefine = ''
|
||||||
return ast.FnDecl{
|
return ast.FnDecl{
|
||||||
name: name
|
name: name
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
|
@ -231,6 +235,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
no_body: no_body
|
no_body: no_body
|
||||||
pos: start_pos.extend(end_pos)
|
pos: start_pos.extend(end_pos)
|
||||||
is_builtin: p.builtin_mod || p.mod in util.builtin_module_parts
|
is_builtin: p.builtin_mod || p.mod in util.builtin_module_parts
|
||||||
|
ctdefine: ctdefine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ mut:
|
||||||
builtin_mod bool // are we in the `builtin` module?
|
builtin_mod bool // are we in the `builtin` module?
|
||||||
mod string // current module name
|
mod string // current module name
|
||||||
attr string
|
attr string
|
||||||
|
attr_ctdefine string
|
||||||
expr_mod string
|
expr_mod string
|
||||||
scope &ast.Scope
|
scope &ast.Scope
|
||||||
global_scope &ast.Scope
|
global_scope &ast.Scope
|
||||||
|
@ -490,8 +491,10 @@ pub fn (mut p Parser) stmt() ast.Stmt {
|
||||||
|
|
||||||
fn (mut p Parser) attribute() ast.Attr {
|
fn (mut p Parser) attribute() ast.Attr {
|
||||||
p.check(.lsbr)
|
p.check(.lsbr)
|
||||||
|
mut is_if_attr := false
|
||||||
if p.tok.kind == .key_if {
|
if p.tok.kind == .key_if {
|
||||||
p.next()
|
p.next()
|
||||||
|
is_if_attr = true
|
||||||
}
|
}
|
||||||
mut name := p.check_name()
|
mut name := p.check_name()
|
||||||
if p.tok.kind == .colon {
|
if p.tok.kind == .colon {
|
||||||
|
@ -505,6 +508,9 @@ fn (mut p Parser) attribute() ast.Attr {
|
||||||
}
|
}
|
||||||
p.check(.rsbr)
|
p.check(.rsbr)
|
||||||
p.attr = name
|
p.attr = name
|
||||||
|
if is_if_attr {
|
||||||
|
p.attr_ctdefine = name
|
||||||
|
}
|
||||||
return ast.Attr{
|
return ast.Attr{
|
||||||
name: name
|
name: name
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ pub:
|
||||||
is_generic bool
|
is_generic bool
|
||||||
is_pub bool
|
is_pub bool
|
||||||
mod string
|
mod string
|
||||||
|
ctdefine string // compile time define. myflag, when [if myflag] tag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Arg {
|
pub struct Arg {
|
||||||
|
|
Loading…
Reference in New Issue