diff --git a/makefile b/makefile index 0e635200..9d2748d9 100644 --- a/makefile +++ b/makefile @@ -3,6 +3,8 @@ J=-j4 o3: @$(MAKE) $(J) -C obj/o3 o3 +o3n: + @$(MAKE) $(J) -C obj/o3n o3n o3g: @$(MAKE) $(J) -C obj/o3g o3g debug: @@ -16,6 +18,8 @@ rtverify: o3-clean: @$(MAKE) -C obj/o3 clean +o3n-clean: + @$(MAKE) -C obj/o3n clean o3g-clean: @$(MAKE) -C obj/o3g clean debug-clean: @@ -27,4 +31,4 @@ heapverify-clean: rtverify-clean: @$(MAKE) -C obj/rtverify clean -clean: o3-clean o3g-clean debug-clean rtperf-clean heapverify-clean rtverify-clean +clean: o3-clean o3n-clean o3g-clean debug-clean rtperf-clean heapverify-clean rtverify-clean diff --git a/obj/o3n/makefile b/obj/o3n/makefile new file mode 120000 index 00000000..26ebd524 --- /dev/null +++ b/obj/o3n/makefile @@ -0,0 +1 @@ +../subMakefile \ No newline at end of file diff --git a/obj/subMakefile b/obj/subMakefile index e9905ee1..08efd0ad 100644 --- a/obj/subMakefile +++ b/obj/subMakefile @@ -7,6 +7,8 @@ CMD=$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions ${CCFLAGS} $(FLA o3: FLAGS=-O3 o3: gen +o3n: FLAGS=-O3 -march=native +o3n: gen o3g: FLAGS=-O3 -g o3g: gen debug: FLAGS=-g -DDEBUG diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 675571d9..e0d44c96 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -227,47 +227,62 @@ B slash_c2(B t, B w, B x) { usz xia = a(x)->ia; B xf = getFillQ(x); if (wia!=xia) thrF("/: Lengths of components of š•Ø must match š•© (%s ≠ %s)", wia, xia); - i64 wsum = isum(w); if (wsum>USZ_MAX) thrOOM(); - usz ria = wsum; + usz ri = 0; if (TI(w).elType==el_i32) { i32* wp = i32any_ptr(w); + while (wia>0 && !wp[wia-1]) wia--; + + i64 wsum = 0; + u32 or = 0; + for (usz i = 0; i < wia; i++) { + wsum+= wp[i]; + or|= (u32)wp[i]; + } + if (or>>31) thrM("/: š•Ø must consist of natural numbers"); + if (TI(x).elType==el_i32) { i32* xp = i32any_ptr(x); - i32* rp; B r = m_i32arrv(&rp, ria); - for (usz i = 0; i < wia; i++) { - i32 c = wp[i]; - if (c<0) thrF("/: š•Ø must consist of natural numbers (%iāˆŠš•Ø)", c); - i32 cx = xp[i]; - for (usz j = 0; j < c; j++) *rp++ = cx; + i32* rp; B r = m_i32arrv(&rp, wsum); + if (or<2) { + for (usz i = 0; i < wia; i++) { + *rp = xp[i]; + rp+= wp[i]; + } + } else { + for (usz i = 0; i < wia; i++) { + i32 cw = wp[i]; + i32 cx = xp[i]; + for (usz j = 0; j < cw; j++) *rp++ = cx; + } } dec(w); dec(x); return r; } else if (TI(x).elType==el_f64) { f64* xp = f64any_ptr(x); - f64* rp; B r = m_f64arrv(&rp, ria); + f64* rp; B r = m_f64arrv(&rp, wsum); for (usz i = 0; i < wia; i++) { - i32 c = wp[i]; - if (c<0) thrF("/: š•Ø must consist of natural numbers (%iāˆŠš•Ø)", c); + i32 cw = wp[i]; f64 cx = xp[i]; - for (usz j = 0; j < c; j++) *rp++ = cx; + for (usz j = 0; j < cw; j++) *rp++ = cx; } dec(w); dec(x); return r; } else { - HArr_p r = m_harrs(ria, &ri); + HArr_p r = m_harrs(wsum, &ri); BS2B xgetU = TI(x).getU; for (usz i = 0; i < wia; i++) { - i32 c = wp[i]; - if (c==0) continue; - if (c<0) thrF("/: š•Ø must consist of natural numbers (%iāˆŠš•Ø)", c); + i32 cw = wp[i]; + if (cw==0) continue; B cx = xgetU(x, i); - for (usz j = 0; j < c; j++) r.a[ri++] = inc(cx); + for (usz j = 0; j < cw; j++) r.a[ri++] = inc(cx); } dec(w); dec(x); return withFill(harr_fv(r), xf); } } else { + i64 ria = isum(w); + if (ria>USZ_MAX) thrOOM(); HArr_p r = m_harrs(ria, &ri); BS2B wgetU = TI(w).getU; BS2B xgetU = TI(x).getU; diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 633c386d..29de276f 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -232,7 +232,7 @@ B fchars_c1(B d, B x) { return file_chars(path_resolve(nfn_objU(d), x)); } B fchars_c2(B d, B w, B x) { - file_write(path_resolve(nfn_objU(d), w), x); + file_wChars(path_resolve(nfn_objU(d), w), x); return x; } static NFnDesc* fBytesDesc; diff --git a/src/core/stuff.h b/src/core/stuff.h index ffa7ae26..124fb5ad 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -48,7 +48,9 @@ typedef struct TStack { } TStack; #define TSALLOC(T,N,I) usz N##_dc=(I); u32 N##_e=sizeof(T); TStack* N##_o = (TStack*)mm_allocN(sizeof(TStack)+N##_e*N##_dc, t_temp); N##_o->size=0; N##_o->cap=N##_dc; T* N = (T*)N##_o->data; #define TSFREE(N) mm_free((Value*)N##_o); -#define TSADD(N,X) { if (N##_o->size==N##_o->cap) { N##_o = tstack_ext(N##_o, N##_e); N = (void*)N##_o->data; } N[N##_o->size++] = X; } +#define TSDBL(N) { N##_o = tstack_ext(N##_o, N##_e); N = (void*)N##_o->data; } +#define TSADD(N,X) { if (N##_o->size==N##_o->cap) TSDBL(N); N[N##_o->size++] = X; } +#define TSADDA(N,P,AM) { u64 n=AM; while(N##_o->size+n>N##_o->cap) TSDBL(N); memcpy(N+N##_o->size,P,n*N##_e); N##_o->size+= AM; } #define TSSIZE(N) (N##_o->size) static NOINLINE TStack* tstack_ext(TStack* o, u32 elsz) { usz ncap = o->cap*2; diff --git a/src/utils/file.c b/src/utils/file.c index e68caaf8..ef84f8e1 100644 --- a/src/utils/file.c +++ b/src/utils/file.c @@ -84,7 +84,7 @@ B path_dir(B path) { // consumes; returns directory part of file path with trail } -void file_write(B path, B x) { // consumes path +void file_wChars(B path, B x) { // consumes path FILE* f = file_open(path, "write to", "w"); u64 len = utf8lenB(x); @@ -96,6 +96,19 @@ void file_write(B path, B x) { // consumes path dec(path); fclose(f); } +void file_wBytes(B path, B x) { // consumes path + FILE* f = file_open(path, "write to", "w"); + + u64 len = a(x)->ia; + TALLOC(char, val, len); + BS2B xgetU = TI(x).getU; + for (u64 i = 0; i < len; i++) val[i] = o2i(xgetU(x,i)); + + if (fwrite(val, 1, len, f) != len) thrF("Error writing to file \"%R\"", path); + TFREE(val); + dec(path); + fclose(f); +} B file_list(B path) { DIR* d = dir_open(path); diff --git a/src/utils/file.h b/src/utils/file.h index 63379e24..0c49a18d 100644 --- a/src/utils/file.h +++ b/src/utils/file.h @@ -12,6 +12,7 @@ B path_dir(B path); // consumes; returns directory part of file path, with trail TmpFile* file_bytes(B path); // consumes B file_chars(B path); // consumes -void file_write(B path, B x); // consumes path +void file_wChars(B path, B x); // consumes path +void file_wBytes(B path, B x); // consumes path B file_list(B path); // consumes