mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: support an unambiguous sizeof[T]() and isreftype[T]() (part 1) (#16684)
This commit is contained in:
parent
e5e73ebbfa
commit
0a11955284
@ -6468,4 +6468,4 @@ Assignment Operators
|
|||||||
+= -= *= /= %=
|
+= -= *= /= %=
|
||||||
&= |= ^=
|
&= |= ^=
|
||||||
>>= <<= >>>=
|
>>= <<= >>>=
|
||||||
```
|
```
|
@ -1591,19 +1591,21 @@ pub mut:
|
|||||||
|
|
||||||
pub struct SizeOf {
|
pub struct SizeOf {
|
||||||
pub:
|
pub:
|
||||||
is_type bool
|
guessed_type bool // a legacy `sizeof( GuessedType )` => a deprecation notice, suggesting `v fmt -w .` => `sizeof[ Type ]()`
|
||||||
pos token.Pos
|
is_type bool
|
||||||
|
pos token.Pos
|
||||||
pub mut:
|
pub mut:
|
||||||
expr Expr // checker uses this to set typ
|
expr Expr // checker uses this to set typ, when !is_type
|
||||||
typ Type
|
typ Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IsRefType {
|
pub struct IsRefType {
|
||||||
pub:
|
pub:
|
||||||
is_type bool
|
guessed_type bool // a legacy `isreftype( GuessedType )` => a deprecation notice, suggesting `v fmt -w .` => `isreftype[ Type ]()`
|
||||||
pos token.Pos
|
is_type bool
|
||||||
|
pos token.Pos
|
||||||
pub mut:
|
pub mut:
|
||||||
expr Expr // checker uses this to set typ
|
expr Expr // checker uses this to set typ, when !is_type
|
||||||
typ Type
|
typ Type
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1629,7 +1631,7 @@ pub:
|
|||||||
is_type bool
|
is_type bool
|
||||||
pos token.Pos
|
pos token.Pos
|
||||||
pub mut:
|
pub mut:
|
||||||
expr Expr // checker uses this to set typ
|
expr Expr // checker uses this to set typ, when !is_type
|
||||||
typ Type
|
typ Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2520,12 +2520,16 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
|||||||
if !node.is_type {
|
if !node.is_type {
|
||||||
node.typ = c.expr(node.expr)
|
node.typ = c.expr(node.expr)
|
||||||
}
|
}
|
||||||
|
// c.deprecate_old_isreftype_and_sizeof_of_a_guessed_type(node.guessed_type,
|
||||||
|
// node.typ, node.pos, 'sizeof')
|
||||||
return ast.u32_type
|
return ast.u32_type
|
||||||
}
|
}
|
||||||
ast.IsRefType {
|
ast.IsRefType {
|
||||||
if !node.is_type {
|
if !node.is_type {
|
||||||
node.typ = c.expr(node.expr)
|
node.typ = c.expr(node.expr)
|
||||||
}
|
}
|
||||||
|
// c.deprecate_old_isreftype_and_sizeof_of_a_guessed_type(node.guessed_type,
|
||||||
|
// node.typ, node.pos, 'isreftype')
|
||||||
return ast.bool_type
|
return ast.bool_type
|
||||||
}
|
}
|
||||||
ast.OffsetOf {
|
ast.OffsetOf {
|
||||||
@ -4395,3 +4399,11 @@ fn semicolonize(main string, details string) string {
|
|||||||
}
|
}
|
||||||
return '${main}; ${details}'
|
return '${main}; ${details}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Checker) deprecate_old_isreftype_and_sizeof_of_a_guessed_type(is_guessed_type bool, typ ast.Type, pos token.Pos, label string) {
|
||||||
|
if is_guessed_type {
|
||||||
|
styp := c.table.type_to_str(typ)
|
||||||
|
c.note('`${label}(${styp})` is deprecated. Use `v fmt -w .` to convert it to `${label}[${styp}]()` instead.',
|
||||||
|
pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
vlib/v/checker/tests/unknown_sizeof_type_err_a.vv:14:34: cgen error: unknown type `T`
|
vlib/v/checker/tests/unknown_sizeof_type_err_a.vv:14:34: cgen error: unknown type `T`
|
||||||
12 | println("size of Abc: ${sizeof(Abc)}")
|
12 | println('size of Abc: ${sizeof[Abc]()}')
|
||||||
13 | println("size of Xyz: ${sizeof(Xyz)}")
|
13 | println('size of Xyz: ${sizeof[Xyz]()}')
|
||||||
14 | println("size of Test: ${sizeof(T)}")
|
14 | println('size of Test: ${sizeof[T]()}')
|
||||||
| ^
|
| ~~
|
||||||
15 | }
|
15 | }
|
||||||
|
@ -9,7 +9,7 @@ struct Xyz {
|
|||||||
type Test = Abc | Xyz
|
type Test = Abc | Xyz
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println("size of Abc: ${sizeof(Abc)}")
|
println('size of Abc: ${sizeof[Abc]()}')
|
||||||
println("size of Xyz: ${sizeof(Xyz)}")
|
println('size of Xyz: ${sizeof[Xyz]()}')
|
||||||
println("size of Test: ${sizeof(T)}")
|
println('size of Test: ${sizeof[T]()}')
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
vlib/v/checker/tests/unknown_sizeof_type_err_b.vv:14:34: cgen error: unknown type `Zabc`
|
vlib/v/checker/tests/unknown_sizeof_type_err_b.vv:14:34: cgen error: unknown type `Zabc`
|
||||||
12 | println("size of Abc: ${sizeof(Abc)}")
|
12 | println('size of Abc: ${sizeof[Abc]()}')
|
||||||
13 | println("size of Xyz: ${sizeof(Xyz)}")
|
13 | println('size of Xyz: ${sizeof[Xyz]()}')
|
||||||
14 | println("size of Test: ${sizeof(Zabc)}")
|
14 | println('size of Test: ${sizeof[Zabc]()}')
|
||||||
| ~~~~
|
| ~~~~~
|
||||||
15 | }
|
15 | }
|
||||||
|
@ -9,7 +9,7 @@ struct Xyz {
|
|||||||
type Test = Abc | Xyz
|
type Test = Abc | Xyz
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println("size of Abc: ${sizeof(Abc)}")
|
println('size of Abc: ${sizeof[Abc]()}')
|
||||||
println("size of Xyz: ${sizeof(Xyz)}")
|
println('size of Xyz: ${sizeof[Xyz]()}')
|
||||||
println("size of Test: ${sizeof(Zabc)}")
|
println('size of Test: ${sizeof[Zabc]()}')
|
||||||
}
|
}
|
||||||
|
@ -2572,23 +2572,43 @@ pub fn (mut f Fmt) selector_expr(node ast.SelectorExpr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) size_of(node ast.SizeOf) {
|
pub fn (mut f Fmt) size_of(node ast.SizeOf) {
|
||||||
f.write('sizeof(')
|
f.write('sizeof')
|
||||||
if node.is_type {
|
if node.is_type {
|
||||||
|
// keep the old form for now
|
||||||
|
f.write('(')
|
||||||
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
||||||
} else {
|
f.write(')')
|
||||||
f.expr(node.expr)
|
return
|
||||||
|
}
|
||||||
|
if node.is_type {
|
||||||
|
f.write('[')
|
||||||
|
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
||||||
|
f.write(']()')
|
||||||
|
} else {
|
||||||
|
f.write('(')
|
||||||
|
f.expr(node.expr)
|
||||||
|
f.write(')')
|
||||||
}
|
}
|
||||||
f.write(')')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) is_ref_type(node ast.IsRefType) {
|
pub fn (mut f Fmt) is_ref_type(node ast.IsRefType) {
|
||||||
f.write('isreftype(')
|
f.write('isreftype')
|
||||||
if node.is_type {
|
if node.is_type {
|
||||||
|
// keep the old form for now
|
||||||
|
f.write('(')
|
||||||
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
||||||
} else {
|
f.write(')')
|
||||||
f.expr(node.expr)
|
return
|
||||||
|
}
|
||||||
|
if node.is_type {
|
||||||
|
f.write('[')
|
||||||
|
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
||||||
|
f.write(']()')
|
||||||
|
} else {
|
||||||
|
f.write('(')
|
||||||
|
f.expr(node.expr)
|
||||||
|
f.write(')')
|
||||||
}
|
}
|
||||||
f.write(')')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) sql_expr(node ast.SqlExpr) {
|
pub fn (mut f Fmt) sql_expr(node ast.SqlExpr) {
|
||||||
|
@ -236,57 +236,85 @@ pub fn (mut p Parser) check_expr(precedence int) !ast.Expr {
|
|||||||
.key_sizeof, .key_isreftype {
|
.key_sizeof, .key_isreftype {
|
||||||
is_reftype := p.tok.kind == .key_isreftype
|
is_reftype := p.tok.kind == .key_isreftype
|
||||||
p.next() // sizeof
|
p.next() // sizeof
|
||||||
p.check(.lpar)
|
|
||||||
pos := p.tok.pos()
|
|
||||||
mut is_known_var := p.mark_var_as_used(p.tok.lit)
|
|
||||||
|| p.table.global_scope.known_const(p.mod + '.' + p.tok.lit)
|
|
||||||
//|| p.table.known_fn(p.mod + '.' + p.tok.lit)
|
|
||||||
// assume `mod.` prefix leads to a type
|
|
||||||
mut is_type := p.known_import(p.tok.lit) || p.tok.kind.is_start_of_type()
|
|
||||||
|| (p.tok.lit.len > 0 && p.tok.lit[0].is_capital())
|
|
||||||
|
|
||||||
if p.tok.lit in ['c', 'r'] && p.peek_tok.kind == .string {
|
if p.tok.kind == .lsbr {
|
||||||
is_known_var = false
|
// parse sizeof[T]() and isreftype[T]() without guessing:
|
||||||
is_type = false
|
p.check(.lsbr)
|
||||||
}
|
mut type_pos := p.tok.pos()
|
||||||
if is_known_var || !is_type {
|
typ := p.parse_type()
|
||||||
expr := p.expr(0)
|
type_pos = type_pos.extend(p.tok.pos())
|
||||||
|
p.check(.rsbr)
|
||||||
|
p.check(.lpar)
|
||||||
|
p.check(.rpar)
|
||||||
if is_reftype {
|
if is_reftype {
|
||||||
node = ast.IsRefType{
|
node = ast.IsRefType{
|
||||||
is_type: false
|
is_type: true
|
||||||
expr: expr
|
typ: typ
|
||||||
pos: pos
|
pos: type_pos
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node = ast.SizeOf{
|
node = ast.SizeOf{
|
||||||
is_type: false
|
is_type: true
|
||||||
expr: expr
|
typ: typ
|
||||||
pos: pos
|
pos: type_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if p.tok.kind == .name {
|
p.check(.lpar)
|
||||||
p.register_used_import(p.tok.lit)
|
pos := p.tok.pos()
|
||||||
|
mut is_known_var := p.mark_var_as_used(p.tok.lit)
|
||||||
|
|| p.table.global_scope.known_const(p.mod + '.' + p.tok.lit)
|
||||||
|
//|| p.table.known_fn(p.mod + '.' + p.tok.lit)
|
||||||
|
// assume `mod.` prefix leads to a type
|
||||||
|
mut is_type := p.known_import(p.tok.lit)
|
||||||
|
|| p.tok.kind.is_start_of_type()
|
||||||
|
|| (p.tok.lit.len > 0 && p.tok.lit[0].is_capital())
|
||||||
|
|
||||||
|
if p.tok.lit in ['c', 'r'] && p.peek_tok.kind == .string {
|
||||||
|
is_known_var = false
|
||||||
|
is_type = false
|
||||||
}
|
}
|
||||||
save_expr_mod := p.expr_mod
|
if is_known_var || !is_type {
|
||||||
p.expr_mod = ''
|
expr := p.expr(0)
|
||||||
arg_type := p.parse_type()
|
if is_reftype {
|
||||||
p.expr_mod = save_expr_mod
|
node = ast.IsRefType{
|
||||||
if is_reftype {
|
is_type: false
|
||||||
node = ast.IsRefType{
|
expr: expr
|
||||||
is_type: true
|
pos: pos
|
||||||
typ: arg_type
|
}
|
||||||
pos: pos
|
} else {
|
||||||
|
node = ast.SizeOf{
|
||||||
|
is_type: false
|
||||||
|
expr: expr
|
||||||
|
pos: pos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node = ast.SizeOf{
|
if p.tok.kind == .name {
|
||||||
is_type: true
|
p.register_used_import(p.tok.lit)
|
||||||
typ: arg_type
|
}
|
||||||
pos: pos
|
save_expr_mod := p.expr_mod
|
||||||
|
p.expr_mod = ''
|
||||||
|
arg_type := p.parse_type()
|
||||||
|
p.expr_mod = save_expr_mod
|
||||||
|
if is_reftype {
|
||||||
|
node = ast.IsRefType{
|
||||||
|
guessed_type: true
|
||||||
|
is_type: true
|
||||||
|
typ: arg_type
|
||||||
|
pos: pos
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node = ast.SizeOf{
|
||||||
|
guessed_type: true
|
||||||
|
is_type: true
|
||||||
|
typ: arg_type
|
||||||
|
pos: pos
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p.check(.rpar)
|
||||||
}
|
}
|
||||||
p.check(.rpar)
|
|
||||||
}
|
}
|
||||||
.key_dump {
|
.key_dump {
|
||||||
spos := p.tok.pos()
|
spos := p.tok.pos()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user