1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast: minor optimization of clear_flags() (#17938)

This commit is contained in:
yuyi 2023-04-13 13:27:26 +08:00 committed by GitHub
parent 87ca877c83
commit 92cb7468ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 54 additions and 40 deletions

View File

@ -354,10 +354,18 @@ pub fn (t Type) clear_flag(flag TypeFlag) Type {
return int(t) & ~(1 << (int(flag) + 24)) return int(t) & ~(1 << (int(flag) + 24))
} }
// clear all flags // clear all flags or multi flags
[inline] [inline]
pub fn (t Type) clear_flags() Type { pub fn (t Type) clear_flags(flags ...TypeFlag) Type {
return int(t) & 0xffffff if flags.len == 0 {
return int(t) & 0xffffff
} else {
mut typ := int(t)
for flag in flags {
typ = typ & ~(1 << (int(flag) + 24))
}
return typ
}
} }
// return true if `flag` is set on `t` // return true if `flag` is set on `t`

View File

@ -154,7 +154,7 @@ fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
&& expected.has_flag(.result)) { && expected.has_flag(.result)) {
// IError // IError
return true return true
} else if !c.check_basic(got, expected.clear_flag(.option).clear_flag(.result)) { } else if !c.check_basic(got, expected.clear_flags(.option, .result)) {
return false return false
} }
} }

View File

@ -1116,7 +1116,7 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return
return return
} }
last_stmt := node.stmts.last() last_stmt := node.stmts.last()
c.check_or_last_stmt(last_stmt, ret_type, expr_return_type.clear_flag(.option).clear_flag(.result)) c.check_or_last_stmt(last_stmt, ret_type, expr_return_type.clear_flags(.option, .result))
} }
fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_return_type ast.Type) { fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_return_type ast.Type) {
@ -1124,13 +1124,14 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
match stmt { match stmt {
ast.ExprStmt { ast.ExprStmt {
c.expected_type = ret_type c.expected_type = ret_type
c.expected_or_type = ret_type.clear_flag(.option).clear_flag(.result) c.expected_or_type = ret_type.clear_flags(.option, .result)
last_stmt_typ := c.expr(stmt.expr) last_stmt_typ := c.expr(stmt.expr)
if ret_type.has_flag(.option) if ret_type.has_flag(.option)
&& (last_stmt_typ.has_flag(.option) || last_stmt_typ == ast.none_type) { && (last_stmt_typ.has_flag(.option) || last_stmt_typ == ast.none_type) {
if stmt.expr in [ast.Ident, ast.SelectorExpr, ast.CallExpr, ast.None] { if stmt.expr in [ast.Ident, ast.SelectorExpr, ast.CallExpr, ast.None] {
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result)) expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
got_type_name := c.table.type_to_str(last_stmt_typ) got_type_name := c.table.type_to_str(last_stmt_typ)
c.error('`or` block must provide a value of type `${expected_type_name}`, not `${got_type_name}`', c.error('`or` block must provide a value of type `${expected_type_name}`, not `${got_type_name}`',
stmt.expr.pos()) stmt.expr.pos())
@ -1161,7 +1162,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
} }
return return
} }
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result)) expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('`or` block must provide a default value of type `${expected_type_name}`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)', c.error('`or` block must provide a default value of type `${expected_type_name}`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)',
stmt.expr.pos()) stmt.expr.pos())
} else { } else {
@ -1173,7 +1175,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
return return
} }
type_name := c.table.type_to_str(last_stmt_typ) type_name := c.table.type_to_str(last_stmt_typ)
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result)) expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('wrong return type `${type_name}` in the `or {}` block, expected `${expected_type_name}`', c.error('wrong return type `${type_name}` in the `or {}` block, expected `${expected_type_name}`',
stmt.expr.pos()) stmt.expr.pos())
} }
@ -1187,7 +1190,8 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
} }
ast.Return {} ast.Return {}
else { else {
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result)) expected_type_name := c.table.type_to_str(ret_type.clear_flags(.option,
.result))
c.error('last statement in the `or {}` block should be an expression of type `${expected_type_name}` or exit parent scope', c.error('last statement in the `or {}` block should be an expression of type `${expected_type_name}` or exit parent scope',
stmt.pos) stmt.pos)
} }
@ -1434,7 +1438,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
} }
node.typ = field.typ node.typ = field.typ
if node.or_block.kind == .block { if node.or_block.kind == .block {
c.expected_or_type = node.typ.clear_flag(.option).clear_flag(.result) c.expected_or_type = node.typ.clear_flags(.option, .result)
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(node.or_block.stmts)
c.expected_or_type = ast.void_type c.expected_or_type = ast.void_type
} }
@ -3179,7 +3183,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
c.error('cannot use `or {}` block on non-option variable', node.pos) c.error('cannot use `or {}` block on non-option variable', node.pos)
} }
} }
unwrapped_typ := info.typ.clear_flag(.option).clear_flag(.result) unwrapped_typ := info.typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts) c.stmts_ending_with_expression(node.or_expr.stmts)
c.check_or_expr(node.or_expr, info.typ, c.expected_or_type, node) c.check_or_expr(node.or_expr, info.typ, c.expected_or_type, node)
@ -3245,7 +3249,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
} }
} }
} else { } else {
typ = obj.expr.expr_type.clear_flag(.option).clear_flag(.result) typ = obj.expr.expr_type.clear_flags(.option, .result)
} }
} else if obj.expr is ast.EmptyExpr { } else if obj.expr is ast.EmptyExpr {
c.error('invalid variable `${node.name}`', node.pos) c.error('invalid variable `${node.name}`', node.pos)
@ -3278,7 +3282,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
node.pos) node.pos)
} }
} }
unwrapped_typ := typ.clear_flag(.option).clear_flag(.result) unwrapped_typ := typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts) c.stmts_ending_with_expression(node.or_expr.stmts)
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node) c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
@ -3323,7 +3327,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
if mut obj.expr is ast.CallExpr { if mut obj.expr is ast.CallExpr {
if obj.expr.or_block.kind != .absent { if obj.expr.or_block.kind != .absent {
typ = typ.clear_flag(.option).clear_flag(.result) typ = typ.clear_flags(.option, .result)
} }
} }
} }

