•file.List
This commit is contained in:
parent
48ac839a1d
commit
f1b1686300
@ -233,7 +233,7 @@ static B internalNS;
|
||||
B getInternalNS() {
|
||||
if (internalNS.u == 0) {
|
||||
#define F(X) inc(bi_##X),
|
||||
B fn = bqn_exec(m_str32(U"{⟨ Type, Refc, Squeeze, IsPure, Info, ListVariations, Variation, ClearRefs, Unshare⟩⇐𝕩}"), inc(bi_emptyHVec), inc(bi_emptyHVec));
|
||||
B fn = bqn_exec(m_str32(U"{⟨ Type, Refc, Squeeze, IsPure, Info, ListVariations, Variation, ClearRefs, Unshare⟩⇐𝕩}"), inc(bi_emptyCVec), inc(bi_emptySVec));
|
||||
B arg = m_caB(9, (B[]){F(itype)F(refc)F(squeeze)F(isPure)F(info)F(listVariations)F(variation)F(clearRefs)F(unshare)});
|
||||
#undef F
|
||||
internalNS = c1(fn,arg);
|
||||
|
||||
@ -175,7 +175,7 @@ B hash_c1(B t, B x) {
|
||||
static B rand_ns;
|
||||
static B rand_rangeName;
|
||||
static i32 rand_a, rand_b;
|
||||
static NFnDesc* rand_range;
|
||||
static NFnDesc* rand_rangeDesc;
|
||||
B rand_range_c1(B t, B x) {
|
||||
i64 xv = o2i64(x);
|
||||
if (xv<0) thrM("(rand).Range: 𝕩 cannot be negative");
|
||||
@ -210,9 +210,9 @@ B rand_range_c2(B t, B w, B x) {
|
||||
}
|
||||
|
||||
static NOINLINE void rand_init() {
|
||||
rand_ns = bqn_exec(m_str32(U"{a←𝕨⋄b←𝕩⋄range⇐0}"), inc(bi_emptyHVec), inc(bi_emptyHVec)); gc_add(rand_ns);
|
||||
rand_ns = bqn_exec(m_str32(U"{a←𝕨⋄b←𝕩⋄range⇐0}"), inc(bi_emptyCVec), inc(bi_emptySVec)); gc_add(rand_ns);
|
||||
rand_rangeName = m_str32(U"range"); gc_add(rand_rangeName);
|
||||
rand_range = registerNFn(m_str32(U"(rand).Range"), rand_range_c1, rand_range_c2);
|
||||
rand_rangeDesc = registerNFn(m_str32(U"(rand).Range"), rand_range_c1, rand_range_c2);
|
||||
B tmp = c1(rand_ns, m_f64(0));
|
||||
rand_a = ns_pos(tmp, m_str32(U"a"));
|
||||
rand_b = ns_pos(tmp, m_str32(U"b"));
|
||||
@ -222,21 +222,21 @@ B makeRand_c1(B t, B x) {
|
||||
if (!isNum(x)) thrM("•MakeRand: 𝕩 must be a number");
|
||||
if (rand_ns.u==0) rand_init();
|
||||
B r = c2(rand_ns, b(x.u>>32), b(x.u&0xFFFFFFFF));
|
||||
ns_set(r, rand_rangeName, m_nfn(rand_range, inc(r)));
|
||||
ns_set(r, rand_rangeName, m_nfn(rand_rangeDesc, inc(r)));
|
||||
return r;
|
||||
}
|
||||
|
||||
static NFnDesc* fCharsDesc;
|
||||
B fchars_c1(B d, B x) { B base = nfn_objU(d);
|
||||
return file_chars(path_resolve(base, x));
|
||||
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) { B base = nfn_objU(d);
|
||||
file_write(path_resolve(base, w), x);
|
||||
B fchars_c2(B d, B w, B x) {
|
||||
file_write(path_resolve(nfn_objU(d), w), x);
|
||||
return x;
|
||||
}
|
||||
static NFnDesc* fBytesDesc;
|
||||
B fbytes_c1(B d, B x) { B base = nfn_objU(d);
|
||||
TmpFile* tf = file_bytes(path_resolve(base, x));
|
||||
B fbytes_c1(B d, B x) {
|
||||
TmpFile* tf = file_bytes(path_resolve(nfn_objU(d), 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];
|
||||
@ -244,8 +244,8 @@ B fbytes_c1(B d, B x) { B base = nfn_objU(d);
|
||||
return r;
|
||||
}
|
||||
static NFnDesc* fLinesDesc;
|
||||
B flines_c1(B d, B x) { B base = nfn_objU(d);
|
||||
TmpFile* tf = file_bytes(path_resolve(base, x));
|
||||
B flines_c1(B d, B x) {
|
||||
TmpFile* tf = file_bytes(path_resolve(nfn_objU(d), x));
|
||||
usz ia = tf->ia; u8* p = (u8*)tf->a;
|
||||
usz lineCount = 0;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
@ -270,11 +270,11 @@ B flines_c1(B d, B x) { B base = nfn_objU(d);
|
||||
return harr_fv(r);
|
||||
}
|
||||
static NFnDesc* importDesc;
|
||||
B import_c1(B d, B x) { B base = nfn_objU(d);
|
||||
return bqn_execFile(path_resolve(base, x), inc(bi_emptyHVec));
|
||||
}
|
||||
B import_c2(B d, B w, B x) { B base = nfn_objU(d);
|
||||
return bqn_execFile(path_resolve(base, x), w);
|
||||
B import_c1(B d, B x) { return bqn_execFile(path_resolve(nfn_objU(d), x), inc(bi_emptySVec)); }
|
||||
B import_c2(B d, B w, B x) { return bqn_execFile(path_resolve(nfn_objU(d), x), w); }
|
||||
static NFnDesc* listDesc;
|
||||
B list_c1(B d, B x) {
|
||||
return file_list(path_resolve(nfn_objU(d), x));
|
||||
}
|
||||
|
||||
B exit_c1(B t, B x) {
|
||||
@ -283,16 +283,27 @@ B exit_c1(B t, B x) {
|
||||
|
||||
B getInternalNS();
|
||||
|
||||
static B file_nsGen;
|
||||
B sys_c1(B t, B x) {
|
||||
assert(isArr(x));
|
||||
usz i = 0;
|
||||
HArr_p r = m_harrs(a(x)->ia, &i);
|
||||
BS2B xgetU = TI(x).getU;
|
||||
B fileNS = m_f64(0);
|
||||
for (; i < a(x)->ia; i++) {
|
||||
B c = xgetU(x,i);
|
||||
if (eqStr(c, U"out")) r.a[i] = inc(bi_out);
|
||||
else if (eqStr(c, U"show")) r.a[i] = inc(bi_show);
|
||||
else if (eqStr(c, U"exit")) r.a[i] = inc(bi_exit);
|
||||
else if (eqStr(c, U"file")) {
|
||||
if(fileNS.u==m_f64(0).u) {
|
||||
#define F(X) m_nfn(X##Desc, path_dir(inc(comp_currPath))),
|
||||
B arg = m_caB(4, (B[]){F(list)F(fBytes)F(fChars)F(fLines)});
|
||||
#undef F
|
||||
fileNS = c1(file_nsGen,arg);
|
||||
}
|
||||
r.a[i] = inc(fileNS);
|
||||
}
|
||||
else if (eqStr(c, U"internal")) r.a[i] = getInternalNS();
|
||||
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
|
||||
else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);
|
||||
@ -312,6 +323,7 @@ B sys_c1(B t, B x) {
|
||||
r.a[i] = inc(comp_currArgs);
|
||||
} else { dec(x); thrF("Unknown system function •%R", c); }
|
||||
}
|
||||
dec(fileNS);
|
||||
return harr_fcd(r, x);
|
||||
}
|
||||
|
||||
@ -320,4 +332,8 @@ void sysfn_init() {
|
||||
fLinesDesc = registerNFn(m_str32(U"•FLines"), flines_c1, c2_invalid);
|
||||
fBytesDesc = registerNFn(m_str32(U"•FBytes"), fbytes_c1, c2_invalid);
|
||||
importDesc = registerNFn(m_str32(U"•Import"), import_c1, import_c2);
|
||||
listDesc = registerNFn(m_str32(U"•file.List"), list_c1, c2_invalid);
|
||||
}
|
||||
void sysfnPost_init() {
|
||||
file_nsGen = bqn_exec(m_str32(U"{⟨List, Bytes, Chars, Lines⟩⇐𝕩}"), inc(bi_emptyCVec), inc(bi_emptySVec)); gc_add(file_nsGen);
|
||||
}
|
||||
|
||||
@ -44,6 +44,8 @@ void c32arr_init() {
|
||||
ti[t_i32arr].arrD1 = true; ti[t_i32slice].arrD1 = true;
|
||||
ti[t_c32arr].elType = el_c32; ti[t_c32slice].elType = el_c32;
|
||||
ti[t_c32arr].canStore = c32arr_canStore;
|
||||
u32* tmp; bi_emptyCVec = m_c32arrv(&tmp, 0);
|
||||
gc_add(bi_emptyCVec);
|
||||
u32* tmp; bi_emptyCVec = m_c32arrv(&tmp, 0); gc_add(bi_emptyCVec);
|
||||
bi_emptySVec = m_fillarrp(0); gc_add(bi_emptySVec);
|
||||
arr_shVec(bi_emptySVec, 0);
|
||||
fillarr_setFill(bi_emptySVec, bi_emptyCVec);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "../utils/utf.h"
|
||||
|
||||
u64 allocB; // currently allocated number of bytes
|
||||
B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec;
|
||||
B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec, bi_emptySVec;
|
||||
#define F(N) u64 N;
|
||||
CTR_FOR(F)
|
||||
#undef F
|
||||
|
||||
2
src/h.h
2
src/h.h
@ -242,7 +242,7 @@ static const B bi_noVar = tag(1, TAG_TAG);
|
||||
static const B bi_badHdr = tag(2, TAG_TAG);
|
||||
static const B bi_optOut = tag(3, TAG_TAG);
|
||||
static const B bi_noFill = tag(5, TAG_TAG);
|
||||
extern B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec;
|
||||
extern B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec, bi_emptySVec;
|
||||
static void dec(B x);
|
||||
static B inc(B x);
|
||||
static void ptr_dec(void* x);
|
||||
|
||||
@ -365,7 +365,7 @@ static inline void base_init() { // very first init function
|
||||
#undef FD
|
||||
}
|
||||
|
||||
#define FOR_INIT(F) F(base) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(hash) F(sfns) F(fns) F(arith) F(md1) F(md2) F(derv) F(comp) F(rtWrap) F(ns) F(nfn) F(sysfn) F(load)
|
||||
#define FOR_INIT(F) F(base) F(harr) F(fillarr) F(i32arr) F(c32arr) F(f64arr) F(hash) F(sfns) F(fns) F(arith) F(md1) F(md2) F(derv) F(comp) F(rtWrap) F(ns) F(nfn) F(sysfn) F(load) F(sysfnPost)
|
||||
#define F(X) void X##_init();
|
||||
FOR_INIT(F)
|
||||
#undef F
|
||||
|
||||
10
src/main.c
10
src/main.c
@ -89,17 +89,17 @@ int main(int argc, char* argv[]) {
|
||||
#define REQARG(X) if(*carg) { fprintf(stderr, "%s: -%s must end the option\n", argv[0], #X); exit(1); } if (i==argc) { fprintf(stderr, "%s: -%s requires an argument\n", argv[0], #X); exit(1); }
|
||||
case 'f': repl_init(); REQARG(f); goto execFile;
|
||||
case 'e': { repl_init(); REQARG(e);
|
||||
dec(gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-e)"), inc(bi_emptyHVec)));
|
||||
dec(gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-e)"), inc(bi_emptySVec)));
|
||||
break;
|
||||
}
|
||||
case 'p': { repl_init(); REQARG(p);
|
||||
B r = gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-p)"), inc(bi_emptyHVec));
|
||||
B r = gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-p)"), inc(bi_emptySVec));
|
||||
print(r); dec(r);
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
case 'o': { repl_init(); REQARG(o);
|
||||
B r = gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-o)"), inc(bi_emptyHVec));
|
||||
B r = gsc_exec_inline(fromUTF8l(argv[i++]), m_str32(U"(-o)"), inc(bi_emptySVec));
|
||||
printRaw(r); dec(r);
|
||||
printf("\n");
|
||||
break;
|
||||
@ -130,7 +130,7 @@ int main(int argc, char* argv[]) {
|
||||
B src = fromUTF8l(argv[i++]);
|
||||
B args;
|
||||
if (i==argc) {
|
||||
args = inc(bi_emptyHVec);
|
||||
args = inc(bi_emptySVec);
|
||||
} else {
|
||||
HArr_p ap = m_harrUv(argc-i); // eh whatever, erroring will exit anyways
|
||||
for (usz j = 0; j < argc-i; j++) {
|
||||
@ -158,7 +158,7 @@ int main(int argc, char* argv[]) {
|
||||
size_t gl = 0;
|
||||
i64 read = getline(&ln, &gl, stdin);
|
||||
if (read<=0 || ln[0]==0 || ln[0]==10) break;
|
||||
Block* block = bqn_compSc(fromUTF8(ln, strlen(ln)), inc(replPath), inc(bi_emptyHVec), gsc, true);
|
||||
Block* block = bqn_compSc(fromUTF8(ln, strlen(ln)), inc(replPath), inc(bi_emptySVec), gsc, true);
|
||||
free(ln);
|
||||
|
||||
ptr_dec(gsc->body); ptr_inc(block->body);
|
||||
|
||||
@ -11,7 +11,7 @@ typedef struct NFn { // native function
|
||||
} NFn;
|
||||
|
||||
NFnDesc* registerNFn(B name, BB2B c1, BBB2B c2); // should be called a constant number of times; consumes name
|
||||
B m_nfn(NFnDesc* desc, B obj);
|
||||
B m_nfn(NFnDesc* desc, B obj); // consumes obj
|
||||
B nfn_name(B x); // doesn't consume
|
||||
static B nfn_objU(B t) {
|
||||
return c(NFn,t)->obj;
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#include <dirent.h>
|
||||
#include "../core.h"
|
||||
#include "file.h"
|
||||
#include "mut.h"
|
||||
|
||||
static FILE* file_open(B path, char* desc, char* mode) { // doesn't consume; can error
|
||||
static FILE* file_open(B path, char* desc, char* mode) { // doesn't consume
|
||||
u64 plen = utf8lenB(path);
|
||||
TALLOC(char, p, plen+1);
|
||||
toUTF8(path, p);
|
||||
@ -11,8 +13,18 @@ static FILE* file_open(B path, char* desc, char* mode) { // doesn't consume; can
|
||||
if (f==NULL) thrF("Couldn't %S file \"%R\"", desc, path);
|
||||
return f;
|
||||
}
|
||||
static DIR* dir_open(B path) { // doesn't consume
|
||||
u64 plen = utf8lenB(path);
|
||||
TALLOC(char, p, plen+1);
|
||||
toUTF8(path, p);
|
||||
p[plen] = 0;
|
||||
DIR* f = opendir(p);
|
||||
TFREE(p);
|
||||
if (f==NULL) thrF("Couldn't open directory \"%R\"", path);
|
||||
return f;
|
||||
}
|
||||
|
||||
TmpFile* file_bytes(B path) { // consumes; may throw
|
||||
TmpFile* file_bytes(B path) { // consumes
|
||||
FILE* f = file_open(path, "read", "r");
|
||||
fseek(f, 0, SEEK_END);
|
||||
u64 len = ftell(f);
|
||||
@ -24,14 +36,14 @@ TmpFile* file_bytes(B path) { // consumes; may throw
|
||||
fclose(f);
|
||||
return src;
|
||||
}
|
||||
B file_chars(B path) { // consumes; may throw
|
||||
B file_chars(B path) { // consumes
|
||||
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
|
||||
B path_resolve(B base, B rel) { // consumes rel; 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;
|
||||
@ -52,7 +64,7 @@ B path_resolve(B base, B rel) { // consumes rel; may error; assumes base is a ch
|
||||
return r;
|
||||
}
|
||||
|
||||
B path_dir(B path) { // consumes; returns directory part of file path, with trailing slash; may error
|
||||
B path_dir(B path) { // consumes; returns directory part of file path with trailing slash, or ·
|
||||
assert(isArr(path) || isNothing(path));
|
||||
if (isNothing(path)) return path;
|
||||
BS2B pgetU = TI(path).getU;
|
||||
@ -72,7 +84,7 @@ B path_dir(B path) { // consumes; returns directory part of file path, with trai
|
||||
}
|
||||
|
||||
|
||||
void file_write(B path, B x) { // consumes path; may throw
|
||||
void file_write(B path, B x) { // consumes path
|
||||
FILE* f = file_open(path, "write to", "w");
|
||||
|
||||
u64 len = utf8lenB(x);
|
||||
@ -84,3 +96,14 @@ void file_write(B path, B x) { // consumes path; may throw
|
||||
dec(path);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
B file_list(B path) {
|
||||
DIR* d = dir_open(path);
|
||||
struct dirent *c;
|
||||
B res = inc(bi_emptySVec);
|
||||
while ((c = readdir(d)) != NULL) {
|
||||
char* name = c->d_name;
|
||||
if (name[0]=='.'? !(name[1]==0 || (name[1]=='.'&&name[2]==0)) : true) res = vec_add(res, m_str8l(name));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -6,9 +6,12 @@ typedef struct TmpFile { // to be turned into a proper I8Arr
|
||||
i8 a[];
|
||||
} TmpFile;
|
||||
|
||||
B path_resolve(B base, B rel); // consumes rel; may error; assumes base is a char vector or bi_N
|
||||
B path_dir(B path); // consumes; returns directory part of file path, with trailing slash; may error
|
||||
B path_resolve(B base, B rel); // consumes rel; assumes base is a char vector or bi_N
|
||||
B path_dir(B path); // consumes; returns directory part of file path, with trailing slash
|
||||
|
||||
TmpFile* file_bytes(B path); // consumes; may throw
|
||||
B file_chars(B path); // consumes; may throw
|
||||
void file_write(B path, B x); // consumes path; may throw
|
||||
TmpFile* file_bytes(B path); // consumes
|
||||
B file_chars(B path); // consumes
|
||||
|
||||
void file_write(B path, B x); // consumes path
|
||||
|
||||
B file_list(B path); // consumes
|
||||
|
||||
Loading…
Reference in New Issue
Block a user