Skip to content

Commit ee53a99

Browse files
authored
v: add typeof(var).indirections and T.indirections (#22805)
1 parent 6ffc9c9 commit ee53a99

File tree

8 files changed

+48
-5
lines changed

8 files changed

+48
-5
lines changed

vlib/v/ast/ast.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ pub enum GenericKindField {
287287
name
288288
typ
289289
unaliased_typ
290+
indirections
290291
}
291292

292293
// `foo.bar`

vlib/v/checker/checker.v

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,17 +1531,16 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
15311531
.name {
15321532
return ast.string_type
15331533
}
1534-
.unaliased_typ {
1535-
return ast.int_type
1536-
}
1537-
.typ {
1534+
.unaliased_typ, .typ, .indirections {
15381535
return ast.int_type
15391536
}
15401537
else {
15411538
if node.field_name == 'name' {
15421539
return ast.string_type
15431540
} else if node.field_name == 'idx' {
15441541
return ast.int_type
1542+
} else if node.field_name == 'indirections' {
1543+
return ast.int_type
15451544
}
15461545
c.error('invalid field `.${node.field_name}` for type `${node.expr}`',
15471546
node.pos)

vlib/v/checker/if.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,12 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
268268
}
269269
}
270270
}
271+
} else if left.expr is ast.TypeOf {
272+
skip_state = if left.expr.typ.nr_muls() == right.val.i64() {
273+
ComptimeBranchSkipState.eval
274+
} else {
275+
ComptimeBranchSkipState.skip
276+
}
271277
}
272278
} else if branch.cond.op in [.eq, .ne] && left is ast.SelectorExpr
273279
&& right is ast.StringLiteral {

vlib/v/gen/c/cgen.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3875,6 +3875,10 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
38753875
g.write(int(g.table.unaliased_type(g.unwrap_generic(node.name_type))).str())
38763876
return
38773877
}
3878+
.indirections {
3879+
g.write(int(g.unwrap_generic(node.name_type).nr_muls()).str())
3880+
return
3881+
}
38783882
.unknown {
38793883
// ast.TypeOf of `typeof(string).idx` etc
38803884
if node.field_name == 'name' {
@@ -3893,6 +3897,14 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
38933897
// `typeof(expr).idx`
38943898
g.write(int(g.unwrap_generic(name_type)).str())
38953899
return
3900+
} else if node.field_name == 'indirections' {
3901+
mut name_type := node.name_type
3902+
if node.expr is ast.TypeOf {
3903+
name_type = g.resolve_comptime_type(node.expr.expr, name_type)
3904+
}
3905+
// `typeof(expr).indirections`
3906+
g.write(int(g.unwrap_generic(name_type).nr_muls()).str())
3907+
return
38963908
}
38973909
g.error('unknown generic field', node.pos)
38983910
}

vlib/v/gen/c/comptime.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ fn (mut g Gen) get_expr_type(cond ast.Expr) ast.Type {
469469
return g.unwrap_generic(cond.name_type)
470470
} else if cond.gkind_field == .unaliased_typ {
471471
return g.table.unaliased_type(g.unwrap_generic(cond.name_type))
472+
} else if cond.gkind_field == .indirections {
473+
return ast.int_type
472474
} else {
473475
name := '${cond.expr}.${cond.field_name}'
474476
if name in g.comptime.type_map {

vlib/v/gen/js/js.v

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3252,13 +3252,17 @@ fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
32523252
g.write('new int(')
32533253
g.write('${int(g.unwrap_generic(it.name_type))}')
32543254
g.write(')')
3255-
g.write(')')
32563255
return
32573256
}
32583257
.unaliased_typ {
32593258
g.write('new int(')
32603259
g.write('${int(g.table.unaliased_type(g.unwrap_generic(it.name_type)))}')
32613260
g.write(')')
3261+
return
3262+
}
3263+
.indirections {
3264+
g.write('new int(')
3265+
g.write('${int(g.unwrap_generic(it.name_type).nr_muls())}')
32623266
g.write(')')
32633267
return
32643268
}

vlib/v/parser/parser.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2923,6 +2923,7 @@ fn (mut p Parser) name_expr() ast.Expr {
29232923
'name' { ast.GenericKindField.name }
29242924
'typ' { ast.GenericKindField.typ }
29252925
'unaliased_typ' { ast.GenericKindField.unaliased_typ }
2926+
'indirections' { ast.GenericKindField.indirections }
29262927
else { ast.GenericKindField.unknown }
29272928
}
29282929
pos.extend(p.tok.pos())
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn indirections[T](val T) int {
2+
return T.indirections
3+
}
4+
5+
fn test_main() {
6+
a := 0
7+
assert typeof(a).indirections == 0
8+
assert indirections(a) == 0
9+
b := &a
10+
assert typeof(b).indirections == 1
11+
assert indirections(b) == 1
12+
c := [1]
13+
assert typeof(c).indirections == 0
14+
assert indirections(c) == 0
15+
d := &c
16+
assert typeof(d).indirections == 1
17+
assert indirections(d) == 1
18+
}

0 commit comments

Comments
 (0)