•Import, relative paths
This commit is contained in:
parent
523a062b95
commit
87138ee523
65
src/file.c
Normal file
65
src/file.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
typedef struct TmpFile { // to be turned into a proper I8Arr
|
||||||
|
struct Arr;
|
||||||
|
i8 a[];
|
||||||
|
} TmpFile;
|
||||||
|
|
||||||
|
TmpFile* file_bytes(B path) { // consumes; may throw
|
||||||
|
u64 plen = utf8lenB(path);
|
||||||
|
char p[plen+1];
|
||||||
|
toUTF8(path, p);
|
||||||
|
p[plen] = 0;
|
||||||
|
FILE* f = fopen(p, "r");
|
||||||
|
if (f==NULL) thrM("Couldn't read file");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
u64 len = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
TmpFile* src = mm_allocN(fsizeof(TmpFile,a,u8,len), t_i8arr);
|
||||||
|
arr_shVec(tag(src,ARR_TAG), len);
|
||||||
|
fread((char*)src->a, 1, len, f);
|
||||||
|
fclose(f);
|
||||||
|
dec(path);
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
B file_chars(B path) { // consumes; may throw
|
||||||
|
TmpFile* c = file_bytes(path);
|
||||||
|
B r = fromUTF8((char*)c->a, c->ia);
|
||||||
|
ptr_dec(c);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
B path_resolve(B base, B rel) { // consumes rel; may error; assumes base is a char vector or bi_N
|
||||||
|
assert((isArr(base) || isNothing(base)) && isArr(rel));
|
||||||
|
BS2B rgetU = TI(rel).getU;
|
||||||
|
usz ria = a(rel)->ia;
|
||||||
|
if (rnk(rel)!=1) thrM("Paths must be character vectors");
|
||||||
|
for (usz i = 0; i < ria; i++) if (!isC32(rgetU(rel, i))) thrM("Paths must be character vectors");
|
||||||
|
if (ria==0) { dec(rel); return inc(base); }
|
||||||
|
if (o2cu(rgetU(rel, 0))=='/') return rel;
|
||||||
|
if (isNothing(base)) thrM("Using relative path with no absolute base path known");
|
||||||
|
BS2B bgetU = TI(base).getU;
|
||||||
|
usz bia = a(base)->ia;
|
||||||
|
bool has = bia && o2cu(bgetU(base, bia-1))=='/';
|
||||||
|
u32* rp; B r = m_c32arrv(&rp, bia+ria+(has?0:1));
|
||||||
|
usz ri = 0;
|
||||||
|
for (usz i = 0; i < bia-(has?1:0); i++) rp[ri++] = o2cu(bgetU(base, i));
|
||||||
|
rp[ri++] = '/';
|
||||||
|
for (usz i = 0; i < ria; i++) rp[ri++] = o2cu(rgetU(rel, i));
|
||||||
|
dec(rel);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
B path_dir(B path) { // consumes; returns directory part of file path, with trailing slash; may error
|
||||||
|
BS2B pgetU = TI(path).getU;
|
||||||
|
usz pia = a(path)->ia;
|
||||||
|
for (usz i = 0; i < pia; i++) if (!isC32(pgetU(path, i))) thrM("Paths must be character vectors");
|
||||||
|
for (usz i = pia-1; i >= 0; i--) {
|
||||||
|
if (o2cu(pgetU(path, i))=='/') {
|
||||||
|
B r = TI(path).slice(path, 0);
|
||||||
|
arr_shVec(r, i+1);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dec(path);
|
||||||
|
u32* rp; B r = m_c32arrv(&rp, 2); rp[0] = '.'; rp[1] = '/';
|
||||||
|
return r;
|
||||||
|
}
|
||||||
6
src/h.h
6
src/h.h
@ -126,7 +126,6 @@ char* format_type(u8 u) {
|
|||||||
/*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(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") \
|
||||||
/*sysfn.c*/ F(fchars,"•FChars") F(fbytes,"•FBytes")
|
|
||||||
|
|
||||||
enum PrimFns {
|
enum PrimFns {
|
||||||
#define F(N,X) pf_##N,
|
#define F(N,X) pf_##N,
|
||||||
@ -143,11 +142,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
|
||||||
};
|
};
|
||||||
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enum PrimMd2 {
|
enum PrimMd2 {
|
||||||
@ -254,7 +255,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); // consumes
|
B bqn_exec(B str, B path); // consumes both
|
||||||
|
B bqn_execFile(B path); // 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,13 +23,17 @@ B bqn_fmt(B x) { // consumes
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void load_gcFn() { mm_visit(comp_currPath); }
|
||||||
Block* bqn_comp(B str) { // consumes
|
Block* bqn_comp(B str, B path) { // consumes
|
||||||
inc(str);
|
comp_currPath = path;
|
||||||
return load_compObj(c2(load_comp, inc(load_compArg), str), str);
|
Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str);
|
||||||
|
dec(path);
|
||||||
|
comp_currPath = bi_N;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
B bqn_exec(B str) { // consumes
|
|
||||||
Block* block = bqn_comp(str);
|
B bqn_exec(B str, B path) { // consumes both
|
||||||
|
Block* block = bqn_comp(str, path);
|
||||||
B res = m_funBlock(block, 0);
|
B res = m_funBlock(block, 0);
|
||||||
ptr_dec(block);
|
ptr_dec(block);
|
||||||
return res;
|
return res;
|
||||||
@ -40,6 +44,8 @@ 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;
|
||||||
|
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,
|
||||||
/* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne,
|
/* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne,
|
||||||
@ -155,6 +161,6 @@ static inline void load_init() {
|
|||||||
#endif // NO_COMP
|
#endif // NO_COMP
|
||||||
}
|
}
|
||||||
|
|
||||||
B bqn_execFile(B path) {
|
B bqn_execFile(B path) { // consumes
|
||||||
return bqn_exec(file_chars(path));
|
return bqn_exec(file_chars(inc(path)), path);
|
||||||
}
|
}
|
||||||
@ -37,6 +37,7 @@
|
|||||||
#include "fillarr.c"
|
#include "fillarr.c"
|
||||||
#include "mut.c"
|
#include "mut.c"
|
||||||
#include "utf.c"
|
#include "utf.c"
|
||||||
|
#include "file.c"
|
||||||
#include "derv.c"
|
#include "derv.c"
|
||||||
#include "fns.c"
|
#include "fns.c"
|
||||||
#include "sfns.c"
|
#include "sfns.c"
|
||||||
@ -92,7 +93,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)));
|
Block* block = bqn_comp(fromUTF8(ln, strlen(ln)), bi_N);
|
||||||
free(ln);
|
free(ln);
|
||||||
|
|
||||||
#ifdef TIME
|
#ifdef TIME
|
||||||
|
|||||||
18
src/md1.c
18
src/md1.c
@ -211,14 +211,28 @@ B timed_c1(B d, B x) { B f = c(Md1D,d)->f;
|
|||||||
return m_f64((ens-sns)/1e9);
|
return m_f64((ens-sns)/1e9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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 import_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||||
|
return bqn_execFile(path_resolve(f, x));
|
||||||
|
}
|
||||||
|
|
||||||
#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);
|
||||||
#define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
|
#define bd(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = NAME##_c2; c(Md1,bi_##NAME)->c1 = c1_invalid; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
|
||||||
#define bm(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = c2_invalid;c(Md1,bi_##NAME)->c1 = NAME##_c1 ; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
|
#define bm(NAME) bi_##NAME = mm_alloc(sizeof(Md1), t_md1BI, ftag(MD1_TAG)); c(Md1,bi_##NAME)->c2 = c2_invalid;c(Md1,bi_##NAME)->c1 = NAME##_c1 ; c(Md1,bi_##NAME)->extra=pm1_##NAME; gc_add(bi_##NAME);
|
||||||
|
|
||||||
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;
|
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)
|
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)
|
||||||
ti[t_md1BI].print = print_md1BI;
|
ti[t_md1BI].print = print_md1BI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -364,6 +364,7 @@ void printAllocStats() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_Thread_local B comp_currPath;
|
||||||
#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)
|
||||||
|
|||||||
56
src/sysfn.c
56
src/sysfn.c
@ -137,7 +137,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);
|
return bqn_exec(x, bi_N);
|
||||||
}
|
}
|
||||||
|
|
||||||
B cmp_c2(B t, B w, B x) {
|
B cmp_c2(B t, B w, B x) {
|
||||||
@ -146,54 +146,17 @@ B cmp_c2(B t, B w, B x) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TmpFile { // to be turned into a proper I8Arr
|
|
||||||
struct Arr;
|
|
||||||
i8 a[];
|
|
||||||
} TmpFile;
|
|
||||||
|
|
||||||
TmpFile* file_bytes(B path) { // consumes; may throw
|
#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)
|
||||||
u64 plen = utf8lenB(path);
|
|
||||||
char p[plen+1];
|
|
||||||
toUTF8(path, p);
|
|
||||||
p[plen] = 0;
|
|
||||||
FILE* f = fopen(p, "r");
|
|
||||||
if (f==NULL) thrM("Couldn't read file");
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
u64 len = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
TmpFile* src = mm_allocN(fsizeof(TmpFile,a,u8,len), t_i8arr);
|
|
||||||
arr_shVec(tag(src,ARR_TAG), len);
|
|
||||||
fread((char*)src->a, 1, len, f);
|
|
||||||
fclose(f);
|
|
||||||
dec(path);
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
B file_chars(B path) { // consumes; may throw
|
|
||||||
TmpFile* c = file_bytes(path);
|
|
||||||
B r = fromUTF8((char*)c->a, c->ia);
|
|
||||||
ptr_dec(c);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
B fchars_c1(B t, B x) {
|
|
||||||
return file_chars(x);
|
|
||||||
}
|
|
||||||
B fbytes_c1(B t, B x) {
|
|
||||||
TmpFile* f = file_bytes(x); usz ia = f->ia; u8* p = (u8*)f->a;
|
|
||||||
u32* rp; B r = m_c32arrv(&rp, ia);
|
|
||||||
for (i64 i = 0; i < ia; i++) rp[i] = p[i];
|
|
||||||
ptr_dec(f);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#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) M(fchars) M(fbytes)
|
|
||||||
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
|
||||||
|
|
||||||
B bi_timed;
|
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 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;
|
||||||
@ -210,8 +173,9 @@ 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"fchars")) r.a[i] = inc(bi_fchars);
|
else if (eqStr(c, U"fchars")) r.a[i] = makeRel(bi_fchars);
|
||||||
else if (eqStr(c, U"fbytes")) r.a[i] = inc(bi_fbytes);
|
else if (eqStr(c, U"fbytes")) r.a[i] = makeRel(bi_fbytes);
|
||||||
|
else if (eqStr(c, U"import")) r.a[i] = makeRel(bi_import);
|
||||||
else { dec(x); thrM("Unknown system function"); }
|
else { dec(x); thrM("Unknown system function"); }
|
||||||
}
|
}
|
||||||
return harr_fcd(r, x);
|
return harr_fcd(r, x);
|
||||||
|
|||||||
@ -19,12 +19,12 @@ B fromUTF8(char* s, i64 len) {
|
|||||||
u64 sz = 0;
|
u64 sz = 0;
|
||||||
i64 j = 0;
|
i64 j = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
i8 l = utf8lenb((u8)s[j]);
|
|
||||||
if (l==-1) thrM("Invalid UTF-8");
|
|
||||||
if (j>=len) {
|
if (j>=len) {
|
||||||
if (j!=len) thrM("Invalid UTF-8");
|
if (j!=len) thrM("Invalid UTF-8");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
i8 l = utf8lenb((u8)s[j]);
|
||||||
|
if (l==-1) thrM("Invalid UTF-8");
|
||||||
sz++;
|
sz++;
|
||||||
j+= l;
|
j+= l;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user