mirror of
https://github.com/vlang/v.git
synced 2025-09-17 11:26:17 -04:00
cgen,checker: add $if sizeof(T) == int_literal {
support (#24831)
This commit is contained in:
parent
35af6a8d12
commit
3eb04e346c
@ -891,6 +891,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
} else if cond.left is ast.SizeOf {
|
||||
} else {
|
||||
c.error('invalid `\$if` condition: ${cond.left.type_name()}',
|
||||
cond.pos)
|
||||
@ -920,6 +921,8 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, pos token.Pos) ComptimeBr
|
||||
if cond.left is ast.SelectorExpr && cond.right is ast.IntegerLiteral
|
||||
&& c.comptime.is_comptime_selector_field_name(cond.left, 'indirections') {
|
||||
return .unknown
|
||||
} else if cond.left is ast.SizeOf {
|
||||
return .unknown
|
||||
}
|
||||
c.error('invalid `\$if` condition', cond.pos)
|
||||
}
|
||||
|
@ -349,6 +349,61 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
||||
}
|
||||
else {}
|
||||
}
|
||||
} else if left is ast.SizeOf && right is ast.IntegerLiteral {
|
||||
// TODO: support struct.fieldname
|
||||
typ := c.unwrap_generic(left.typ)
|
||||
if typ == 0 {
|
||||
c.error('invalid `\$if` condition: expected a type', branch.cond.left.pos())
|
||||
} else {
|
||||
s, _ := c.table.type_size(c.unwrap_generic(typ))
|
||||
skip_state = match branch.cond.op {
|
||||
.gt {
|
||||
if s > right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
.lt {
|
||||
if s < right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
.ge {
|
||||
if s >= right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
.le {
|
||||
if s <= right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
.ne {
|
||||
if s != right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
.eq {
|
||||
if s == right.val.i64() {
|
||||
ComptimeBranchSkipState.eval
|
||||
} else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
else {
|
||||
ComptimeBranchSkipState.skip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -685,6 +685,23 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) {
|
||||
g.write(' ${cond.op} ')
|
||||
r, d2 := g.comptime_if_cond(cond.right, pkg_exist)
|
||||
return if cond.op == .eq { l == r } else { l != r }, d1 && d1 == d2
|
||||
}
|
||||
if cond.left is ast.SizeOf && cond.left.typ != 0
|
||||
&& cond.right is ast.IntegerLiteral {
|
||||
// TODO: support struct.fieldname
|
||||
s, _ := g.table.type_size(g.unwrap_generic(cond.left.typ))
|
||||
right := cond.right as ast.IntegerLiteral
|
||||
is_true := match cond.op {
|
||||
.eq { s == right.val.i64() }
|
||||
.ne { s != right.val.i64() }
|
||||
else { false }
|
||||
}
|
||||
if is_true {
|
||||
g.write('1')
|
||||
} else {
|
||||
g.write('0')
|
||||
}
|
||||
return is_true, true
|
||||
} else {
|
||||
g.write('1')
|
||||
return true, true
|
||||
@ -748,6 +765,25 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) {
|
||||
g.write('0')
|
||||
}
|
||||
return is_true, true
|
||||
}
|
||||
if cond.left is ast.SizeOf && cond.left.typ != 0
|
||||
&& cond.right is ast.IntegerLiteral {
|
||||
// TODO: support struct.fieldname
|
||||
s, _ := g.table.type_size(g.unwrap_generic(cond.left.typ))
|
||||
right := cond.right as ast.IntegerLiteral
|
||||
is_true := match cond.op {
|
||||
.gt { s > right.val.i64() }
|
||||
.lt { s < right.val.i64() }
|
||||
.ge { s >= right.val.i64() }
|
||||
.le { s <= right.val.i64() }
|
||||
else { false }
|
||||
}
|
||||
if is_true {
|
||||
g.write('1')
|
||||
} else {
|
||||
g.write('0')
|
||||
}
|
||||
return is_true, true
|
||||
} else {
|
||||
return true, false
|
||||
}
|
||||
|
131
vlib/v/tests/comptime/comptime_if_sizeof_test.v
Normal file
131
vlib/v/tests/comptime/comptime_if_sizeof_test.v
Normal file
@ -0,0 +1,131 @@
|
||||
struct MyStruct {
|
||||
a u16
|
||||
b u8
|
||||
c u32
|
||||
d u64
|
||||
}
|
||||
|
||||
fn test_comptime_if_sizeof() {
|
||||
f[u16]()
|
||||
g[MyStruct]()
|
||||
|
||||
x := MyStruct{}
|
||||
// TODO: support struct.fieldname
|
||||
//$if sizeof(x.a) == 2 {
|
||||
// assert true
|
||||
//} $else {
|
||||
// assert false
|
||||
//}
|
||||
//
|
||||
//$if sizeof(x.d) != 2 {
|
||||
// assert false
|
||||
//} $else {
|
||||
// assert true
|
||||
//}
|
||||
}
|
||||
|
||||
fn f[T]() {
|
||||
$if sizeof(T) == 2 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) != 2 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) < 1 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) < 3 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) > 1 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) > 2 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) <= 2 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) <= 1 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) >= 2 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) >= 3 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
}
|
||||
|
||||
fn g[T]() {
|
||||
$if sizeof(T) == 16 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) != 16 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) < 17 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) < 15 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) > 15 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) > 16 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) <= 16 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) <= 15 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
$if sizeof(T) >= 16 {
|
||||
assert true
|
||||
} $else {
|
||||
assert false
|
||||
}
|
||||
$if sizeof(T) >= 17 {
|
||||
assert false
|
||||
} $else {
|
||||
assert true
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user