diff --git a/build/src/build.bqn b/build/src/build.bqn index be83264a..f3db89ba 100755 --- a/build/src/build.bqn +++ b/build/src/build.bqn @@ -713,17 +713,27 @@ cachedBin‿linkerCache ← { po.versionName≡@? @; srcFile ← linkerCache.File "versionInfo.c" List ← {¯2↓ ∾ ∾⟜", "¨ /´ <˘⍉> 𝕩} - src ← "char* cbqn_versionString = """∾(∾∾⟜"\n"¨ ×∘≠¨⊸/ ⟨ - "CBQN "∾{po.versionName≡""? "on commit "∾(GitCmd ⟨"rev-parse", "HEAD"⟩)∾{""≡GitCmd ⟨"status", "--porcelain", "src"⟩? ""; "-dirty"}; po.versionName} - "built with "⊸∾⍟(×≠) List ⟨ - ⟨po.ffi, "FFI"⟩ - ⟨po.singeli, "singeli "∾{po.native? "native "∾po.arch; po.arch≡"generic"? po.arch∾" (no SIMD)"; po.arch}∾∾' '∾¨po.has⟩ - ⟨po.replxx, "replxx"⟩ - ⟨¬po.o3, "optimizations disabled"⟩ - {⟨×≠𝕩, "debugging checks enabled ("∾𝕩∾")"⟩} List ⟨po.debug‿"DEBUG", po.heapverify‿"heapverify", po.rtverify‿"rtverify"⟩ + + vnameX‿vname ← {po.versionName≡""? "on "⊸∾⊸⋈ "commit "∾(GitCmd ⟨"rev-parse", "HEAD"⟩)∾{""≡GitCmd ⟨"status", "--porcelain", "src"⟩? ""; "-dirty"}; ⋈˜ po.versionName} + + src ← ∾⟨ + "char* cbqn_versionInfo = """ + + ∾∾⟜"\n"¨ ×∘≠¨⊸/ ⟨ + "CBQN "∾vnameX + "built with "⊸∾⍟(×≠) List ⟨ + ⟨po.ffi, "FFI"⟩ + ⟨po.singeli, "singeli "∾{po.native? "native "∾po.arch; po.arch≡"generic"? po.arch∾" (no SIMD)"; po.arch}∾∾' '∾¨po.has⟩ + ⟨po.replxx, "replxx"⟩ + ⟨¬po.o3, "optimizations disabled"⟩ + {⟨×≠𝕩, "debugging checks enabled ("∾𝕩∾")"⟩} List ⟨po.debug‿"DEBUG", po.heapverify‿"heapverify", po.rtverify‿"rtverify"⟩ + ⟩ ⟩ # "build invocation: "⊸∾⍟(×≠) ¯1↓∾∾⟜' '¨ •args - ⟩)∾""";"∾@+10 + + """;", @+10 + "char* cbqn_versionString = """∾vname∾""";", @+10 + ⟩ { •file.Exists AtRoot srcFile? src≡•FChars AtRoot srcFile? @; # don't update (AtRoot srcFile) •FChars src diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index f7294c4d..f5aee785 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1645,7 +1645,8 @@ static Body* file_nsGen; F("args", U"•args", tag(16,VAR_TAG)) \ F("listsys", U"•listsys", tag(17,VAR_TAG)) \ OPTSYS(NATIVE_COMPILER)(F("compobj", U"•CompObj", tag(18,VAR_TAG))) \ - F("ns", U"•ns", tag(19,VAR_TAG)) + F("ns", U"•ns", tag(19,VAR_TAG)) \ + F("platform", U"•platform", tag(20,VAR_TAG)) NFnDesc* ffiloadDesc; B ffiload_c2(B t, B w, B x); @@ -1684,6 +1685,72 @@ static void initFileNS() { ffiloadDesc = registerNFn(m_c32vec_0(U"•FFI"), c1_bad, ffiload_c2); } +#if HAS_VERSION +extern char* cbqn_versionString; +#endif + +static B platformNS; +static B getPlatformNS(void) { + if (platformNS.u == 0) { + + #if defined(_WIN32) || defined(_WIN64) + char* os = "windows"; + #elif __ANDROID__ + char* os = "android"; + #elif __linux__ + char* os = "linux"; + #elif __FreeBSD__ || __OpenBSD__ + char* os = "bsd"; + #elif __APPLE__ || __MACH__ + char* os = "darwin"; + #elif __unix || __unix__ + char* os = "unix"; + #else + char* os = "unknown"; + #endif + + #if __x86_64__ + char* arch = "x86-64"; + #elif __i386__ + char* arch = "x86"; + #elif __aarch64__ + char* arch = "aarch64"; + #elif __arm__ + char* arch = "aarch32"; + #elif __riscv + #define F(X) #X + #define F2(X) F(X) + char* arch = "riscv" F2(__riscv_xlen); + #undef F2 + #undef F + #else + char* arch = "unknown"; + #endif + + #if WASM + char* env = "wasm"; + #else + char* env = "native"; + #endif + + #if HAS_VERSION + char* cbqn_ver = cbqn_versionString; + #else + char* cbqn_ver = "unknown"; + #endif + + platformNS = m_nns(m_nnsDesc("os","environment","cpu","bqn"), + m_c8vec_0(os), + m_c8vec_0(env), + m_nns(m_nnsDesc("arch"), m_c8vec_0(arch)), + m_nns(m_nnsDesc("impl","implversion"), m_c8vec_0("CBQN"), m_c8vec_0(cbqn_ver)), + ); + #undef F + gc_add(platformNS); + } + return incG(platformNS); +} + B sys_c1(B t, B x) { assert(isArr(x)); @@ -1751,6 +1818,7 @@ B sys_c1(B t, B x) { case 17: cr = incG(curr_ns); break; // •listsys case 18: cr = incG(bi_compObj); break; // •CompObj case 19: cr = getNsNS(); break; // •ns + case 20: cr = getPlatformNS(); break; } HARR_ADD(r, i, cr); } @@ -1783,7 +1851,10 @@ u32* dsv_text[] = { U"•internal.ClearRefs",U"•internal.DeepSqueeze",U"•internal.EEqual",U"•internal.ElType",U"•internal.GC",U"•internal.HasFill",U"•internal.HeapDump",U"•internal.Info",U"•internal.IsPure",U"•internal.Keep",U"•internal.ListVariations",U"•internal.Refc",U"•internal.Squeeze",U"•internal.Temp",U"•internal.Type",U"•internal.Unshare",U"•internal.Variation", U"•math.Acos",U"•math.Acosh",U"•math.Asin",U"•math.Asinh",U"•math.Atan",U"•math.Atan2",U"•math.Atanh",U"•math.Cbrt",U"•math.Comb",U"•math.Cos",U"•math.Cosh",U"•math.Erf",U"•math.ErfC",U"•math.Expm1",U"•math.Fact",U"•math.GCD",U"•math.Hypot",U"•math.LCM",U"•math.Log10",U"•math.Log1p",U"•math.Log2",U"•math.LogFact",U"•math.Sin",U"•math.Sinh",U"•math.Sum",U"•math.Tan",U"•math.Tanh", + U"•ns.Get",U"•ns.Has",U"•ns.Keys", + U"•platform.bqn.impl",U"•platform.bqn.implVersion",U"•platform.cpu.arch",U"•platform.environment",U"•platform.os", + U"•rand.Deal",U"•rand.Range",U"•rand.Subset", U"•term.CharB",U"•term.CharN",U"•term.ErrRaw",U"•term.Flush",U"•term.OutRaw",U"•term.RawMode", NULL diff --git a/src/main.c b/src/main.c index 379621f7..46c1d565 100644 --- a/src/main.c +++ b/src/main.c @@ -274,10 +274,19 @@ static NOINLINE i64 readInt(char** p) { ws = rskip_name(chars, we); u32 last = ws>chars? *(ws-1) : 0; mode = last=='.'? 2 : last==U'•'? 1 : 0; + if (mode==2) { - u32* ws2 = rskip_name(chars, ws-1); - if (ws2>chars && U'•' == *(ws2-1)) { ws=ws2; mode = 1; } + u32* ws2 = ws; + while (--ws2 > chars && *ws2=='.') { + u32* ws3 = rskip_name(chars, ws2); + if (ws2==ws3 || ws3==chars) break; + ws2 = ws3; + + u32 last2 = *(ws2-1); + if (last2==U'•') { ws=ws2; mode=1; break; } + } } + if (mode==1) ws--; } @@ -901,7 +910,7 @@ int main() { } #elif !CBQN_LIB #if HAS_VERSION -extern char* cbqn_versionString; +extern char* cbqn_versionInfo; #endif int main(int argc, char* argv[]) { #if USE_REPLXX_IO @@ -940,7 +949,7 @@ int main(int argc, char* argv[]) { exit(0); } else if (!strcmp(carg, "--version")) { #if HAS_VERSION - printf("%s", cbqn_versionString); + printf("%s", cbqn_versionInfo); #else printf("CBQN, unknown version\n"); #endif