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