mirror of
https://github.com/vlang/v.git
synced 2025-09-19 04:17:46 -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
|
ComptimeBranchSkipState.skip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if cond.left is ast.SizeOf {
|
||||||
} else {
|
} else {
|
||||||
c.error('invalid `\$if` condition: ${cond.left.type_name()}',
|
c.error('invalid `\$if` condition: ${cond.left.type_name()}',
|
||||||
cond.pos)
|
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
|
if cond.left is ast.SelectorExpr && cond.right is ast.IntegerLiteral
|
||||||
&& c.comptime.is_comptime_selector_field_name(cond.left, 'indirections') {
|
&& c.comptime.is_comptime_selector_field_name(cond.left, 'indirections') {
|
||||||
return .unknown
|
return .unknown
|
||||||
|
} else if cond.left is ast.SizeOf {
|
||||||
|
return .unknown
|
||||||
}
|
}
|
||||||
c.error('invalid `\$if` condition', cond.pos)
|
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 {}
|
||||||
}
|
}
|
||||||
|
} 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} ')
|
g.write(' ${cond.op} ')
|
||||||
r, d2 := g.comptime_if_cond(cond.right, pkg_exist)
|
r, d2 := g.comptime_if_cond(cond.right, pkg_exist)
|
||||||
return if cond.op == .eq { l == r } else { l != r }, d1 && d1 == d2
|
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 {
|
} else {
|
||||||
g.write('1')
|
g.write('1')
|
||||||
return true, true
|
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')
|
g.write('0')
|
||||||
}
|
}
|
||||||
return is_true, true
|
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 {
|
} else {
|
||||||
return true, false
|
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