•args, •FLines, command-line options, •Repr, fix unit∾unit fill
This commit is contained in:
parent
915b84f028
commit
c2013e3b5d
17
cc.bqn
17
cc.bqn
@ -7,8 +7,8 @@ return ← 1≡⊑args
|
||||
args↓˜↩ return
|
||||
path←(⊑args)∾"/src/"
|
||||
args↓˜↩1
|
||||
L ← {"m_caB(" ∾(⍕≠𝕩)∾",(B[]){" ∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||
LI ← {"m_cai32("∾(⍕≠𝕩)∾",(i32[]){"∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||
L ← {"m_caB(" ∾(•Repr≠𝕩)∾",(B[]){" ∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||
LI ← {"m_cai32("∾(•Repr≠𝕩)∾",(i32[]){"∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||
# Escape the special characters that appear in BQN sources.
|
||||
Esc←{
|
||||
in ← (@+0‿9‿10‿13)∾"'""" # Null, Tab, LF, CR, and quotes
|
||||
@ -19,9 +19,9 @@ Esc←{
|
||||
}
|
||||
Str ← "m_str32(U"""∾Esc∾""")"˙ # A BQN string
|
||||
Char ← {"m_c32(U'"∾(Esc⥊𝕩)∾"')"} # A BQN character
|
||||
Num ← {s←"-"/˜𝕩<0 ⋄ ∞⊸=∘|◶⟨"m_f64("∾")"∾˜s∾⍕∘| ⋄ "m_f64("∾s∾"1.0/0.0)"⟩𝕩} # Format number
|
||||
Num ← {s←"-"/˜𝕩<0 ⋄ ∞⊸=∘|◶⟨"m_f64("∾")"∾˜s∾•Repr∘| ⋄ "m_f64("∾s∾"1.0/0.0)"⟩𝕩} # Format number
|
||||
|
||||
F ← ⍕ # Format number
|
||||
F ← •Repr # Format number
|
||||
|
||||
Import ← {𝕨•Import path∾𝕩}
|
||||
FChars ← {𝕨•FChars path∾𝕩}
|
||||
@ -30,12 +30,13 @@ FLines ← {𝕨•FLines path∾𝕩}
|
||||
glyphs ← Import "glyphs.bqn"
|
||||
_getComp ← { (3+useInd) ↑ (𝕗 Import "c.bqn"){𝔽} }
|
||||
useInd ← "-i"≡⊑args ⋄ args↓˜↩useInd
|
||||
Comp ← ((<"inc(runtime["∾⍕∾"])"˙)¨↕62) glyphs _getComp ⊢
|
||||
J ← ∾∾⟜\n¨
|
||||
Comp ← ((<"inc(runtime["∾•Repr∾"])"˙)¨↕62) glyphs _getComp ⊢
|
||||
J ← ∾∾⟜(@+10)¨
|
||||
Fconst ← ≡◶⟨@⊸≤◶Num‿Char, Str, ⊑⟩
|
||||
Fout ← {((≠𝕩)↑⟨LI F¨,L Fconst¨,L (LI ·F¨ 4↑⊢)¨,L (L F¨)¨⟩) {𝕎𝕩}¨ 𝕩}
|
||||
Frun ← 1⊸Fout
|
||||
Long ← {¯2↓∾𝕩∾¨<","∾\n}
|
||||
Long ← {¯2↓∾𝕩∾¨<","∾@+10}
|
||||
LFC ← Long∘Fout∘Comp
|
||||
|
||||
RT ← {
|
||||
src‿need‿inputs←𝕩Import"pr.bqn"
|
||||
@ -43,7 +44,7 @@ RT ← {
|
||||
Long Fout pr need _getComp src
|
||||
}
|
||||
CArg ← {J (¯5⊸↓∾𝕩˙)⌾⊑ FLines "c.bqn"}
|
||||
LFC ← Long∘Fout∘Comp
|
||||
SVG ← {∾⟨"Modify←GetHighlights←⊢⋄"⟩∾ FChars∘∾⟜".bqn"¨ "../svg"‿𝕩}
|
||||
|
||||
•Out⍟(¬return) (⊑"r"‿"r0"‿"r1"‿"c"‿"cc"‿"f"‿"e"‿"p"⊐⊏)◶⟨
|
||||
RT∘2, RT∘0, RT∘1
|
||||
|
||||
@ -6,11 +6,7 @@ typedef struct FillArr {
|
||||
B a[];
|
||||
} FillArr;
|
||||
|
||||
B getFillQ(B x) { // doesn't consume; can return bi_noFill
|
||||
bool defZero = true;
|
||||
#ifdef CATCH_ERRORS
|
||||
defZero = false;
|
||||
#endif
|
||||
B getFillR(B x) { // doesn't consume; can return bi_noFill
|
||||
if (isArr(x)) {
|
||||
u8 t = v(x)->type;
|
||||
if (t==t_fillarr ) { B r = inc(c(FillArr,x )->fill); return r; }
|
||||
@ -18,12 +14,18 @@ B getFillQ(B x) { // doesn't consume; can return bi_noFill
|
||||
if (t==t_c32arr || t==t_c32slice) return m_c32(' ');
|
||||
if (t==t_i32arr || t==t_i32slice) return m_f64(0 );
|
||||
if (t==t_f64arr || t==t_f64slice) return m_f64(0 );
|
||||
return defZero? m_f64(0) : bi_noFill;
|
||||
return bi_noFill;
|
||||
}
|
||||
if (isF64(x)|isI32(x)) return m_i32(0);
|
||||
if (isC32(x)) return m_c32(' ');
|
||||
|
||||
return defZero? m_f64(0) : bi_noFill;
|
||||
return bi_noFill;
|
||||
}
|
||||
B getFillQ(B x) { // doesn't consume; can return bi_noFill if CATCH_ERRORS
|
||||
B r = getFillR(x);
|
||||
#ifdef CATCH_ERRORS
|
||||
return r;
|
||||
#endif
|
||||
return noFill(r)? m_f64(0) : r;
|
||||
}
|
||||
B getFillE(B x) { // errors if there's no fill
|
||||
B xf = getFillQ(x);
|
||||
|
||||
@ -81,13 +81,6 @@ B ltack_c2(B t, B w, B x) { dec(x); return w; }
|
||||
B rtack_c1(B t, B x) { return x; }
|
||||
B rtack_c2(B t, B w, B x) { dec(w); return x; }
|
||||
|
||||
B fmtN_c1(B t, B x) {
|
||||
#define BL 100
|
||||
char buf[BL];
|
||||
if (isF64(x)) snprintf(buf, BL, "%g", x.f);
|
||||
else snprintf(buf, BL, "(fmtN: not given a number?)");
|
||||
return m_str8(strlen(buf), buf);
|
||||
}
|
||||
B fmtF_c1(B t, B x) {
|
||||
if (!isVal(x)) return m_str32(U"(fmtF: not given a function)");
|
||||
u8 fl = v(x)->flags;
|
||||
@ -180,7 +173,7 @@ B fne_c2(B t, B w, B x) {
|
||||
#define BI_FNS1(F) F(BI_A,BI_M,BI_D)
|
||||
|
||||
|
||||
#define F(A,M,D) A(ud) A(fne) A(feq) A(ltack) A(rtack) M(fmtF) M(fmtN)
|
||||
#define F(A,M,D) A(ud) A(fne) A(feq) A(ltack) A(rtack) M(fmtF)
|
||||
BI_FNS0(F);
|
||||
static inline void fns_init() { BI_FNS1(F)
|
||||
ti[t_funBI].print = print_funBI;
|
||||
|
||||
12
src/h.h
12
src/h.h
@ -123,11 +123,11 @@ char* format_type(u8 u) {
|
||||
#define FOR_PF(F) F(none, "(unknown fn)") \
|
||||
/*arith.c*/ F(add,"+") F(sub,"-") F(mul,"×") F(div,"÷") F(pow,"⋆") F(floor,"⌊") F(ceil,"⌈") F(stile,"|") F(eq,"=") \
|
||||
/*arith.c*/ F(ne,"≠") F(le,"≤") F(ge,"≥") F(lt,"<") F(gt,">") F(and,"∧") F(or,"∨") F(not,"¬") F(log,"⋆⁼") \
|
||||
/*fns.c*/ F(ud,"↕") F(fne,"≢") F(feq,"≡") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"•FmtF") F(fmtN,"•FmtN") \
|
||||
/*fns.c*/ F(ud,"↕") F(fne,"≢") F(feq,"≡") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"•FmtF") \
|
||||
/*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(couple,"≍") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") F(group,"⊔") \
|
||||
/*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \
|
||||
/*sort.c*/ F(gradeUp,"⍋") \
|
||||
/*sysfn.c*/ F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(fill,"•FillFn") \
|
||||
/*sysfn.c*/ F(type,"•Type") F(decp,"•Decompose") F(primInd,"•PrimInd") F(glyph,"•Glyph") F(repr,"•Repr") F(fill,"•FillFn") \
|
||||
/*sysfn.c*/ F(grLen,"•GroupLen") F(grOrd,"•groupOrd") F(asrt,"!") F(sys,"•getsys") F(bqn,"•BQN") F(cmp,"•Cmp") F(internal,"•Internal") F(show,"•Show") F(out,"•Out") \
|
||||
|
||||
enum PrimFns {
|
||||
@ -145,13 +145,13 @@ char* format_pf(u8 u) {
|
||||
enum PrimMd1 {
|
||||
pm1_none,
|
||||
pm1_tbl, pm1_each, pm1_fold, pm1_scan, pm1_const, pm1_swap, pm1_timed, // md1.c
|
||||
pm1_fchars, pm1_fbytes, pm1_import, // md1.c
|
||||
pm1_fchars, pm1_fbytes, pm1_flines, pm1_import, // md1.c
|
||||
};
|
||||
char* format_pm1(u8 u) {
|
||||
switch(u) {
|
||||
default: case pf_none: return"(unknown 1-modifier)";
|
||||
case pm1_tbl:return"⌜"; case pm1_each:return"¨"; case pm1_fold:return"´"; case pm1_scan:return"`"; case pm1_const:return"˙"; case pm1_swap:return"˜"; case pm1_timed:return"•_timed";
|
||||
case pm1_fchars:return"•FChars"; case pm1_fbytes:return"•FBytes"; case pm1_import:return"•Import";
|
||||
case pm1_fchars:return"•FChars"; case pm1_fbytes:return"•FBytes"; case pm1_flines:return"•FLines"; case pm1_import:return"•Import";
|
||||
}
|
||||
}
|
||||
enum PrimMd2 {
|
||||
@ -258,8 +258,8 @@ B m_unit (B x); // consumes
|
||||
B m_hunit(B x); // consumes
|
||||
B m_str32(u32* s); // meant to be used as m_str32(U"{𝕨‿𝕩}"), so doesn't free for you
|
||||
|
||||
B bqn_exec(B str, B path); // consumes both
|
||||
B bqn_execFile(B path); // consumes
|
||||
B bqn_exec(B str, B path, B args); // consumes both
|
||||
B bqn_execFile(B path, B args); // consumes
|
||||
|
||||
NOINLINE NORETURN void thr(B b);
|
||||
NOINLINE NORETURN void thrM(char* s);
|
||||
|
||||
22
src/load.c
22
src/load.c
@ -23,17 +23,22 @@ B bqn_fmt(B x) { // consumes
|
||||
}
|
||||
#endif
|
||||
|
||||
void load_gcFn() { mm_visit(comp_currPath); }
|
||||
Block* bqn_comp(B str, B path) { // consumes both
|
||||
void load_gcFn() {
|
||||
mm_visit(comp_currPath);
|
||||
mm_visit(comp_currArgs);
|
||||
}
|
||||
|
||||
Block* bqn_comp(B str, B path, B args) { // consumes all
|
||||
comp_currPath = path;
|
||||
comp_currArgs = args;
|
||||
Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str);
|
||||
dec(path);
|
||||
comp_currPath = bi_N;
|
||||
dec(path); dec(args);
|
||||
comp_currArgs = comp_currPath = bi_N;
|
||||
return r;
|
||||
}
|
||||
|
||||
B bqn_exec(B str, B path) { // consumes both
|
||||
Block* block = bqn_comp(str, path);
|
||||
B bqn_exec(B str, B path, B args) { // consumes all
|
||||
Block* block = bqn_comp(str, path, args);
|
||||
B res = m_funBlock(block, 0);
|
||||
ptr_dec(block);
|
||||
return res;
|
||||
@ -45,6 +50,7 @@ void bqn_setComp(B comp) { // consumes; doesn't unload old comp, but whatever
|
||||
|
||||
static inline void load_init() {
|
||||
comp_currPath = bi_N;
|
||||
comp_currArgs = bi_N;
|
||||
gc_addFn(load_gcFn);
|
||||
B fruntime[] = {
|
||||
/* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil, bi_stile , bi_not,
|
||||
@ -161,6 +167,6 @@ static inline void load_init() {
|
||||
#endif // NO_COMP
|
||||
}
|
||||
|
||||
B bqn_execFile(B path) { // consumes
|
||||
return bqn_exec(file_chars(inc(path)), path);
|
||||
B bqn_execFile(B path, B args) { // consumes both
|
||||
return bqn_exec(file_chars(inc(path)), path, args);
|
||||
}
|
||||
|
||||
77
src/main.c
77
src/main.c
@ -81,8 +81,77 @@ int main(int argc, char* argv[]) {
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc==1) {
|
||||
bool startREPL = argc==1;
|
||||
if (!startREPL) {
|
||||
i32 i = 1;
|
||||
while (i!=argc) {
|
||||
char* carg = argv[i];
|
||||
if (carg[0]!='-') break;
|
||||
i++;
|
||||
if (carg[1]=='-') {
|
||||
if (!strcmp(carg, "--help")) {
|
||||
printf(
|
||||
"Usage: %s [options] [file.bqn [arguments]]\n"
|
||||
"Options:\n"
|
||||
"-f file: execute the contents of the file with all further arguments as •args\n"
|
||||
"-e code: execute the argument as BQN\n"
|
||||
"-p code: execute the argument as BQN and print its result pretty-printed\n"
|
||||
"-o code: execute the argument as BQN and print its raw result\n"
|
||||
"-r : start the REPL after all further arguments\n"
|
||||
, argv[0]);
|
||||
exit(0);
|
||||
} else {
|
||||
printf("%s: Unknown option: %s\n", argv[0], carg);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
carg++;
|
||||
char c;
|
||||
while ((c=*carg++) != '\0') {
|
||||
switch(c) { default: printf("Unknown option: -%c\n", c);
|
||||
#define REQARG(X) if(*carg) { printf("%s: -%s must end the option\n", argv[0], #X); exit(1); } if (i==argc) { printf("%s: -%s requires an argument\n", argv[0], #X); exit(1); }
|
||||
case 'f': REQARG(f); goto execFile;
|
||||
case 'e': { REQARG(e);
|
||||
dec(bqn_exec(fromUTF8l(argv[i++]), m_str32(U"-e"), inc(bi_emptyHVec)));
|
||||
break;
|
||||
}
|
||||
case 'p': { REQARG(p);
|
||||
B r = bqn_exec(fromUTF8l(argv[i++]), m_str32(U"-e"), inc(bi_emptyHVec));
|
||||
print(r); dec(r);
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
case 'o': { REQARG(o);
|
||||
B r = bqn_exec(fromUTF8l(argv[i++]), m_str32(U"-e"), inc(bi_emptyHVec));
|
||||
printRaw(r); dec(r);
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
startREPL = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
execFile:
|
||||
if (i!=argc) {
|
||||
B src = fromUTF8l(argv[i++]);
|
||||
B args;
|
||||
if (i==argc) {
|
||||
args = inc(bi_emptyHVec);
|
||||
} else {
|
||||
HArr_p ap = m_harrUv(argc-i); // eh whatever, erroring will exit anyways
|
||||
for (usz j = 0; j < argc-i; j++) {
|
||||
ap.a[j] = fromUTF8l(argv[i+j]);
|
||||
}
|
||||
args = ap.b;
|
||||
}
|
||||
dec(bqn_execFile(src, args));
|
||||
}
|
||||
}
|
||||
if (startREPL) {
|
||||
while (CATCH) {
|
||||
printf("Error: "); print(catchMessage); putchar('\n');
|
||||
vm_pst(envCurr, envStart+envPrevHeight);
|
||||
@ -94,7 +163,7 @@ int main(int argc, char* argv[]) {
|
||||
size_t gl = 0;
|
||||
getline(&ln, &gl, stdin);
|
||||
if (ln[0]==0 || ln[0]==10) break;
|
||||
Block* block = bqn_comp(fromUTF8(ln, strlen(ln)), inc(replPath));
|
||||
Block* block = bqn_comp(fromUTF8(ln, strlen(ln)), inc(replPath), inc(bi_emptyHVec));
|
||||
free(ln);
|
||||
|
||||
#ifdef TIME
|
||||
@ -124,8 +193,6 @@ int main(int argc, char* argv[]) {
|
||||
#endif
|
||||
}
|
||||
popCatch();
|
||||
} else {
|
||||
bqn_execFile(fromUTF8l(argv[1]));
|
||||
}
|
||||
rtPerf_print();
|
||||
CTR_FOR(CTR_PRINT)
|
||||
|
||||
36
src/md1.c
36
src/md1.c
@ -215,14 +215,42 @@ B fchars_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
return file_chars(path_resolve(f, x));
|
||||
}
|
||||
B fbytes_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
TmpFile* tf = file_bytes(path_resolve(f, x)); usz ia = tf->ia; u8* p = (u8*)tf->a;
|
||||
TmpFile* tf = file_bytes(path_resolve(f, x));
|
||||
usz ia = tf->ia; u8* p = (u8*)tf->a;
|
||||
u32* rp; B r = m_c32arrv(&rp, ia);
|
||||
for (i64 i = 0; i < ia; i++) rp[i] = p[i];
|
||||
ptr_dec(tf);
|
||||
return r;
|
||||
}
|
||||
B flines_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
TmpFile* tf = file_bytes(path_resolve(f, x));
|
||||
usz ia = tf->ia; u8* p = (u8*)tf->a;
|
||||
usz lineCount = 0;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
if (p[i]=='\n') lineCount++;
|
||||
else if (p[i]=='\r') {
|
||||
lineCount++;
|
||||
if(i+1<ia && p[i+1]=='\n') i++;
|
||||
}
|
||||
}
|
||||
if (ia && (p[ia-1]!='\n' && p[ia-1]!='\r')) lineCount++;
|
||||
usz i = 0;
|
||||
HArr_p r = m_harrs(lineCount, &i);
|
||||
usz pos = 0;
|
||||
while (i < lineCount) {
|
||||
usz spos = pos;
|
||||
while(p[pos]!='\n' && p[pos]!='\r') pos++;
|
||||
r.a[i++] = fromUTF8((char*)p+spos, pos-spos);
|
||||
if (p[pos]=='\r' && pos+1<ia && p[pos+1]=='\n') pos+= 2;
|
||||
else pos++;
|
||||
}
|
||||
return harr_fv(r);
|
||||
}
|
||||
B import_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
return bqn_execFile(path_resolve(f, x));
|
||||
return bqn_execFile(path_resolve(f, x), inc(bi_emptyHVec));
|
||||
}
|
||||
B import_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
return bqn_execFile(path_resolve(f, x), w);
|
||||
}
|
||||
|
||||
#define ba(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = NAME##_c1 ; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
|
||||
@ -231,8 +259,8 @@ B import_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
|
||||
void print_md1BI(B x) { printf("%s", format_pm1(c(Md1,x)->extra)); }
|
||||
|
||||
B bi_tbl, bi_each, bi_fold, bi_scan, bi_const, bi_swap, bi_timed, bi_fchars, bi_fbytes, bi_import;
|
||||
static inline void md1_init() { ba(tbl) ba(each) ba(fold) ba(scan) ba(const) ba(swap) ba(timed) bm(fchars) bm(fbytes) bm(import)
|
||||
B bi_tbl, bi_each, bi_fold, bi_scan, bi_const, bi_swap, bi_timed, bi_fchars, bi_fbytes, bi_flines, bi_import;
|
||||
static inline void md1_init() { ba(tbl) ba(each) ba(fold) ba(scan) ba(const) ba(swap) ba(timed) bm(fchars) bm(fbytes) bm(flines) ba(import)
|
||||
ti[t_md1BI].print = print_md1BI;
|
||||
}
|
||||
|
||||
|
||||
17
src/sfns.c
17
src/sfns.c
@ -430,8 +430,19 @@ B join_c1(B t, B x) {
|
||||
if (rnk(x)==1) {
|
||||
usz xia = a(x)->ia;
|
||||
if (xia==0) {
|
||||
B xf = getFillE(x); dec(x);
|
||||
if (isAtm(xf)) thrM("∾: Empty vector 𝕩 cannot have an atom fill element");
|
||||
B xf = getFillE(x);
|
||||
if (isAtm(xf)) {
|
||||
decR(xf);
|
||||
if (!PROPER_FILLS) {
|
||||
B xfq = getFillR(x);
|
||||
bool no = noFill(xfq);
|
||||
decR(xfq);
|
||||
if (no) return x;
|
||||
}
|
||||
dec(x);
|
||||
thrM("∾: Empty vector 𝕩 cannot have an atom fill element");
|
||||
}
|
||||
dec(x);
|
||||
ur ir = rnk(xf);
|
||||
if (ir==0) thrM("∾: Empty vector 𝕩 cannot have a unit fill element");
|
||||
B xff = getFillQ(xf);
|
||||
@ -493,7 +504,7 @@ B join_c2(B t, B w, B x) {
|
||||
HArr_p r = m_harrUv(2);
|
||||
r.a[0] = TI(w).get(w,0); dec(w);
|
||||
r.a[1] = TI(x).get(x,0); dec(x);
|
||||
return r.b;
|
||||
return withFill(r.b, f);
|
||||
}
|
||||
if (c-wr > 1 || c-xr > 1) thrM("∾: Argument ranks must differ by 1 or less");
|
||||
MAKE_MUT(r, wia+xia);
|
||||
|
||||
@ -365,6 +365,7 @@ void printAllocStats() {
|
||||
}
|
||||
|
||||
_Thread_local B comp_currPath;
|
||||
_Thread_local B comp_currArgs;
|
||||
#define FOR_INIT(F) F(hdr) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(fns) F(sfns) F(arith) F(grade) F(md1) F(md2) F(sysfn) F(derv) F(comp) F(rtPerf) F(ns) F(load)
|
||||
#define F(X) static inline void X##_init();
|
||||
FOR_INIT(F)
|
||||
|
||||
21
src/sysfn.c
21
src/sysfn.c
@ -32,6 +32,14 @@ B glyph_c1(B t, B x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
B repr_c1(B t, B x) {
|
||||
#define BL 100
|
||||
char buf[BL];
|
||||
if (isF64(x)) snprintf(buf, BL, "%g", x.f);
|
||||
else snprintf(buf, BL, "(fmtN: not given a number?)");
|
||||
return m_str8(strlen(buf), buf);
|
||||
}
|
||||
|
||||
B fill_c1(B t, B x) {
|
||||
B r = getFillE(x);
|
||||
dec(x);
|
||||
@ -137,7 +145,7 @@ B bqn_c1(B t, B x) {
|
||||
BS2B xgetU = TI(x).getU;
|
||||
for (usz i = 0; i < ia; i++) if (!isC32(xgetU(x,i))) thrM("•BQN: Argument must be a character vector");
|
||||
}
|
||||
return bqn_exec(x, bi_N);
|
||||
return bqn_exec(x, bi_N, bi_N);
|
||||
}
|
||||
|
||||
B cmp_c2(B t, B w, B x) {
|
||||
@ -147,7 +155,7 @@ B cmp_c2(B t, B w, B x) {
|
||||
}
|
||||
|
||||
|
||||
#define F(A,M,D) M(type) M(decp) M(primInd) M(glyph) A(fill) A(grLen) D(grOrd) A(asrt) M(out) M(show) M(sys) M(bqn) D(cmp) D(internal)
|
||||
#define F(A,M,D) M(type) M(decp) M(primInd) M(glyph) M(repr) A(fill) A(grLen) D(grOrd) A(asrt) M(out) M(show) M(sys) M(bqn) D(cmp) D(internal)
|
||||
BI_FNS0(F);
|
||||
static inline void sysfn_init() { BI_FNS1(F) }
|
||||
#undef F
|
||||
@ -156,7 +164,7 @@ static B makeRel(B md) { // doesn't consume
|
||||
return m1_d(inc(md), path_dir(inc(comp_currPath)));
|
||||
}
|
||||
|
||||
B bi_timed, bi_fchars, bi_fbytes, bi_import;
|
||||
B bi_timed, bi_fchars, bi_fbytes, bi_flines, bi_import;
|
||||
B sys_c1(B t, B x) {
|
||||
assert(isArr(x));
|
||||
usz i = 0;
|
||||
@ -173,10 +181,15 @@ B sys_c1(B t, B x) {
|
||||
else if (eqStr(c, U"bqn")) r.a[i] = inc(bi_bqn);
|
||||
else if (eqStr(c, U"cmp")) r.a[i] = inc(bi_cmp);
|
||||
else if (eqStr(c, U"timed")) r.a[i] = inc(bi_timed);
|
||||
else if (eqStr(c, U"repr")) r.a[i] = inc(bi_repr);
|
||||
else if (eqStr(c, U"fchars")) r.a[i] = makeRel(bi_fchars);
|
||||
else if (eqStr(c, U"fbytes")) r.a[i] = makeRel(bi_fbytes);
|
||||
else if (eqStr(c, U"flines")) r.a[i] = makeRel(bi_flines);
|
||||
else if (eqStr(c, U"import")) r.a[i] = makeRel(bi_import);
|
||||
else { dec(x); thrM("Unknown system function"); }
|
||||
else if (eqStr(c, U"args")) {
|
||||
if(isNothing(comp_currArgs)) thrM("No arguments present for •args");
|
||||
r.a[i] = inc(comp_currArgs);
|
||||
} else { dec(x); thrM("Unknown system function"); }
|
||||
}
|
||||
return harr_fcd(r, x);
|
||||
}
|
||||
|
||||
85
src/vm.c
85
src/vm.c
@ -685,46 +685,6 @@ void popCatch() {
|
||||
#endif
|
||||
}
|
||||
|
||||
NOINLINE NORETURN void thr(B msg) {
|
||||
if (cf>cfStart) {
|
||||
catchMessage = msg;
|
||||
cf--;
|
||||
|
||||
B* gStackNew = gStackStart + cf->gsDepth;
|
||||
assert(gStackNew<=gStack);
|
||||
while (gStack!=gStackNew) dec(*--gStack);
|
||||
envPrevHeight = envCurr-envStart;
|
||||
Env* envNew = envStart + cf->envDepth;
|
||||
assert(envNew<=envCurr);
|
||||
while (envCurr!=envNew) {
|
||||
envCurr--;
|
||||
#if VM_POS
|
||||
envCurr->bcV = *envCurr->bcP - i32arr_ptr(envCurr->sc->body->comp->bc) - 1;
|
||||
#else
|
||||
envCurr->bcV = envCurr->bcL - i32arr_ptr(envCurr->sc->body->comp->bc);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cfStart+cf->cfDepth > cf) err("bad catch cfDepth");
|
||||
cf = cfStart+cf->cfDepth;
|
||||
longjmp(cf->jmp, 1);
|
||||
}
|
||||
assert(cf==cfStart);
|
||||
printf("Error: ");
|
||||
print(msg);
|
||||
puts("");
|
||||
#ifdef DEBUG
|
||||
__builtin_trap();
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
NOINLINE NORETURN void thrM(char* s) {
|
||||
thr(fromUTF8(s, strlen(s)));
|
||||
}
|
||||
NOINLINE NORETURN void thrOOM() { thrM("Out of memory"); }
|
||||
|
||||
|
||||
NOINLINE void vm_pst(Env* s, Env* e) {
|
||||
assert(s<=e);
|
||||
@ -763,3 +723,48 @@ NOINLINE void vm_pst(Env* s, Env* e) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
static void unwindEnv(Env* envNew) {
|
||||
assert(envNew<=envCurr);
|
||||
while (envCurr!=envNew) {
|
||||
envCurr--;
|
||||
#if VM_POS
|
||||
envCurr->bcV = *envCurr->bcP - i32arr_ptr(envCurr->sc->body->comp->bc) - 1;
|
||||
#else
|
||||
envCurr->bcV = envCurr->bcL - i32arr_ptr(envCurr->sc->body->comp->bc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
NOINLINE NORETURN void thr(B msg) {
|
||||
if (cf>cfStart) {
|
||||
catchMessage = msg;
|
||||
cf--;
|
||||
|
||||
B* gStackNew = gStackStart + cf->gsDepth;
|
||||
assert(gStackNew<=gStack);
|
||||
while (gStack!=gStackNew) dec(*--gStack);
|
||||
envPrevHeight = envCurr-envStart;
|
||||
unwindEnv(envStart + cf->envDepth);
|
||||
|
||||
|
||||
if (cfStart+cf->cfDepth > cf) err("bad catch cfDepth");
|
||||
cf = cfStart+cf->cfDepth;
|
||||
longjmp(cf->jmp, 1);
|
||||
}
|
||||
assert(cf==cfStart);
|
||||
printf("Error: "); print(msg); putchar('\n');
|
||||
Env* envPrev = envCurr;
|
||||
unwindEnv(envStart);
|
||||
vm_pst(envCurr, envPrev);
|
||||
#ifdef DEBUG
|
||||
__builtin_trap();
|
||||
#else
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
NOINLINE NORETURN void thrM(char* s) {
|
||||
thr(fromUTF8(s, strlen(s)));
|
||||
}
|
||||
NOINLINE NORETURN void thrOOM() { thrM("Out of memory"); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user