diff --git a/vlib/v/ast/comptime_valid_idents.v b/vlib/v/ast/comptime_valid_idents.v index 3d9e00d126..2a242adb53 100644 --- a/vlib/v/ast/comptime_valid_idents.v +++ b/vlib/v/ast/comptime_valid_idents.v @@ -1,5 +1,7 @@ module ast +import v.pref + pub const valid_comptime_if_os = ['windows', 'ios', 'macos', 'mach', 'darwin', 'hpux', 'gnu', 'qnx', 'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'termux', 'solaris', 'haiku', 'serenity', 'vinix', 'plan9', 'wasm32_emscripten'] @@ -22,3 +24,225 @@ fn all_valid_comptime_idents() []string { res << valid_comptime_if_other return res } + +pub fn eval_comptime_not_user_defined_ident(ident string, the_pref &pref.Preferences) !bool { + mut is_true := false + if ident in valid_comptime_if_os { + if ident_enum_val := pref.os_from_string(ident) { + if ident_enum_val == the_pref.os { + is_true = true + } + } + } else if ident in valid_comptime_if_compilers { + is_true = pref.cc_from_string(ident) == the_pref.ccompiler_type + } else if ident in valid_comptime_if_platforms { + match ident { + 'amd64' { + is_true = the_pref.arch == .amd64 + } + 'i386' { + is_true = the_pref.arch == .i386 + } + 'aarch64' { + is_true = the_pref.arch == .arm64 + } + 'arm64' { + is_true = the_pref.arch == .arm64 + } + 'arm32' { + is_true = the_pref.arch == .arm32 + } + 'rv64' { + is_true = the_pref.arch == .rv64 + } + 'rv32' { + is_true = the_pref.arch == .rv32 + } + 's390x' { + is_true = the_pref.arch == .s390x + } + 'ppc64le' { + is_true = the_pref.arch == .ppc64le + } + 'loongarch64' { + is_true = the_pref.arch == .loongarch64 + } + else { + return error('invalid \$if condition: unknown platforms `${ident}`') + } + } + } else if ident in valid_comptime_if_cpu_features { + match ident { + 'x64' { + is_true = the_pref.m64 + } + 'x32' { + is_true = !the_pref.m64 + } + 'little_endian' { + is_true = $if little_endian { true } $else { false } + } + 'big_endian' { + is_true = $if big_endian { true } $else { false } + } + else { + return error('invalid \$if condition: unknown cpu_features `${ident}`') + } + } + } else if ident in valid_comptime_if_other { + match ident { + 'apk' { + is_true = the_pref.is_apk + } + 'js' { + is_true = the_pref.backend.is_js() + } + 'debug' { + is_true = the_pref.is_debug + } + 'prod' { + is_true = the_pref.is_prod + } + 'test' { + is_true = the_pref.is_test + } + 'glibc' { + is_true = the_pref.is_glibc + } + 'prealloc' { + is_true = the_pref.prealloc + } + 'no_bounds_checking' { + is_true = the_pref.no_bounds_checking + } + 'freestanding' { + is_true = the_pref.is_bare && !the_pref.output_cross_c + } + 'threads' { + return error('threads should handle outside of `check_valid_ident()`') + } + 'js_node' { + is_true = the_pref.backend == .js_node + } + 'js_browser' { + is_true = the_pref.backend == .js_browser + } + 'js_freestanding' { + is_true = the_pref.backend == .js_freestanding + } + 'interpreter' { + is_true = the_pref.backend == .interpret + } + 'es5' { + is_true = the_pref.output_es5 + } + 'profile' { + is_true = the_pref.is_prof + } + 'wasm32' { + is_true = the_pref.arch == .wasm32 + } + 'wasm32_wasi' { + is_true = the_pref.os == .wasm32_wasi + } + 'fast_math' { + is_true = the_pref.fast_math + } + 'native' { + is_true = the_pref.backend == .native + } + 'autofree' { + is_true = the_pref.autofree + } + else { + return error('invalid \$if condition: unknown other indent `${ident}`') + } + } + } else if ident in the_pref.compile_defines { + is_true = true + } else { + return error('invalid \$if condition: unknown indent `${ident}`') + } + return is_true +} + +pub const system_ident_map = { + // OS + 'windows': '_WIN32' + 'ios': '__TARGET_IOS__' + 'macos': '__APPLE__' + 'mach': '__MACH__' + 'darwin': '__DARWIN__' + 'hpux': '__HPUX__' + 'gnu': '__GNU__' + 'qnx': '__QNX__' + 'linux': '__linux__' + 'serenity': '__serenity__' + 'plan9': '__plan9__' + 'vinix': '__vinix__' + 'freebsd': '__FreeBSD__' + 'openbsd': '__OpenBSD__' + 'netbsd': '__NetBSD__' + 'bsd': '__BSD__' + 'dragonfly': '__DragonFly__' + 'android': '__ANDROID__' + 'termux': '__TERMUX__' + 'solaris': '__sun' + 'haiku': '__HAIKU__' + // Backend + 'js': '_VJS' + 'wasm32_emscripten': '__EMSCRIPTEN__' + 'native': '_VNATIVE' + // Compiler + 'gcc': '__V_GCC__' + 'tinyc': '__TINYC__' + 'clang': '__clang__' + 'mingw': '__MINGW32__' + 'msvc': '_MSC_VER' + 'cplusplus': '__cplusplus' + // Others + 'threads': '__VTHREADS__' + 'gcboehm': '_VGCBOEHM' + 'debug': '_VDEBUG' + 'prod': '_VPROD' + 'profile': '_VPROFILE' + 'test': '_VTEST' + 'glibc': '__GLIBC__' + 'prealloc': '_VPREALLOC' + 'no_bounds_checking': 'CUSTOM_DEFINE_no_bounds_checking' + 'freestanding': '_VFREESTANDING' + 'autofree': '_VAUTOFREE' + // CPU + 'amd64': '__V_amd64' + 'aarch64': '__V_arm64' + 'arm64': '__V_arm64' // aarch64 alias + 'arm32': '__V_arm32' + 'i386': '__V_x86' + 'rv64': '__V_rv64' + 'riscv64': '__V_rv64' // rv64 alias + 'rv32': '__V_rv32' + 'riscv32': '__V_rv32' // rv32 alias + 's390x': '__V_s390x' + 'ppc64le': '__V_ppc64le' + 'loongarch64': '__V_loongarch64' + 'x64': 'TARGET_IS_64BIT' + 'x32': 'TARGET_IS_32BIT' + 'little_endian': 'TARGET_ORDER_IS_LITTLE' + 'big_endian': 'TARGET_ORDER_IS_BIG' +} + +pub fn comptime_if_to_ifdef(name string, the_pref &pref.Preferences) !string { + if name == 'fast_math' { + return if the_pref.ccompiler_type == .msvc { + // turned on by: `-cflags /fp:fast` + '_M_FP_FAST' + } else { + // turned on by: `-cflags -ffast-math` + '__FAST_MATH__' + } + } + if ifdef := system_ident_map[name] { + return ifdef + } + return error('bad os ifdef name `${name}`') +} diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index 1befa70d85..9567c77cf5 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -784,191 +784,6 @@ fn (mut c Checker) evaluate_once_comptime_if_attribute(mut node ast.Attr) bool { return node.ct_skip } -fn (mut c Checker) comptime_if_to_ifdef(name string) !string { - match name { - // platforms/os-es: - 'windows' { - return '_WIN32' - } - 'ios' { - return '__TARGET_IOS__' - } - 'macos' { - return '__APPLE__' - } - 'mach' { - return '__MACH__' - } - 'darwin' { - return '__DARWIN__' - } - 'hpux' { - return '__HPUX__' - } - 'gnu' { - return '__GNU__' - } - 'qnx' { - return '__QNX__' - } - 'linux' { - return '__linux__' - } - 'serenity' { - return '__serenity__' - } - 'plan9' { - return '__plan9__' - } - 'vinix' { - return '__vinix__' - } - 'freebsd' { - return '__FreeBSD__' - } - 'openbsd' { - return '__OpenBSD__' - } - 'netbsd' { - return '__NetBSD__' - } - 'bsd' { - return '__BSD__' - } - 'dragonfly' { - return '__DragonFly__' - } - 'android' { - return '__ANDROID__' - } - 'termux' { - // Note: termux is running on Android natively so __ANDROID__ will also be defined - return '__TERMUX__' - } - 'solaris' { - return '__sun' - } - 'haiku' { - return '__HAIKU__' - } - // - 'js' { - return '_VJS' - } - 'wasm32_emscripten' { - return '__EMSCRIPTEN__' - } - 'native' { - return '_VNATIVE' // when using the native backend, cgen is inactive - } - // compilers: - 'gcc' { - return '__V_GCC__' - } - 'tinyc' { - return '__TINYC__' - } - 'clang' { - return '__clang__' - } - 'mingw' { - return '__MINGW32__' - } - 'msvc' { - return '_MSC_VER' - } - 'cplusplus' { - return '__cplusplus' - } - // other: - 'threads' { - return '__VTHREADS__' - } - 'gcboehm' { - return '_VGCBOEHM' - } - 'debug' { - return '_VDEBUG' - } - 'prod' { - return '_VPROD' - } - 'profile' { - return '_VPROFILE' - } - 'test' { - return '_VTEST' - } - 'glibc' { - return '__GLIBC__' - } - 'prealloc' { - return '_VPREALLOC' - } - 'no_bounds_checking' { - return 'CUSTOM_DEFINE_no_bounds_checking' - } - 'freestanding' { - return '_VFREESTANDING' - } - 'autofree' { - return '_VAUTOFREE' - } - // architectures: - 'amd64' { - return '__V_amd64' - } - 'aarch64', 'arm64' { - return '__V_arm64' - } - 'arm32' { - return '__V_arm32' - } - 'i386' { - return '__V_x86' - } - 'rv64', 'riscv64' { - return '__V_rv64' - } - 'rv32', 'riscv32' { - return '__V_rv32' - } - 's390x' { - return '__V_s390x' - } - 'ppc64le' { - return '__V_ppc64le' - } - 'loongarch64' { - return '__V_loongarch64' - } - // bitness: - 'x64' { - return 'TARGET_IS_64BIT' - } - 'x32' { - return 'TARGET_IS_32BIT' - } - // endianness: - 'little_endian' { - return 'TARGET_ORDER_IS_LITTLE' - } - 'big_endian' { - return 'TARGET_ORDER_IS_BIG' - } - 'fast_math' { - if c.pref.ccompiler_type == .msvc { - // turned on by: `-cflags /fp:fast` - return '_M_FP_FAST' - } - // turned on by: `-cflags -ffast-math` - return '__FAST_MATH__' - } - else {} - } - return error('bad os ifdef name "${name}"') -} - // check if `ident` is a function generic, such as `T` fn (mut c Checker) is_generic_ident(ident string) bool { if !isnil(c.table.cur_fn) && ident in c.table.cur_fn.generic_names @@ -1141,10 +956,6 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( should_record_ident = true is_user_ident = true ident_name = cname - // ifdef := c.comptime_if_to_ifdef(cname, true) or { - // c.error(err.msg(), cond.pos) - // return false, false - //} sb.write_string('defined(CUSTOM_DEFINE_${cname})') is_true = cname in c.pref.compile_defines return is_true, false @@ -1483,143 +1294,12 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( should_record_ident = true is_user_ident = false ident_name = cname - if cname in ast.valid_comptime_if_os { - if cname_enum_val := pref.os_from_string(cname) { - if cname_enum_val == c.pref.os { - is_true = true - } - } - } else if cname in ast.valid_comptime_if_compilers { - is_true = pref.cc_from_string(cname) == c.pref.ccompiler_type - } else if cname in ast.valid_comptime_if_platforms { - if cname == 'aarch64' { - c.note('use `arm64` instead of `aarch64`', cond.pos) - } - match cname { - 'amd64' { - is_true = c.pref.arch == .amd64 - } - 'i386' { - is_true = c.pref.arch == .i386 - } - 'aarch64' { - is_true = c.pref.arch == .arm64 - } - 'arm64' { - is_true = c.pref.arch == .arm64 - } - 'arm32' { - is_true = c.pref.arch == .arm32 - } - 'rv64' { - is_true = c.pref.arch == .rv64 - } - 'rv32' { - is_true = c.pref.arch == .rv32 - } - 's390x' { - is_true = c.pref.arch == .s390x - } - 'ppc64le' { - is_true = c.pref.arch == .ppc64le - } - 'loongarch64' { - is_true = c.pref.arch == .loongarch64 - } - else { - c.error('invalid \$if condition: unknown platforms `${cname}`', - cond.pos) - return false, false - } - } - } else if cname in ast.valid_comptime_if_cpu_features { - match cname { - 'x64' { - is_true = c.pref.m64 - } - 'x32' { - is_true = !c.pref.m64 - } - 'little_endian' { - is_true = $if little_endian { true } $else { false } - } - 'big_endian' { - is_true = $if big_endian { true } $else { false } - } - else { - c.error('invalid \$if condition: unknown cpu_features `${cname}`', - cond.pos) - return false, false - } - } - } else if cname in ast.valid_comptime_if_other { - match cname { - 'apk' { - is_true = c.pref.is_apk - } - 'js' { - is_true = c.pref.backend.is_js() - } - 'debug' { - is_true = c.pref.is_debug - } - 'prod' { - is_true = c.pref.is_prod - } - 'test' { - is_true = c.pref.is_test - } - 'glibc' { - is_true = c.pref.is_glibc - } - 'prealloc' { - is_true = c.pref.prealloc - } - 'no_bounds_checking' { - is_true = c.pref.no_bounds_checking - } - 'freestanding' { - is_true = c.pref.is_bare && !c.pref.output_cross_c - } - 'threads' { - is_true = c.table.gostmts > 0 - } - 'js_node' { - is_true = c.pref.backend == .js_node - } - 'js_browser' { - is_true = c.pref.backend == .js_browser - } - 'js_freestanding' { - is_true = c.pref.backend == .js_freestanding - } - 'interpreter' { - is_true = c.pref.backend == .interpret - } - 'es5' { - is_true = c.pref.output_es5 - } - 'profile' { - is_true = c.pref.is_prof - } - 'wasm32' { - is_true = c.pref.arch == .wasm32 - } - 'wasm32_wasi' { - is_true = c.pref.os == .wasm32_wasi - } - 'fast_math' { - is_true = c.pref.fast_math - } - 'native' { - is_true = c.pref.backend == .native - } - 'autofree' { - is_true = c.pref.autofree - } - else { - c.error('invalid \$if condition: unknown other indent `${cname}`', - cond.pos) + if cname in ast.valid_comptime_not_user_defined { + if cname == 'threads' { + is_true = c.table.gostmts > 0 + } else { + is_true = ast.eval_comptime_not_user_defined_ident(cname, c.pref) or { + c.error(err.msg(), cond.pos) return false, false } } @@ -1655,7 +1335,7 @@ fn (mut c Checker) comptime_if_cond(mut cond ast.Expr, mut sb strings.Builder) ( c.error('invalid \$if condition: unknown indent `${cname}`', cond.pos) return false, false } - if ifdef := c.comptime_if_to_ifdef(cname) { + if ifdef := ast.comptime_if_to_ifdef(cname, c.pref) { sb.write_string('defined(${ifdef})') } else { sb.write_string('${is_true}') diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index 3578481a06..260be280f4 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -5,7 +5,6 @@ module parser import v.ast import v.token -import v.pref import v.pkgconfig fn (mut p Parser) if_expr(is_comptime bool, is_expr bool) ast.IfExpr { @@ -724,140 +723,12 @@ fn (mut p Parser) comptime_if_cond(mut cond ast.Expr) bool { } ast.Ident { cname := cond.name - if cname in ast.valid_comptime_if_os { - if cname_enum_val := pref.os_from_string(cname) { - if cname_enum_val == p.pref.os { - is_true = true - } - } - } else if cname in ast.valid_comptime_if_compilers { - is_true = pref.cc_from_string(cname) == p.pref.ccompiler_type - } else if cname in ast.valid_comptime_if_platforms { - if cname == 'aarch64' { - p.note('use `arm64` instead of `aarch64`') - } - match cname { - 'amd64' { - is_true = p.pref.arch == .amd64 - } - 'i386' { - is_true = p.pref.arch == .i386 - } - 'aarch64' { - is_true = p.pref.arch == .arm64 - } - 'arm64' { - is_true = p.pref.arch == .arm64 - } - 'arm32' { - is_true = p.pref.arch == .arm32 - } - 'rv64' { - is_true = p.pref.arch == .rv64 - } - 'rv32' { - is_true = p.pref.arch == .rv32 - } - 's390x' { - is_true = p.pref.arch == .s390x - } - 'ppc64le' { - is_true = p.pref.arch == .ppc64le - } - 'loongarch64' { - is_true = p.pref.arch == .loongarch64 - } - else { - p.error('invalid \$if condition: unknown platforms `${cname}`') - return false - } - } - } else if cname in ast.valid_comptime_if_cpu_features { - match cname { - 'x64' { - is_true = p.pref.m64 - } - 'x32' { - is_true = !p.pref.m64 - } - 'little_endian' { - is_true = $if little_endian { true } $else { false } - } - 'big_endian' { - is_true = $if big_endian { true } $else { false } - } - else { - p.error('invalid \$if condition: unknown cpu_features `${cname}`') - return false - } - } - } else if cname in ast.valid_comptime_if_other { - match cname { - 'apk' { - is_true = p.pref.is_apk - } - 'js' { - is_true = p.pref.backend.is_js() - } - 'debug' { - is_true = p.pref.is_debug - } - 'prod' { - is_true = p.pref.is_prod - } - 'test' { - is_true = p.pref.is_test - } - 'glibc' { - is_true = p.pref.is_glibc - } - 'prealloc' { - is_true = p.pref.prealloc - } - 'no_bounds_checking' { - is_true = p.pref.no_bounds_checking - } - 'freestanding' { - is_true = p.pref.is_bare && !p.pref.output_cross_c - } - 'threads' { - is_true = p.table.gostmts > 0 - } - 'js_node' { - is_true = p.pref.backend == .js_node - } - 'js_browser' { - is_true = p.pref.backend == .js_browser - } - 'js_freestanding' { - is_true = p.pref.backend == .js_freestanding - } - 'interpreter' { - is_true = p.pref.backend == .interpret - } - 'es5' { - is_true = p.pref.output_es5 - } - 'profile' { - is_true = p.pref.is_prof - } - 'wasm32' { - is_true = p.pref.arch == .wasm32 - } - 'wasm32_wasi' { - is_true = p.pref.os == .wasm32_wasi - } - 'fast_math' { - is_true = p.pref.fast_math - } - 'native' { - is_true = p.pref.backend == .native - } - 'autofree' { - is_true = p.pref.autofree - } - else { - p.error('invalid \$if condition: unknown other indent `${cname}`') + if cname in ast.valid_comptime_not_user_defined { + if cname == 'threads' { + is_true = p.table.gostmts > 0 + } else { + is_true = ast.eval_comptime_not_user_defined_ident(cname, p.pref) or { + p.error(err.msg()) return false } }