View File

@ -235,7 +235,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
unwrapped_expr_type := c.unwrap_generic(field.typ) unwrapped_expr_type := c.unwrap_generic(field.typ)
tsym := c.table.sym(unwrapped_expr_type) tsym := c.table.sym(unwrapped_expr_type)
c.table.dumps[int(unwrapped_expr_type.clear_flag(.option).clear_flag(.result).clear_flag(.atomic_f))] = tsym.cname c.table.dumps[int(unwrapped_expr_type.clear_flags(.option, .result, .atomic_f))] = tsym.cname
} }
c.comptime_for_field_var = '' c.comptime_for_field_var = ''
c.inside_comptime_for_field = false c.inside_comptime_for_field = false

View File

@ -138,7 +138,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
c.expected_type.clear_flag(.shared_f).deref() c.expected_type.clear_flag(.shared_f).deref()
} else { } else {
c.expected_type c.expected_type
}.clear_flag(.option).clear_flag(.result) }.clear_flags(.option, .result)
} }
// [1,2,3] // [1,2,3]
if node.exprs.len > 0 && node.elem_type == ast.void_type { if node.exprs.len > 0 && node.elem_type == ast.void_type {
@ -299,7 +299,7 @@ fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
sym := c.table.sym(c.expected_type) sym := c.table.sym(c.expected_type)
if sym.kind == .map { if sym.kind == .map {
info := sym.map_info() info := sym.map_info()
node.typ = c.expected_type.clear_flag(.option).clear_flag(.result) node.typ = c.expected_type.clear_flags(.option, .result)
node.key_type = info.key_type node.key_type = info.key_type
node.value_type = info.value_type node.value_type = info.value_type
return node.typ return node.typ

View File

@ -2285,7 +2285,7 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
} else if !is_map && arg_expr.return_type != ast.bool_type { } else if !is_map && arg_expr.return_type != ast.bool_type {
if arg_expr.or_block.kind != .absent && (arg_expr.return_type.has_flag(.option) if arg_expr.or_block.kind != .absent && (arg_expr.return_type.has_flag(.option)
|| arg_expr.return_type.has_flag(.result)) || arg_expr.return_type.has_flag(.result))
&& arg_expr.return_type.clear_flag(.option).clear_flag(.result) == ast.bool_type { && arg_expr.return_type.clear_flags(.option, .result) == ast.bool_type {
return return
} }
c.error('type mismatch, `${arg_expr.name}` must return a bool', arg_expr.pos) c.error('type mismatch, `${arg_expr.name}` must return a bool', arg_expr.pos)

View File

@ -135,7 +135,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
if next_fn.params.len != 1 { if next_fn.params.len != 1 {
c.error('iterator method `next()` must have 0 parameters', node.cond.pos()) c.error('iterator method `next()` must have 0 parameters', node.cond.pos())
} }
mut val_type := next_fn.return_type.clear_flag(.option).clear_flag(.result) mut val_type := next_fn.return_type.clear_flags(.option, .result)
if node.val_is_mut { if node.val_is_mut {
val_type = val_type.ref() val_type = val_type.ref()
} }

View File

@ -71,7 +71,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
} }
} }
if mut branch.cond is ast.IfGuardExpr { if mut branch.cond is ast.IfGuardExpr {
if branch.cond.expr_type.clear_flag(.option).clear_flag(.result) == ast.void_type if branch.cond.expr_type.clear_flags(.option, .result) == ast.void_type
&& !(branch.cond.vars.len == 1 && branch.cond.vars[0].name == '_') { && !(branch.cond.vars.len == 1 && branch.cond.vars[0].name == '_') {
c.error('if guard expects non-propagate option or result', branch.pos) c.error('if guard expects non-propagate option or result', branch.pos)
continue continue

View File

@ -705,7 +705,7 @@ fn (mut g Gen) gen_multi_return_assign(node &ast.AssignStmt, return_type ast.Typ
mut mr_styp := g.typ(return_type.clear_flag(.result)) mut mr_styp := g.typ(return_type.clear_flag(.result))
if node.right[0] is ast.CallExpr && (node.right[0] as ast.CallExpr).or_block.kind != .absent { if node.right[0] is ast.CallExpr && (node.right[0] as ast.CallExpr).or_block.kind != .absent {
is_option = false is_option = false
mr_styp = g.typ(return_type.clear_flag(.option).clear_flag(.result)) mr_styp = g.typ(return_type.clear_flags(.option, .result))
} }
g.write('${mr_styp} ${mr_var_name} = ') g.write('${mr_styp} ${mr_var_name} = ')
g.expr(node.right[0]) g.expr(node.right[0])

View File

@ -1388,7 +1388,7 @@ pub fn (mut g Gen) write_typedef_types() {
g.type_definitions.writeln(def_str) g.type_definitions.writeln(def_str)
} else { } else {
g.type_definitions.writeln('typedef ${fixed} ${styp} [${len}];') g.type_definitions.writeln('typedef ${fixed} ${styp} [${len}];')
base := g.typ(info.elem_type.clear_flag(.option).clear_flag(.result)) base := g.typ(info.elem_type.clear_flags(.option, .result))
if info.elem_type.has_flag(.option) && base !in g.options_forward { if info.elem_type.has_flag(.option) && base !in g.options_forward {
g.options_forward << base g.options_forward << base
} else if info.elem_type.has_flag(.result) && base !in g.results_forward { } else if info.elem_type.has_flag(.result) && base !in g.results_forward {
@ -3031,7 +3031,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
ret_type := if node.or_block.kind == .absent { ret_type := if node.or_block.kind == .absent {
node.return_type node.return_type
} else { } else {
node.return_type.clear_flag(.option).clear_flag(.result) node.return_type.clear_flags(.option, .result)
} }
mut shared_styp := '' mut shared_styp := ''
if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block { if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block {
@ -3457,7 +3457,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
g.or_block(tmp_var, node.or_block, node.typ) g.or_block(tmp_var, node.or_block, node.typ)
g.write(stmt_str) g.write(stmt_str)
g.write(' ') g.write(' ')
unwrapped_typ := node.typ.clear_flag(.option).clear_flag(.result) unwrapped_typ := node.typ.clear_flags(.option, .result)
unwrapped_styp := g.typ(unwrapped_typ) unwrapped_styp := g.typ(unwrapped_typ)
g.write('(*(${unwrapped_styp}*)${tmp_var}.data)') g.write('(*(${unwrapped_styp}*)${tmp_var}.data)')
return return
@ -3817,7 +3817,7 @@ fn (mut g Gen) unlock_locks() {
fn (mut g Gen) map_init(node ast.MapInit) { fn (mut g Gen) map_init(node ast.MapInit) {
unwrap_key_typ := g.unwrap_generic(node.key_type) unwrap_key_typ := g.unwrap_generic(node.key_type)
unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flag(.option).clear_flag(.result) unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flags(.option, .result)
key_typ_str := g.typ(unwrap_key_typ) key_typ_str := g.typ(unwrap_key_typ)
value_typ_str := g.typ(unwrap_val_typ) value_typ_str := g.typ(unwrap_val_typ)
value_sym := g.table.sym(unwrap_val_typ) value_sym := g.table.sym(unwrap_val_typ)
@ -4288,11 +4288,11 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
} }
fn (mut g Gen) concat_expr(node ast.ConcatExpr) { fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
mut styp := g.typ(node.return_type.clear_flag(.option).clear_flag(.result)) mut styp := g.typ(node.return_type.clear_flags(.option, .result))
if g.inside_return { if g.inside_return {
styp = g.typ(g.fn_decl.return_type.clear_flag(.option).clear_flag(.result)) styp = g.typ(g.fn_decl.return_type.clear_flags(.option, .result))
} else if g.inside_or_block { } else if g.inside_or_block {
styp = g.typ(g.or_expr_return_type.clear_flag(.option).clear_flag(.result)) styp = g.typ(g.or_expr_return_type.clear_flags(.option, .result))
} }
sym := g.table.sym(node.return_type) sym := g.table.sym(node.return_type)
is_multi := sym.kind == .multi_return is_multi := sym.kind == .multi_return
@ -4761,7 +4761,8 @@ fn (mut g Gen) return_stmt(node ast.Return) {
} }
} }
for i, expr in node.exprs { for i, expr in node.exprs {
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flag(.option).clear_flag(.result)) g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flags(.option,
.result))
if i < node.exprs.len - 1 { if i < node.exprs.len - 1 {
g.write(', ') g.write(', ')
} }
@ -5830,7 +5831,8 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
} }
old_inside_opt_data := g.inside_opt_data old_inside_opt_data := g.inside_opt_data
g.inside_opt_data = true g.inside_opt_data = true
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_flag(.option).clear_flag(.result)) g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_flags(.option,
.result))
g.inside_opt_data = old_inside_opt_data g.inside_opt_data = old_inside_opt_data
g.writeln(';') g.writeln(';')
g.stmt_path_pos.delete_last() g.stmt_path_pos.delete_last()
@ -5866,7 +5868,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
} }
} }
if or_block.kind == .block { if or_block.kind == .block {
g.or_expr_return_type = return_type.clear_flag(.option).clear_flag(.result) g.or_expr_return_type = return_type.clear_flags(.option, .result)
if g.inside_or_block { if g.inside_or_block {
g.writeln('\terr = ${cvar_name}.err;') g.writeln('\terr = ${cvar_name}.err;')
} else { } else {

View File

@ -20,8 +20,8 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
if node.expr is ast.Ident { if node.expr is ast.Ident {
// var // var
if node.expr.info is ast.IdentVar && node.expr.language == .v { if node.expr.info is ast.IdentVar && node.expr.language == .v {
name = g.typ(g.unwrap_generic(node.expr.info.typ.clear_flag(.shared_f).clear_flag(.result))).replace('*', name = g.typ(g.unwrap_generic(node.expr.info.typ.clear_flags(.shared_f,
'') .result))).replace('*', '')
} }
} }
} }
@ -32,14 +32,14 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
if node.expr.field_expr.expr.name == g.comptime_for_field_var if node.expr.field_expr.expr.name == g.comptime_for_field_var
&& node.expr.field_expr.field_name == 'name' { && node.expr.field_expr.field_name == 'name' {
field, _ := g.get_comptime_selector_var_type(node.expr) field, _ := g.get_comptime_selector_var_type(node.expr)
name = g.typ(g.unwrap_generic(field.typ.clear_flag(.shared_f).clear_flag(.result))) name = g.typ(g.unwrap_generic(field.typ.clear_flags(.shared_f, .result)))
expr_type = field.typ expr_type = field.typ
} }
} }
} }
} else if node.expr is ast.Ident && g.inside_comptime_for_field && g.is_comptime_var(node.expr) { } else if node.expr is ast.Ident && g.inside_comptime_for_field && g.is_comptime_var(node.expr) {
expr_type = g.get_comptime_var_type(node.expr) expr_type = g.get_comptime_var_type(node.expr)
name = g.typ(g.unwrap_generic(expr_type.clear_flag(.shared_f).clear_flag(.result))).replace('*', name = g.typ(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*',
'') '')
} }
@ -83,7 +83,7 @@ fn (mut g Gen) dump_expr_definitions() {
typ := ast.Type(dump_type) typ := ast.Type(dump_type)
is_ptr := typ.is_ptr() is_ptr := typ.is_ptr()
deref, _ := deref_kind(str_method_expects_ptr, is_ptr, dump_type) deref, _ := deref_kind(str_method_expects_ptr, is_ptr, dump_type)
to_string_fn_name := g.get_str_fn(typ.clear_flag(.shared_f).clear_flag(.result)) to_string_fn_name := g.get_str_fn(typ.clear_flags(.shared_f, .result))
ptr_asterisk := if is_ptr { '*'.repeat(typ.nr_muls()) } else { '' } ptr_asterisk := if is_ptr { '*'.repeat(typ.nr_muls()) } else { '' }
mut str_dumparg_type := '' mut str_dumparg_type := ''
if dump_sym.kind == .none_ { if dump_sym.kind == .none_ {

View File

@ -779,11 +779,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
} }
if gen_or { if gen_or {
g.or_block(tmp_opt, node.or_block, node.return_type) g.or_block(tmp_opt, node.or_block, node.return_type)
mut unwrapped_typ := node.return_type.clear_flag(.option).clear_flag(.result) mut unwrapped_typ := node.return_type.clear_flags(.option, .result)
if g.table.sym(unwrapped_typ).kind == .alias { if g.table.sym(unwrapped_typ).kind == .alias {
unaliased_type := g.table.unaliased_type(unwrapped_typ) unaliased_type := g.table.unaliased_type(unwrapped_typ)
if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) {
unwrapped_typ = unaliased_type.clear_flag(.option).clear_flag(.result) unwrapped_typ = unaliased_type.clear_flags(.option, .result)
} }
} }
unwrapped_styp := g.typ(unwrapped_typ) unwrapped_styp := g.typ(unwrapped_typ)

View File

@ -397,7 +397,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
if g.inside_return { if g.inside_return {
g.typ(elem_type) g.typ(elem_type)
} else { } else {
g.typ(elem_type.clear_flag(.option).clear_flag(.result)) g.typ(elem_type.clear_flags(.option, .result))
} }
} }
get_and_set_types := elem_sym.kind in [.struct_, .map, .array] get_and_set_types := elem_sym.kind in [.struct_, .map, .array]