mirror of
https://github.com/vlang/v.git
synced 2025-09-12 17:07:11 -04:00
eval: add comptime-if support (#24919)
This commit is contained in:
parent
54e8ed5ec5
commit
a1b7f5485f
@ -202,15 +202,104 @@ pub fn (mut e Eval) register_symbol_stmts(stmts []ast.Stmt, mod string, file str
|
|||||||
pub fn (mut e Eval) comptime_cond(cond ast.Expr) bool {
|
pub fn (mut e Eval) comptime_cond(cond ast.Expr) bool {
|
||||||
match cond {
|
match cond {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
match cond.name {
|
cname := cond.name
|
||||||
'native' {
|
if cname in ast.valid_comptime_if_os {
|
||||||
return false
|
mut ident_result := false
|
||||||
|
if !e.pref.output_cross_c {
|
||||||
|
if cname_enum_val := pref.os_from_string(cname) {
|
||||||
|
if cname_enum_val == e.pref.os {
|
||||||
|
ident_result = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'windows' {
|
$if trace_comptime_os_checks ? {
|
||||||
return e.pref.os == .windows
|
eprintln('>>> ident_name: ${ident_name} | e.pref.os: ${e.pref.os} | ident_result: ${ident_result}')
|
||||||
}
|
}
|
||||||
else {
|
return ident_result
|
||||||
e.error('unknown compile time if')
|
} else if cname in ast.valid_comptime_if_compilers {
|
||||||
|
return pref.cc_from_string(cname) == e.pref.ccompiler_type
|
||||||
|
} else if cname in ast.valid_comptime_if_platforms {
|
||||||
|
match cname {
|
||||||
|
'amd64' { return e.pref.arch == .amd64 }
|
||||||
|
'i386' { return e.pref.arch == .i386 }
|
||||||
|
'aarch64' { return e.pref.arch == .arm64 }
|
||||||
|
'arm64' { return e.pref.arch == .arm64 }
|
||||||
|
'arm32' { return e.pref.arch == .arm32 }
|
||||||
|
'rv64' { return e.pref.arch == .rv64 }
|
||||||
|
'rv32' { return e.pref.arch == .rv32 }
|
||||||
|
's390x' { return e.pref.arch == .s390x }
|
||||||
|
'ppc64le' { return e.pref.arch == .ppc64le }
|
||||||
|
'loongarch64' { return e.pref.arch == .loongarch64 }
|
||||||
|
else { e.error('unknown comptime platforms \$if ${cname}') }
|
||||||
|
}
|
||||||
|
} else if cname in ast.valid_comptime_if_cpu_features {
|
||||||
|
match cname {
|
||||||
|
'x64' { e.pref.m64 }
|
||||||
|
'x32' { !e.pref.m64 }
|
||||||
|
else { e.error('unknown comptime cpu features \$if ${cname}') }
|
||||||
|
}
|
||||||
|
} else if cname in ast.valid_comptime_if_other {
|
||||||
|
match cname {
|
||||||
|
'apk' {
|
||||||
|
return e.pref.is_apk
|
||||||
|
}
|
||||||
|
'js' {
|
||||||
|
return e.pref.backend.is_js()
|
||||||
|
}
|
||||||
|
'debug' {
|
||||||
|
return e.pref.is_debug
|
||||||
|
}
|
||||||
|
'prod' {
|
||||||
|
return e.pref.is_prod
|
||||||
|
}
|
||||||
|
'profile' {
|
||||||
|
return e.pref.is_prof
|
||||||
|
}
|
||||||
|
'test' {
|
||||||
|
return e.pref.is_test
|
||||||
|
}
|
||||||
|
'musl' {
|
||||||
|
e.error('unknown comptime other \$if ${cname}')
|
||||||
|
}
|
||||||
|
'glibc' {
|
||||||
|
e.error('unknown comptime other \$if ${cname}')
|
||||||
|
}
|
||||||
|
'threads' {
|
||||||
|
return e.table.gostmts > 0
|
||||||
|
}
|
||||||
|
'prealloc' {
|
||||||
|
return e.pref.prealloc
|
||||||
|
}
|
||||||
|
'no_bounds_checking' {
|
||||||
|
return cname in e.pref.compile_defines_all
|
||||||
|
}
|
||||||
|
'autofree' {
|
||||||
|
return e.pref.autofree
|
||||||
|
}
|
||||||
|
'freestanding' {
|
||||||
|
return e.pref.is_bare && !e.pref.output_cross_c
|
||||||
|
}
|
||||||
|
'interpreter' {
|
||||||
|
return e.pref.backend == .interpret
|
||||||
|
}
|
||||||
|
'es5' {
|
||||||
|
return e.pref.output_es5
|
||||||
|
}
|
||||||
|
'wasm32' {
|
||||||
|
return e.pref.os == .wasm32
|
||||||
|
}
|
||||||
|
'wasm32_wasi' {
|
||||||
|
return e.pref.os == .wasm32_wasi
|
||||||
|
}
|
||||||
|
'fast_math' {
|
||||||
|
return e.pref.fast_math
|
||||||
|
}
|
||||||
|
'native' {
|
||||||
|
return e.pref.backend == .native
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('unknown comptime other \$if ${cname}')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
module eval
|
module eval
|
||||||
|
|
||||||
import v.pref
|
|
||||||
import v.ast
|
import v.ast
|
||||||
import v.util
|
import v.util
|
||||||
import math
|
import math
|
||||||
@ -145,36 +144,13 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
|||||||
return Object(res)
|
return Object(res)
|
||||||
}
|
}
|
||||||
ast.IfExpr {
|
ast.IfExpr {
|
||||||
if expr.is_expr {
|
|
||||||
e.error('`if` expressions not supported')
|
|
||||||
}
|
|
||||||
|
|
||||||
if expr.is_comptime {
|
if expr.is_comptime {
|
||||||
for i, branch in expr.branches {
|
for i, branch in expr.branches {
|
||||||
mut do_if := false
|
if e.comptime_cond(branch.cond) || expr.branches.len == i + 1 {
|
||||||
if expr.has_else && i + 1 == expr.branches.len { // else branch
|
e.returning = true
|
||||||
do_if = true
|
e.return_values = []
|
||||||
} else {
|
|
||||||
if branch.cond is ast.Ident {
|
|
||||||
if known_os := pref.os_from_string(branch.cond.name) {
|
|
||||||
do_if = e.pref.os == known_os
|
|
||||||
} else {
|
|
||||||
match branch.cond.name {
|
|
||||||
'prealloc' {
|
|
||||||
do_if = e.pref.prealloc
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e.error('unknown compile time if: ${branch.cond.name}')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if branch.cond is ast.PostfixExpr {
|
|
||||||
do_if = (branch.cond.expr as ast.Ident).name in e.pref.compile_defines
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if do_if {
|
|
||||||
e.stmts(branch.stmts)
|
e.stmts(branch.stmts)
|
||||||
break
|
return e.return_values[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return empty
|
return empty
|
||||||
|
@ -17,7 +17,10 @@ pub fn (mut e Eval) stmts(stmts []ast.Stmt) {
|
|||||||
pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
||||||
match stmt {
|
match stmt {
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
e.expr(stmt.expr, stmt.typ)
|
ret := e.expr(stmt.expr, stmt.typ)
|
||||||
|
if e.returning {
|
||||||
|
e.return_values << ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
// if stmt.left.len != 1 {
|
// if stmt.left.len != 1 {
|
||||||
|
21
vlib/v/eval/tests/comptime_if_test.v
Normal file
21
vlib/v/eval/tests/comptime_if_test.v
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import v.eval
|
||||||
|
|
||||||
|
fn test_comptime_if() {
|
||||||
|
mut e := eval.create()
|
||||||
|
|
||||||
|
ret := e.run('const a =
|
||||||
|
\$if amd64 { "amd" }
|
||||||
|
\$else \$if i386 { "i386" }
|
||||||
|
\$else \$if aarch64 { "aarch64" }
|
||||||
|
\$else \$if arm64 { "arm64" }
|
||||||
|
\$else \$if arm32 { "arm32" }
|
||||||
|
\$else \$if rv64 { "rv64" }
|
||||||
|
\$else \$if rv32 { "rv32" }
|
||||||
|
\$else \$if s390x { "s390x" }
|
||||||
|
\$else \$if ppc64le { "ppc64le" }
|
||||||
|
\$else \$if loongarch64 { "loongarch64" }
|
||||||
|
\$else { "unknown" }')!
|
||||||
|
dump(ret)
|
||||||
|
assert ret[0].string().len != 0
|
||||||
|
assert ret[0].string() != 'unknown'
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user