•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
|
args↓˜↩ return
|
||||||
path←(⊑args)∾"/src/"
|
path←(⊑args)∾"/src/"
|
||||||
args↓˜↩1
|
args↓˜↩1
|
||||||
L ← {"m_caB(" ∾(⍕≠𝕩)∾",(B[]){" ∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
L ← {"m_caB(" ∾(•Repr≠𝕩)∾",(B[]){" ∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||||
LI ← {"m_cai32("∾(⍕≠𝕩)∾",(i32[]){"∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
LI ← {"m_cai32("∾(•Repr≠𝕩)∾",(i32[]){"∾(1↓∾","⊸∾¨𝕩)∾"})"}
|
||||||
# Escape the special characters that appear in BQN sources.
|
# Escape the special characters that appear in BQN sources.
|
||||||
Esc←{
|
Esc←{
|
||||||
in ← (@+0‿9‿10‿13)∾"'""" # Null, Tab, LF, CR, and quotes
|
in ← (@+0‿9‿10‿13)∾"'""" # Null, Tab, LF, CR, and quotes
|
||||||
@ -19,9 +19,9 @@ Esc←{
|
|||||||
}
|
}
|
||||||
Str ← "m_str32(U"""∾Esc∾""")"˙ # A BQN string
|
Str ← "m_str32(U"""∾Esc∾""")"˙ # A BQN string
|
||||||
Char ← {"m_c32(U'"∾(Esc⥊𝕩)∾"')"} # A BQN character
|
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∾𝕩}
|
Import ← {𝕨•Import path∾𝕩}
|
||||||
FChars ← {𝕨•FChars path∾𝕩}
|
FChars ← {𝕨•FChars path∾𝕩}
|
||||||
@ -30,12 +30,13 @@ FLines ← {𝕨•FLines path∾𝕩}
|
|||||||
glyphs ← Import "glyphs.bqn"
|
glyphs ← Import "glyphs.bqn"
|
||||||
_getComp ← { (3+useInd) ↑ (𝕗 Import "c.bqn"){𝔽} }
|
_getComp ← { (3+useInd) ↑ (𝕗 Import "c.bqn"){𝔽} }
|
||||||
useInd ← "-i"≡⊑args ⋄ args↓˜↩useInd
|
useInd ← "-i"≡⊑args ⋄ args↓˜↩useInd
|
||||||
Comp ← ((<"inc(runtime["∾⍕∾"])"˙)¨↕62) glyphs _getComp ⊢
|
Comp ← ((<"inc(runtime["∾•Repr∾"])"˙)¨↕62) glyphs _getComp ⊢
|
||||||
J ← ∾∾⟜\n¨
|
J ← ∾∾⟜(@+10)¨
|
||||||
Fconst ← ≡◶⟨@⊸≤◶Num‿Char, Str, ⊑⟩
|
Fconst ← ≡◶⟨@⊸≤◶Num‿Char, Str, ⊑⟩
|
||||||
Fout ← {((≠𝕩)↑⟨LI F¨,L Fconst¨,L (LI ·F¨ 4↑⊢)¨,L (L F¨)¨⟩) {𝕎𝕩}¨ 𝕩}
|
Fout ← {((≠𝕩)↑⟨LI F¨,L Fconst¨,L (LI ·F¨ 4↑⊢)¨,L (L F¨)¨⟩) {𝕎𝕩}¨ 𝕩}
|
||||||
Frun ← 1⊸Fout
|
Frun ← 1⊸Fout
|
||||||
Long ← {¯2↓∾𝕩∾¨<","∾\n}
|
Long ← {¯2↓∾𝕩∾¨<","∾@+10}
|
||||||
|
LFC ← Long∘Fout∘Comp
|
||||||
|
|
||||||
RT ← {
|
RT ← {
|
||||||
src‿need‿inputs←𝕩Import"pr.bqn"
|
src‿need‿inputs←𝕩Import"pr.bqn"
|
||||||
@ -43,7 +44,7 @@ RT ← {
|
|||||||
Long Fout pr need _getComp src
|
Long Fout pr need _getComp src
|
||||||
}
|
}
|
||||||
CArg ← {J (¯5⊸↓∾𝕩˙)⌾⊑ FLines "c.bqn"}
|
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"⊐⊏)◶⟨
|
•Out⍟(¬return) (⊑"r"‿"r0"‿"r1"‿"c"‿"cc"‿"f"‿"e"‿"p"⊐⊏)◶⟨
|
||||||
RT∘2, RT∘0, RT∘1
|
RT∘2, RT∘0, RT∘1
|
||||||
|
|||||||
@ -6,11 +6,7 @@ typedef struct FillArr {
|
|||||||
B a[];
|
B a[];
|
||||||
} FillArr;
|
} FillArr;
|
||||||
|
|
||||||
B getFillQ(B x) { // doesn't consume; can return bi_noFill
|
B getFillR(B x) { // doesn't consume; can return bi_noFill
|
||||||
bool defZero = true;
|
|
||||||
#ifdef CATCH_ERRORS
|
|
||||||
defZero = false;
|
|
||||||
#endif
|
|
||||||
if (isArr(x)) {
|
if (isArr(x)) {
|
||||||
u8 t = v(x)->type;
|
u8 t = v(x)->type;
|
||||||
if (t==t_fillarr ) { B r = inc(c(FillArr,x )->fill); return r; }
|
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_c32arr || t==t_c32slice) return m_c32(' ');
|
||||||
if (t==t_i32arr || t==t_i32slice) return m_f64(0 );
|
if (t==t_i32arr || t==t_i32slice) return m_f64(0 );
|
||||||
if (t==t_f64arr || t==t_f64slice) 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 (isF64(x)|isI32(x)) return m_i32(0);
|
||||||
if (isC32(x)) return m_c32(' ');
|
if (isC32(x)) return m_c32(' ');
|
||||||
|
return bi_noFill;
|
||||||
return defZero? m_f64(0) : 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 getFillE(B x) { // errors if there's no fill
|
||||||
B xf = getFillQ(x);
|
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_c1(B t, B x) { return x; }
|
||||||
B rtack_c2(B t, B w, B x) { dec(w); 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) {
|
B fmtF_c1(B t, B x) {
|
||||||
if (!isVal(x)) return m_str32(U"(fmtF: not given a function)");
|
if (!isVal(x)) return m_str32(U"(fmtF: not given a function)");
|
||||||
u8 fl = v(x)->flags;
|
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 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);
|
BI_FNS0(F);
|
||||||
static inline void fns_init() { BI_FNS1(F)
|
static inline void fns_init() { BI_FNS1(F)
|
||||||
ti[t_funBI].print = print_funBI;
|
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)") \
|
#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(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,"⋆⁼") \
|
/*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,"⊔") \
|
/*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)") \
|
/*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \
|
||||||
/*sort.c*/ F(gradeUp,"⍋") \
|
/*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") \
|
/*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 {
|
enum PrimFns {
|
||||||
@ -145,13 +145,13 @@ char* format_pf(u8 u) {
|
|||||||
enum PrimMd1 {
|
enum PrimMd1 {
|
||||||
pm1_none,
|
pm1_none,
|
||||||
pm1_tbl, pm1_each, pm1_fold, pm1_scan, pm1_const, pm1_swap, pm1_timed, // md1.c
|
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) {
|
char* format_pm1(u8 u) {
|
||||||
switch(u) {
|
switch(u) {
|
||||||
default: case pf_none: return"(unknown 1-modifier)";
|
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_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 {
|
enum PrimMd2 {
|
||||||
@ -258,8 +258,8 @@ B m_unit (B x); // consumes
|
|||||||
B m_hunit(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 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_exec(B str, B path, B args); // consumes both
|
||||||
B bqn_execFile(B path); // consumes
|
B bqn_execFile(B path, B args); // consumes
|
||||||
|
|
||||||
NOINLINE NORETURN void thr(B b);
|
NOINLINE NORETURN void thr(B b);
|
||||||
NOINLINE NORETURN void thrM(char* s);
|
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
|
#endif
|
||||||
|
|
||||||
void load_gcFn() { mm_visit(comp_currPath); }
|
void load_gcFn() {
|
||||||
Block* bqn_comp(B str, B path) { // consumes both
|
mm_visit(comp_currPath);
|
||||||
|
mm_visit(comp_currArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Block* bqn_comp(B str, B path, B args) { // consumes all
|
||||||
comp_currPath = path;
|
comp_currPath = path;
|
||||||
|
comp_currArgs = args;
|
||||||
Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str);
|
Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str);
|
||||||
dec(path);
|
dec(path); dec(args);
|
||||||
comp_currPath = bi_N;
|
comp_currArgs = comp_currPath = bi_N;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
B bqn_exec(B str, B path) { // consumes both
|
B bqn_exec(B str, B path, B args) { // consumes all
|
||||||
Block* block = bqn_comp(str, path);
|
Block* block = bqn_comp(str, path, args);
|
||||||
B res = m_funBlock(block, 0);
|
B res = m_funBlock(block, 0);
|
||||||
ptr_dec(block);
|
ptr_dec(block);
|
||||||
return res;
|
return res;
|
||||||
@ -45,6 +50,7 @@ void bqn_setComp(B comp) { // consumes; doesn't unload old comp, but whatever
|
|||||||
|
|
||||||
static inline void load_init() {
|
static inline void load_init() {
|
||||||
comp_currPath = bi_N;
|
comp_currPath = bi_N;
|
||||||
|
comp_currArgs = bi_N;
|
||||||
gc_addFn(load_gcFn);
|
gc_addFn(load_gcFn);
|
||||||
B fruntime[] = {
|
B fruntime[] = {
|
||||||
/* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil, bi_stile , bi_not,
|
/* +-×÷⋆√⌊⌈|¬ */ 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
|
#endif // NO_COMP
|
||||||
}
|
}
|
||||||
|
|
||||||
B bqn_execFile(B path) { // consumes
|
B bqn_execFile(B path, B args) { // consumes both
|
||||||
return bqn_exec(file_chars(inc(path)), path);
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
bool startREPL = argc==1;
|
||||||
if (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) {
|
while (CATCH) {
|
||||||
printf("Error: "); print(catchMessage); putchar('\n');
|
printf("Error: "); print(catchMessage); putchar('\n');
|
||||||
vm_pst(envCurr, envStart+envPrevHeight);
|
vm_pst(envCurr, envStart+envPrevHeight);
|
||||||
@ -94,7 +163,7 @@ int main(int argc, char* argv[]) {
|
|||||||
size_t gl = 0;
|
size_t gl = 0;
|
||||||
getline(&ln, &gl, stdin);
|
getline(&ln, &gl, stdin);
|
||||||
if (ln[0]==0 || ln[0]==10) break;
|
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);
|
free(ln);
|
||||||
|
|
||||||
#ifdef TIME
|
#ifdef TIME
|
||||||
@ -124,8 +193,6 @@ int main(int argc, char* argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
popCatch();
|
popCatch();
|
||||||
} else {
|
|
||||||
bqn_execFile(fromUTF8l(argv[1]));
|
|
||||||
}
|
}
|
||||||
rtPerf_print();
|
rtPerf_print();
|
||||||
CTR_FOR(CTR_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));
|
return file_chars(path_resolve(f, x));
|
||||||
}
|
}
|
||||||
B fbytes_c1(B d, B x) { B f = c(Md1D,d)->f;
|
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);
|
u32* rp; B r = m_c32arrv(&rp, ia);
|
||||||
for (i64 i = 0; i < ia; i++) rp[i] = p[i];
|
for (i64 i = 0; i < ia; i++) rp[i] = p[i];
|
||||||
ptr_dec(tf);
|
ptr_dec(tf);
|
||||||
return r;
|
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;
|
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);
|
#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)); }
|
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;
|
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(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;
|
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) {
|
if (rnk(x)==1) {
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
if (xia==0) {
|
if (xia==0) {
|
||||||
B xf = getFillE(x); dec(x);
|
B xf = getFillE(x);
|
||||||
if (isAtm(xf)) thrM("∾: Empty vector 𝕩 cannot have an atom fill element");
|
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);
|
ur ir = rnk(xf);
|
||||||
if (ir==0) thrM("∾: Empty vector 𝕩 cannot have a unit fill element");
|
if (ir==0) thrM("∾: Empty vector 𝕩 cannot have a unit fill element");
|
||||||
B xff = getFillQ(xf);
|
B xff = getFillQ(xf);
|
||||||
@ -493,7 +504,7 @@ B join_c2(B t, B w, B x) {
|
|||||||
HArr_p r = m_harrUv(2);
|
HArr_p r = m_harrUv(2);
|
||||||
r.a[0] = TI(w).get(w,0); dec(w);
|
r.a[0] = TI(w).get(w,0); dec(w);
|
||||||
r.a[1] = TI(x).get(x,0); dec(x);
|
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");
|
if (c-wr > 1 || c-xr > 1) thrM("∾: Argument ranks must differ by 1 or less");
|
||||||
MAKE_MUT(r, wia+xia);
|
MAKE_MUT(r, wia+xia);
|
||||||
|
|||||||
@ -365,6 +365,7 @@ void printAllocStats() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_Thread_local B comp_currPath;
|
_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 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();
|
#define F(X) static inline void X##_init();
|
||||||
FOR_INIT(F)
|
FOR_INIT(F)
|
||||||
|
|||||||
21
src/sysfn.c
21
src/sysfn.c
@ -32,6 +32,14 @@ B glyph_c1(B t, B x) {
|
|||||||
return 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 fill_c1(B t, B x) {
|
||||||
B r = getFillE(x);
|
B r = getFillE(x);
|
||||||
dec(x);
|
dec(x);
|
||||||
@ -137,7 +145,7 @@ B bqn_c1(B t, B x) {
|
|||||||
BS2B xgetU = TI(x).getU;
|
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");
|
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) {
|
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);
|
BI_FNS0(F);
|
||||||
static inline void sysfn_init() { BI_FNS1(F) }
|
static inline void sysfn_init() { BI_FNS1(F) }
|
||||||
#undef 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)));
|
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) {
|
B sys_c1(B t, B x) {
|
||||||
assert(isArr(x));
|
assert(isArr(x));
|
||||||
usz i = 0;
|
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"bqn")) r.a[i] = inc(bi_bqn);
|
||||||
else if (eqStr(c, U"cmp")) r.a[i] = inc(bi_cmp);
|
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"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"fchars")) r.a[i] = makeRel(bi_fchars);
|
||||||
else if (eqStr(c, U"fbytes")) r.a[i] = makeRel(bi_fbytes);
|
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 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);
|
return harr_fcd(r, x);
|
||||||
}
|
}
|
||||||
|
|||||||
85
src/vm.c
85
src/vm.c
@ -685,46 +685,6 @@ void popCatch() {
|
|||||||
#endif
|
#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) {
|
NOINLINE void vm_pst(Env* s, Env* e) {
|
||||||
assert(s<=e);
|
assert(s<=e);
|
||||||
@ -763,3 +723,48 @@ NOINLINE void vm_pst(Env* s, Env* e) {
|
|||||||
i--;
|
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