⎊ and proper _fillBy_
This commit is contained in:
parent
38ab8ecf96
commit
e345f37605
2
cc.bqn
2
cc.bqn
@ -29,7 +29,7 @@ useInd ← "-i"≡⊑args ⋄ args↓˜↩useInd
|
||||
Comp ← (3+useInd) ↑ ((<"inc(runtime["∾⍕∾"])"˙)¨↕62)⊸Compile
|
||||
J ← ∾∾⟜\n¨
|
||||
Fconst ← ≡◶⟨@⊸≤◶Num‿Char, Str, ⊑⟩
|
||||
prov ← {"inc("∾𝕩∾")"}¨"bi_type"‿"bi_fill"‿"bi_log"‿"bi_grLen"‿"bi_grOrd"‿"bi_asrt"‿"bi_add"‿"bi_sub"‿"bi_mul"‿"bi_div"‿"bi_pow"‿"bi_floor"‿"bi_eq"‿"bi_le"‿"bi_fne"‿"bi_shape"‿"bi_pick"‿"bi_ud"‿"bi_tbl"‿"bi_scan"‿"bi_fillBy"‿"bi_val"
|
||||
prov ← {"inc("∾𝕩∾")"}¨"bi_type"‿"bi_fill"‿"bi_log"‿"bi_grLen"‿"bi_grOrd"‿"bi_asrt"‿"bi_add"‿"bi_sub"‿"bi_mul"‿"bi_div"‿"bi_pow"‿"bi_floor"‿"bi_eq"‿"bi_le"‿"bi_fne"‿"bi_shape"‿"bi_pick"‿"bi_ud"‿"bi_tbl"‿"bi_scan"‿"bi_fillBy"‿"bi_val"‿"bi_catch"
|
||||
Fout ← {((≠𝕩)↑⟨LI F¨,L ·prov⊸∾⍟(𝕨⊣0) Fconst¨,L (LI F¨)¨,L (L F¨)¨⟩) {𝕎𝕩}¨ 𝕩}
|
||||
Frun ← 1⊸Fout
|
||||
Long ← {¯2↓∾𝕩∾¨<","∾\n}
|
||||
|
||||
@ -28,7 +28,7 @@ B m_str8(usz sz, char* s) {
|
||||
for (u64 i = 0; i < sz; i++) p[i] = s[i];
|
||||
return r;
|
||||
}
|
||||
B m_str32(u32* s) { // meant to be used as m_str32(U"{𝕨‿𝕩}")
|
||||
NOINLINE B m_str32(u32* s) { // meant to be used as m_str32(U"{𝕨‿𝕩}")
|
||||
u64 sz = 0; while(s[sz]) sz++;
|
||||
B r = m_c32arrv(sz); u32* p = c32arr_ptr(r);
|
||||
for (u64 i = 0; i < sz; i++) p[i] = s[i];
|
||||
|
||||
@ -22,7 +22,7 @@ B asFill(B x) { // consumes
|
||||
dec(x);
|
||||
return bi_noFill;
|
||||
}
|
||||
B getFill(B x) { // consumes
|
||||
B getFill(B x) { // consumes; can return bi_noFill
|
||||
if (isArr(x)) {
|
||||
u8 t = v(x)->type;
|
||||
if (t==t_fillarr ) { B r = inc(c(FillArr,x )->fill); dec(x); return r; }
|
||||
@ -30,13 +30,15 @@ B getFill(B x) { // consumes
|
||||
if (t==t_c32arr || t==t_c32slice) { dec(x); return m_c32(' '); }
|
||||
if (t==t_i32arr || t==t_i32slice) { dec(x); return m_f64(0 ); }
|
||||
dec(x);
|
||||
return m_f64(0);
|
||||
return bi_noFill;
|
||||
}
|
||||
if (isC32(x)) return m_c32(' ');
|
||||
if (isF64(x)|isI32(x)) return m_i32(0);
|
||||
if (isC32(x)) return m_c32(' ');
|
||||
dec(x);
|
||||
return m_f64(0);
|
||||
if (isMd(x) || isFun(x)) return bi_noFill;
|
||||
return bi_noFill;
|
||||
}
|
||||
bool noFill(B x) { return x.u == bi_noFill.u; }
|
||||
|
||||
typedef struct FillSlice {
|
||||
struct Slice;
|
||||
@ -85,6 +87,7 @@ void fillarr_init() {
|
||||
|
||||
B withFill(B x, B fill) { // consumes both
|
||||
assert(isArr(x));
|
||||
if (noFill(fill) && v(x)->type!=t_fillarr && v(x)->type!=t_fillslice) return x;
|
||||
switch(v(x)->type) {
|
||||
case t_i32arr : case t_i32slice : if(fill.u == m_i32(0 ).u) return x; break;
|
||||
case t_c32arr : case t_c32slice : if(fill.u == m_c32(' ').u) return x; break;
|
||||
|
||||
20
src/h.h
20
src/h.h
@ -121,12 +121,12 @@ char* format_pm1(u8 u) {
|
||||
}
|
||||
enum PrimMd2 {
|
||||
pm2_none,
|
||||
pm2_val, pm2_fillBy, // md2.c
|
||||
pm2_val, pm2_fillBy, pm2_catch, // md2.c
|
||||
};
|
||||
char* format_pm2(u8 u) {
|
||||
switch(u) {
|
||||
default: case pf_none: return"(unknown 1-modifier)";
|
||||
case pm2_val: return"⊘"; case pm2_fillBy: return"•_fillBy_";
|
||||
case pm2_val: return"⊘"; case pm2_fillBy: return"•_fillBy_"; case pm2_catch: return"⎊";
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,8 +204,8 @@ NORETURN void thr(B b);
|
||||
NORETURN void thrM(char* s);
|
||||
jmp_buf* prepareCatch();
|
||||
#ifdef CATCH_ERRORS
|
||||
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error; dec(catchMessage);*/ } /*regular execution*/ popCatch();`
|
||||
#else
|
||||
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error; dec(catchMessage);*/ } /*potentially erroring thing*/ popCatch();`
|
||||
#else // note: popCatch() must always be called if no error was caught, so no returns before it!
|
||||
#define CATCH false
|
||||
#endif
|
||||
void popCatch();
|
||||
@ -252,6 +252,7 @@ bool isVal(B x) { return (x.u - (((u64)VAL_TAG<<51) + 1)) < ((1ull<<51) - 1); }
|
||||
bool isF64(B x) { return (x.u<<1) - ((0xFFEull<<52) + 2) >= (1ull<<52) - 2; }
|
||||
|
||||
bool isAtm(B x) { return !isVal(x); }
|
||||
bool noFill(B x);
|
||||
|
||||
// shape mess
|
||||
typedef struct ShArr {
|
||||
@ -313,9 +314,9 @@ B m_i32(i32 n) { return m_f64(n); }
|
||||
B m_error() { return tag(4, TAG_TAG); }
|
||||
B m_usz(usz n) { return n==(i32)n? m_i32(n) : m_f64(n); }
|
||||
|
||||
i32 o2i (B x) { if ((i32)x.f!=x.f) err("o2i"": expected integer"); return (i32)x.f; }
|
||||
usz o2s (B x) { if ((usz)x.f!=x.f) err("o2s"": expected integer"); return (usz)x.f; }
|
||||
i64 o2i64(B x) { if ((i64)x.f!=x.f) err("o2i64: expected integer"); return (i64)x.f; }
|
||||
i32 o2i (B x) { if ((i32)x.f!=x.f) thrM("Expected integer"); return (i32)x.f; }
|
||||
usz o2s (B x) { if ((usz)x.f!=x.f) thrM("Expected integer"); return (usz)x.f; }
|
||||
i64 o2i64(B x) { if ((i64)x.f!=x.f) thrM("Expected integer"); return (i64)x.f; }
|
||||
i32 o2iu (B x) { return isI32(x)? (i32)(u32)x.u : (i32)x.f; }
|
||||
bool q_i32(B x) { return isI32(x) || isF64(x)&(x.f==(i32)x.f); }
|
||||
|
||||
@ -464,6 +465,7 @@ void print(B x) {
|
||||
else if (x.u==bi_optOut.u) printf("(value optimized out)");
|
||||
else if (x.u==bi_noVar.u) printf("(unset variable placeholder)");
|
||||
else if (x.u==bi_badHdr.u) printf("(bad header note)");
|
||||
else if (x.u==bi_noFill.u) printf("(no fill placeholder)");
|
||||
else printf("(todo tag %lx)", x.u>>48);
|
||||
}
|
||||
void printRaw(B x) {
|
||||
@ -476,7 +478,7 @@ void printRaw(B x) {
|
||||
BS2B xget = TI(x).get;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
B c = xget(x,i);
|
||||
if (c.u==0 | c.u==bi_noFill.u) { printf(" "); continue; }
|
||||
if (c.u==0 || noFill(c)) { printf(" "); continue; }
|
||||
if (!isC32(c)) err("bad printRaw argument: expected all character items");
|
||||
printUTF8((u32)c.u);
|
||||
}
|
||||
@ -655,4 +657,4 @@ static inline void onFree(Value* x) {
|
||||
x->refc = -1431655000;
|
||||
#endif
|
||||
// x->refc = 0x61616161;
|
||||
}
|
||||
}
|
||||
|
||||
10
src/main.c
10
src/main.c
@ -16,6 +16,7 @@
|
||||
// #define FORMATTER // use self-hosted formatter for output
|
||||
// #define TIME // output runtime of every expression
|
||||
|
||||
#define rtLen 63
|
||||
#include "h.h"
|
||||
#include "heap.c"
|
||||
#include "mm_buddy.c"
|
||||
@ -27,9 +28,9 @@
|
||||
#include "derv.c"
|
||||
#include "arith.c"
|
||||
#include "sfns.c"
|
||||
#include "sysfn.c"
|
||||
#include "md1.c"
|
||||
#include "md2.c"
|
||||
#include "sysfn.c"
|
||||
#include "vm.c"
|
||||
|
||||
void pr(char* a, B b) {
|
||||
@ -97,10 +98,11 @@ int main() {
|
||||
/* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_N , bi_N , bi_N , bi_N , bi_N , bi_N , bi_pick , bi_N , bi_N, bi_N,
|
||||
/* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_N , bi_asrt , bi_N , bi_N , bi_N , bi_N , bi_tbl, bi_N, bi_N,
|
||||
/* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan, bi_N , bi_N , bi_N , bi_N , bi_N , bi_val, bi_N, bi_N,
|
||||
/* ⚇⍟ */ bi_N , bi_fill
|
||||
/* ⚇⍟⎊ */ bi_N , bi_fill, bi_catch
|
||||
};
|
||||
for (i32 i = 0; i < 62; i++) inc(fruntime[i]);
|
||||
B frtObj = m_caB(62, fruntime);
|
||||
assert(sizeof(fruntime)/sizeof(B) == rtLen);
|
||||
for (i32 i = 0; i < rtLen; i++) inc(fruntime[i]);
|
||||
B frtObj = m_caB(rtLen, fruntime);
|
||||
|
||||
|
||||
Block* runtime_b = compile(
|
||||
|
||||
@ -96,6 +96,7 @@ B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
|
||||
B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
if (!isArr(x) || rnk(x)==0) thrM("`: argument cannot have rank 0");
|
||||
B xf = getFill(inc(x));
|
||||
ur xr = rnk(x);
|
||||
usz ia = a(x)->ia;
|
||||
if (ia==0) return x;
|
||||
@ -111,7 +112,7 @@ B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
for (usz i = csz; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i));
|
||||
}
|
||||
dec(x);
|
||||
return r.b;
|
||||
return withFill(r.b, xf);
|
||||
}
|
||||
B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
if (!isArr(x) || rnk(x)==0) thrM("`: 𝕩 cannot have rank 0");
|
||||
|
||||
31
src/md2.c
31
src/md2.c
@ -5,8 +5,35 @@
|
||||
B val_c1(B d, B x) { return c1(c(Md2D,d)->f, x); }
|
||||
B val_c2(B d, B w, B x) { return c2(c(Md2D,d)->g, w,x); }
|
||||
|
||||
|
||||
#ifdef CATCH_ERRORS
|
||||
B fillBy_c1(B d, B x) {
|
||||
B xf=getFill(inc(x));
|
||||
B r = c1(c(Md2D,d)->f, x);
|
||||
if(!isArr(r) || noFill(xf)) { dec(xf); return r; }
|
||||
if (CATCH) { dec(catchMessage); return r; }
|
||||
B fill = asFill(c1(c(Md2D,d)->g, xf));
|
||||
popCatch();
|
||||
return withFill(r, fill);
|
||||
}
|
||||
B fillBy_c2(B d, B w, B x) {
|
||||
B wf=getFill(inc(w)); B xf=getFill(inc(x));
|
||||
B r = c2(c(Md2D,d)->f, w,x);
|
||||
if(!isArr(r) || noFill(xf)) { dec(xf); dec(wf); return r; }
|
||||
if (CATCH) { dec(catchMessage); return r; }
|
||||
if (noFill(wf)) wf = inc(bi_asrt);
|
||||
B fill = asFill(c2(c(Md2D,d)->g, wf, xf));
|
||||
popCatch();
|
||||
return withFill(r, fill);
|
||||
}
|
||||
B catch_c1(B d, B x) { if(CATCH) return c1(c(Md2D,d)->g, x); B r = c1(c(Md2D,d)->f, x); popCatch(); return r; }
|
||||
B catch_c2(B d, B w, B x) { if(CATCH) return c2(c(Md2D,d)->g, w,x); B r = c2(c(Md2D,d)->f, w,x); popCatch(); return r; }
|
||||
#else
|
||||
B fillBy_c1(B d, B x) { return c1(c(Md2D,d)->f, x); }
|
||||
B fillBy_c2(B d, B w, B x) { return c2(c(Md2D,d)->f, w,x); }
|
||||
B catch_c1 (B d, B x) { return c1(c(Md2D,d)->f, x); }
|
||||
B catch_c2 (B d, B w, B x) { return c2(c(Md2D,d)->f, w,x); }
|
||||
#endif
|
||||
|
||||
#define ba(NAME) bi_##NAME = mm_alloc(sizeof(Md2), t_md2_def, ftag(MD2_TAG)); c(Md2,bi_##NAME)->c2 = NAME##_c2; c(Md2,bi_##NAME)->c1 = NAME##_c1; c(Md2,bi_##NAME)->extra=pm2_##NAME; gc_add(bi_##NAME);
|
||||
#define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md2), t_md2_def, ftag(MD2_TAG)); c(Md2,bi_##NAME)->c2 = NAME##_c2; c(Md2,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm2_##NAME; gc_add(bi_##NAME);
|
||||
@ -14,8 +41,8 @@ B fillBy_c2(B d, B w, B x) { return c2(c(Md2D,d)->f, w,x); }
|
||||
|
||||
void print_md2_def(B x) { printf("%s", format_pm2(c(Md1,x)->extra)); }
|
||||
|
||||
B bi_val, bi_fillBy;
|
||||
void md2_init() { ba(val) ba(fillBy)
|
||||
B bi_val, bi_fillBy, bi_catch;
|
||||
void md2_init() { ba(val) ba(fillBy) ba(catch)
|
||||
ti[t_md2_def].print = print_md2_def;
|
||||
}
|
||||
|
||||
|
||||
62
src/sfns.c
62
src/sfns.c
@ -1,39 +1,37 @@
|
||||
#include "h.h"
|
||||
|
||||
B shape_c1(B t, B x) {
|
||||
if (isArr(x)) {
|
||||
usz ia = a(x)->ia;
|
||||
if (reusable(x)) {
|
||||
decSh(x);
|
||||
arr_shVec(x, ia);
|
||||
return x;
|
||||
}
|
||||
B r = TI(x).slice(x, 0);
|
||||
arr_shVec(r, ia);
|
||||
return r;
|
||||
} else return err("reshaping non-array");
|
||||
if (!isArr(x)) thrM("reshaping non-array");
|
||||
usz ia = a(x)->ia;
|
||||
if (reusable(x)) {
|
||||
decSh(x);
|
||||
arr_shVec(x, ia);
|
||||
return x;
|
||||
}
|
||||
B r = TI(x).slice(x, 0);
|
||||
arr_shVec(r, ia);
|
||||
return r;
|
||||
}
|
||||
B shape_c2(B t, B w, B x) {
|
||||
if (isArr(x)) {
|
||||
if (!isArr(w)) return shape_c1(t, x);
|
||||
BS2B wget = TI(w).get;
|
||||
ur nr = a(w)->ia;
|
||||
usz nia = a(x)->ia;
|
||||
B r;
|
||||
if (reusable(x)) { r = x; decSh(x); }
|
||||
else r = TI(x).slice(x, 0);
|
||||
usz* sh = arr_shAlloc(r, nia, nr);
|
||||
if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i));
|
||||
dec(w);
|
||||
return r;
|
||||
} else return err("reshaping non-array");
|
||||
if (!isArr(x)) { dec(x); dec(w); thrM("reshaping non-array"); }
|
||||
if (!isArr(w)) return shape_c1(t, x);
|
||||
BS2B wget = TI(w).get;
|
||||
ur nr = a(w)->ia;
|
||||
usz nia = a(x)->ia;
|
||||
B r;
|
||||
if (reusable(x)) { r = x; decSh(x); }
|
||||
else r = TI(x).slice(x, 0);
|
||||
usz* sh = arr_shAlloc(r, nia, nr);
|
||||
if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i));
|
||||
dec(w);
|
||||
return r;
|
||||
}
|
||||
|
||||
B pick_c1(B t, B x) {
|
||||
if (!isArr(x)) return x;
|
||||
if (a(x)->ia==0) {
|
||||
B r = getFill(x);
|
||||
if (r.u==bi_noFill.u) return err("⊑: called on empty array without fill");
|
||||
if (noFill(r)) thrM("⊑: called on empty array without fill");
|
||||
return r;
|
||||
}
|
||||
B r = TI(x).get(x, 0);
|
||||
@ -42,13 +40,11 @@ B pick_c1(B t, B x) {
|
||||
}
|
||||
B pick_c2(B t, B w, B x) {
|
||||
usz wu = o2s(w);
|
||||
if (isArr(x)) {
|
||||
// if (wu >= a(x)->ia) err("⊑: 𝕨 is greater than length of 𝕩"); // no bounds check for now
|
||||
B r = TI(x).get(x, wu);
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
dec(x); return err("n⊑atom");
|
||||
if (!isArr(x)) { dec(x); dec(w); thrM("⊑: 𝕩 wasn't an array"); }
|
||||
// if (wu >= a(x)->ia) err("⊑: 𝕨 is greater than length of 𝕩"); // no bounds check for now
|
||||
B r = TI(x).get(x, wu);
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
|
||||
B ud_c1(B t, B x) {
|
||||
@ -103,7 +99,7 @@ B fmtN_c1(B t, B x) {
|
||||
B fmtF_c1(B t, B x) {
|
||||
if (!isVal(x)) return m_str32(U"(fmtF: not given a function)");
|
||||
u8 fl = v(x)->flags;
|
||||
if (fl==0 || fl>=62) return m_str32(U"(fmtF: not given a runtime primitive)");
|
||||
if (fl==0 || fl>=rtLen) return m_str32(U"(fmtF: not given a runtime primitive)");
|
||||
dec(x);
|
||||
return m_c32(U"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜˘¨⌜⁼´˝`∘○⊸⟜⌾⊘◶⎉⚇⍟"[fl-1]);
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ B type_c1(B t, B x) {
|
||||
else if (isFun(x)) r = 3;
|
||||
else if (isMd1(x)) r = 4;
|
||||
else if (isMd2(x)) r = 5;
|
||||
decR(x);
|
||||
if (r==-1) return err("getting type");
|
||||
decR(x);
|
||||
return m_i32(r);
|
||||
}
|
||||
|
||||
@ -33,12 +33,14 @@ B glyph_c1(B t, B x) {
|
||||
}
|
||||
|
||||
B fill_c1(B t, B x) {
|
||||
return getFill(x);
|
||||
B f = getFill(x);
|
||||
if (noFill(f)) return m_f64(0); // thrM("No fill found");
|
||||
return f;
|
||||
}
|
||||
B fill_c2(B t, B w, B x) { // TODO not set fill for typed arrays
|
||||
if (isArr(x)) {
|
||||
B fill = asFill(w);
|
||||
if (fill.u == bi_noFill.u) { dec(fill); return x; }
|
||||
if (noFill(fill)) return x;
|
||||
return withFill(x, fill);
|
||||
}
|
||||
dec(w);
|
||||
|
||||
@ -20,10 +20,11 @@ B fromUTF8(char* s, u64 len) {
|
||||
u64 j;
|
||||
for (j = 0; j < len; j+= utf8_len(s[j])) sz++;
|
||||
if (j!=len) return err("invalid UTF-8");
|
||||
HArr_p r = m_harrv(sz);
|
||||
B r = m_c32arrv(sz);
|
||||
u32* rp = c32arr_ptr(r);
|
||||
u64 p = 0;
|
||||
for (u64 i = 0; i < len; i+= utf8_len(s[i])) r.a[p++] = m_c32(utf8_p((u8*)s+i)); // may read after end, eh
|
||||
return r.b;
|
||||
for (u64 i = 0; i < len; i+= utf8_len(s[i])) rp[p++] = utf8_p((u8*)s+i); // may read after end, eh
|
||||
return r;
|
||||
}
|
||||
|
||||
void printUTF8(u32 c) {
|
||||
|
||||
11
src/vm.c
11
src/vm.c
@ -265,7 +265,7 @@ void allocStack(u64 am) {
|
||||
u64 left = gStackEnd-gStack;
|
||||
if (am>left) {
|
||||
u64 n = gStackEnd-gStackStart + am + 500;
|
||||
u64 d = gStackStart-gStack;
|
||||
u64 d = gStack-gStackStart;
|
||||
gStackStart = realloc(gStackStart, n*sizeof(B));
|
||||
gStack = gStackStart+d;
|
||||
gStackEnd = gStackStart+n;
|
||||
@ -534,7 +534,7 @@ jmp_buf* prepareCatch() { // in the case of returning false, must call popCatch(
|
||||
if (cf==cfEnd) {
|
||||
u64 n = cfEnd-cfStart;
|
||||
n = n<8? 8 : n*2;
|
||||
u64 d = cfStart-cf;
|
||||
u64 d = cf-cfStart;
|
||||
cfStart = realloc(cfStart, n*sizeof(CatchFrame));
|
||||
cf = cfStart+d;
|
||||
cfEnd = cfStart+n;
|
||||
@ -556,13 +556,12 @@ void thr(B msg) {
|
||||
cf--;
|
||||
|
||||
B* gStackNew = gStackStart + cf->gStackDepth;
|
||||
if (gStackNew>gStack) err("bad catch gStack");
|
||||
if (gStackNew>gStack) err("bad catch gStackDepth");
|
||||
while (gStack!=gStackNew) dec(*--gStack);
|
||||
// gStack = gStackNew;
|
||||
|
||||
cf = cfStart + cf->cfDepth;
|
||||
if (cfStart+cf->cfDepth > cf) err("bad catch cfDepth");
|
||||
cf = cfStart+cf->cfDepth;
|
||||
longjmp(cf->jmp, 1);
|
||||
printf("wat\n");
|
||||
}
|
||||
assert(cf==cfStart);
|
||||
printf("Error: ");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user