mirror of
https://github.com/vlang/v.git
synced 2025-09-12 00:46:55 -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 {
|
||||
match cond {
|
||||
ast.Ident {
|
||||
match cond.name {
|
||||
'native' {
|
||||
return false
|
||||
cname := cond.name
|
||||
if cname in ast.valid_comptime_if_os {
|
||||
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' {
|
||||
return e.pref.os == .windows
|
||||
$if trace_comptime_os_checks ? {
|
||||
eprintln('>>> ident_name: ${ident_name} | e.pref.os: ${e.pref.os} | ident_result: ${ident_result}')
|
||||
}
|
||||
else {
|
||||
e.error('unknown compile time if')
|
||||
return ident_result
|
||||
} 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
|
||||
|
||||
import v.pref
|
||||
import v.ast
|
||||
import v.util
|
||||
import math
|
||||
@ -145,36 +144,13 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
||||
return Object(res)
|
||||
}
|
||||
ast.IfExpr {
|
||||
if expr.is_expr {
|
||||
e.error('`if` expressions not supported')
|
||||
}
|
||||
|
||||
if expr.is_comptime {
|
||||
for i, branch in expr.branches {
|
||||
mut do_if := false
|
||||
if expr.has_else && i + 1 == expr.branches.len { // else branch
|
||||
do_if = true
|
||||
} 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 {
|
||||
if e.comptime_cond(branch.cond) || expr.branches.len == i + 1 {
|
||||
e.returning = true
|
||||
e.return_values = []
|
||||
e.stmts(branch.stmts)
|
||||
break
|
||||
return e.return_values[0]
|
||||
}
|
||||
}
|
||||
return empty
|
||||
|
@ -17,7 +17,10 @@ pub fn (mut e Eval) stmts(stmts []ast.Stmt) {
|
||||
pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
||||
match stmt {
|
||||
ast.ExprStmt {
|
||||
e.expr(stmt.expr, stmt.typ)
|
||||
ret := e.expr(stmt.expr, stmt.typ)
|
||||
if e.returning {
|
||||
e.return_values << ret
|
||||
}
|
||||
}
|
||||
ast.AssignStmt {
|
||||
// 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