extract single REPL input line execution to function

This commit is contained in:
dzaima 2022-04-06 20:59:33 +03:00
parent fd902bb77e
commit e3e54bea06
2 changed files with 193 additions and 177 deletions

View File

@ -31,7 +31,7 @@ rtverifyn-singeli:
wasi-o3: wasi-o3:
@${MAKE} singeli=0 t=wasi_o3 f="-DWASM -DCATCH_ERRORS=0 -D_WASI_EMULATED_MMAN --target=wasm32-wasi" LDFLAGS="-lwasi-emulated-mman --target=wasm32-wasi" LD_LIBS= PIE= c @${MAKE} singeli=0 t=wasi_o3 f="-DWASM -DCATCH_ERRORS=0 -D_WASI_EMULATED_MMAN --target=wasm32-wasi" LDFLAGS="-lwasi-emulated-mman --target=wasm32-wasi" LD_LIBS= PIE= c
emcc-o3: emcc-o3:
@${MAKE} singeli=0 t=emcc_o3 f='-DWASM -O3' CC=emcc c @${MAKE} singeli=0 t=emcc_o3 f='-DWASM -DEMCC -O3' LDFLAGS='-s EXPORTED_FUNCTIONS=_main,_cbqn_runLine -s EXPORTED_RUNTIME_METHODS=ccall,cwrap' CC=emcc c
# compiler setup # compiler setup

View File

@ -39,6 +39,193 @@ static bool isCmd(char* s, char** e, const char* cmd) {
return true; return true;
} }
void cbqn_runLine0(char* ln, i64 read) {
if (ln[0]==10) return;
if (ln[read-1]==10) ln[--read] = 0;
B code;
int output; // 0-no; 1-formatter; 2-internal
i32 time = 0;
if (ln[0] == ')') {
char* cmdS = ln+1;
char* cmdE;
if (isCmd(cmdS, &cmdE, "ex ")) {
B path = fromUTF8l(cmdE);
code = path_chars(path);
output = 0;
} else if (isCmd(cmdS, &cmdE, "t ") || isCmd(cmdS, &cmdE, "time ")) {
code = fromUTF8l(cmdE);
time = -1;
output = 0;
} else if (isCmd(cmdS, &cmdE, "t:") || isCmd(cmdS, &cmdE, "time:")) {
char* repE = cmdE;
i64 am = 0;
while (*repE>='0' & *repE<='9') {
am = am*10 + (*repE - '0');
repE++;
}
if (repE==cmdE) { printf("time command not given repetition count\n"); return; }
if (am==0) { printf("repetition count was zero\n"); return; }
code = fromUTF8l(repE);
time = am;
output = 0;
} else if (isCmd(cmdS, &cmdE, "mem ")) {
bool sizes = 0;
bool types = 0;
bool freed = 0;
char c;
while ((c=*(cmdE++)) != 0) {
if (c=='t') types=1;
if (c=='s') sizes=1;
if (c=='f') freed=1;
}
heap_printInfo(sizes, types, freed);
return;
} else if (isCmd(cmdS, &cmdE, "erase ")) {
char* name = cmdE;
i64 len = strlen(name);
ScopeExt* e = gsc->ext;
if (e!=NULL) {
i32 am = e->varAm;
for (i32 i = 0; i < am; i++) {
B c = e->vars[i+am];
if (a(c)->ia != len) continue;
SGetU(c)
bool ok = true;
for (i32 j = 0; j < len; j++) ok&= o2cu(GetU(c, j))==name[j];
if (ok) {
B val = e->vars[i];
e->vars[i] = bi_noVar;
dec(val);
#if ENABLE_GC
if (!gc_depth) gc_forceGC();
#endif
return;
}
}
}
printf("No such variable found\n");
return;
} else if (isCmd(cmdS, &cmdE, "vars")) {
B r = listVars(gsc);
if (q_N(r)) {
printf("Couldn't list variables\n");
} else {
usz ia = a(r)->ia;
B* rp = harr_ptr(r);
for (usz i = 0; i < ia; i++) {
if (i!=0) printf(", ");
printRaw(rp[i]);
}
putchar('\n');
}
return;
} else if (isCmd(cmdS, &cmdE, "gc ")) {
#if ENABLE_GC
if (0==*cmdE) {
if (gc_depth!=0) {
printf("GC is disabled, but forcibly GCing anyway\n");
gc_enable();
gc_forceGC();
gc_disable();
} else {
gc_forceGC();
}
} else if (strcmp(cmdE,"on")==0) {
if (gc_depth==0) printf("GC already on\n");
else if (gc_depth>1) printf("GC cannot be enabled\n");
else {
gc_enable();
printf("GC enabled\n");
}
} else if (strcmp(cmdE,"off")==0) {
if (gc_depth>0) printf("GC already off\n");
else {
gc_disable();
printf("GC disabled\n");
}
} else printf("Unknown GC command\n");
#else
printf("Macro ENABLE_GC was false at compile-time, cannot GC\n");
#endif
return;
} else if (isCmd(cmdS, &cmdE, "internalPrint ")) {
code = fromUTF8l(cmdE);
output = 2;
} else {
printf("Unknown REPL command\n");
return;
}
} else {
code = fromUTF8l(ln);
output = 1;
}
Block* block = bqn_compSc(code, inc(replPath), emptySVec(), gsc, true);
ptr_dec(gsc->body);
gsc->body = ptr_inc(block->bodies[0]);
B res;
if (time) {
f64 t;
if (time==-1) {
u64 sns = nsTime();
res = execBlockInline(block, gsc);
u64 ens = nsTime();
t = ens-sns;
} else {
u64 sns = nsTime();
for (i64 i = 0; i < time; i++) dec(execBlockInline(block, gsc));
u64 ens = nsTime();
t = (ens-sns)*1.0 / time;
res = m_c32(0);
}
if (t<1e3) printf("%.5gns\n", t);
else if (t<1e6) printf("%.4gus\n", t/1e3);
else if (t<1e9) printf("%.4gms\n", t/1e6);
else printf("%.5gs\n", t/1e9);
} else {
res = execBlockInline(block, gsc);
}
ptr_dec(block);
if (output) {
if (output!=2 && FORMATTER) {
B resFmt = bqn_fmt(res);
printRaw(resFmt); dec(resFmt);
putchar('\n');
} else {
print(res); putchar('\n'); fflush(stdout);
dec(res);
}
} else dec(res);
#ifdef HEAP_VERIFY
heapVerify();
#endif
gc_maybeGC();
}
void cbqn_runLine(char* ln, i64 read) {
if(CATCH) {
fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n', stderr);
vm_pst(envCurr+1, envStart+envPrevHeight);
freeThrown();
#ifdef HEAP_VERIFY
heapVerify();
#endif
gc_maybeGC();
return;
}
cbqn_runLine0(ln, read);
popCatch();
}
#if EMCC
int main() {
repl_init();
}
#else
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
bool startREPL = argc==1; bool startREPL = argc==1;
bool silentREPL = false; bool silentREPL = false;
@ -151,187 +338,15 @@ int main(int argc, char* argv[]) {
} }
if (startREPL) { if (startREPL) {
repl_init(); repl_init();
while (CATCH) { while (true) {
fprintf(stderr, "Error: "); printErrMsg(thrownMsg); fputc('\n', stderr); if (!silentREPL) printf(" ");
vm_pst(envCurr+1, envStart+envPrevHeight);
freeThrown();
#ifdef HEAP_VERIFY
heapVerify();
#endif
gc_maybeGC();
}
while (true) { // exit by evaluating an empty expression
char* ln = NULL; char* ln = NULL;
size_t gl = 0; size_t gl = 0;
if (!silentREPL) printf(" ");
i64 read = getline(&ln, &gl, stdin); i64 read = getline(&ln, &gl, stdin);
if (read<=0 || ln[0]==0) { if(!silentREPL) putchar('\n'); break; } if (read<=0 || ln[0]==0) { if(!silentREPL) putchar('\n'); break; }
if (ln[0]==10) { cont: free(ln); continue; } cbqn_runLine(ln, read);
if (ln[read-1]==10) ln[--read] = 0; free(ln);
B code;
int output; // 0-no; 1-formatter; 2-internal
i32 time = 0;
if (ln[0] == ')') {
char* cmdS = ln+1;
char* cmdE;
if (isCmd(cmdS, &cmdE, "ex ")) {
B path = fromUTF8l(cmdE);
code = path_chars(path);
output = 0;
} else if (isCmd(cmdS, &cmdE, "t ") || isCmd(cmdS, &cmdE, "time ")) {
code = fromUTF8l(cmdE);
time = -1;
output = 0;
} else if (isCmd(cmdS, &cmdE, "t:") || isCmd(cmdS, &cmdE, "time:")) {
char* repE = cmdE;
i64 am = 0;
while (*repE>='0' & *repE<='9') {
am = am*10 + (*repE - '0');
repE++;
}
if (repE==cmdE) { printf("time command not given repetition count\n"); goto cont; }
if (am==0) { printf("repetition count was zero\n"); goto cont; }
code = fromUTF8l(repE);
time = am;
output = 0;
} else if (isCmd(cmdS, &cmdE, "mem ")) {
bool sizes = 0;
bool types = 0;
bool freed = 0;
char c;
while ((c=*(cmdE++)) != 0) {
if (c=='t') types=1;
if (c=='s') sizes=1;
if (c=='f') freed=1;
}
heap_printInfo(sizes, types, freed);
goto cont;
} else if (isCmd(cmdS, &cmdE, "erase ")) {
char* name = cmdE;
i64 len = strlen(name);
ScopeExt* e = gsc->ext;
if (e!=NULL) {
i32 am = e->varAm;
for (i32 i = 0; i < am; i++) {
B c = e->vars[i+am];
if (a(c)->ia != len) continue;
SGetU(c)
bool ok = true;
for (i32 j = 0; j < len; j++) ok&= o2cu(GetU(c, j))==name[j];
if (ok) {
B val = e->vars[i];
e->vars[i] = bi_noVar;
dec(val);
#if ENABLE_GC
if (!gc_depth) gc_forceGC();
#endif
goto cont;
}
}
}
printf("No such variable found\n");
goto cont;
} else if (isCmd(cmdS, &cmdE, "vars")) {
B r = listVars(gsc);
if (q_N(r)) {
printf("Couldn't list variables\n");
} else {
usz ia = a(r)->ia;
B* rp = harr_ptr(r);
for (usz i = 0; i < ia; i++) {
if (i!=0) printf(", ");
printRaw(rp[i]);
}
putchar('\n');
}
goto cont;
} else if (isCmd(cmdS, &cmdE, "gc ")) {
#if ENABLE_GC
if (0==*cmdE) {
if (gc_depth!=0) {
printf("GC is disabled, but forcibly GCing anyway\n");
gc_enable();
gc_forceGC();
gc_disable();
} else {
gc_forceGC();
}
} else if (strcmp(cmdE,"on")==0) {
if (gc_depth==0) printf("GC already on\n");
else if (gc_depth>1) printf("GC cannot be enabled\n");
else {
gc_enable();
printf("GC enabled\n");
}
} else if (strcmp(cmdE,"off")==0) {
if (gc_depth>0) printf("GC already off\n");
else {
gc_disable();
printf("GC disabled\n");
}
} else printf("Unknown GC command\n");
#else
printf("Macro ENABLE_GC was false at compile-time, cannot GC\n");
#endif
goto cont;
} else if (isCmd(cmdS, &cmdE, "internalPrint ")) {
code = fromUTF8l(cmdE);
output = 2;
} else {
printf("Unknown REPL command\n");
goto cont;
}
} else {
code = fromUTF8l(ln);
output = 1;
}
Block* block = bqn_compSc(code, inc(replPath), emptySVec(), gsc, true);
ptr_dec(gsc->body);
gsc->body = ptr_inc(block->bodies[0]);
B res;
if (time) {
f64 t;
if (time==-1) {
u64 sns = nsTime();
res = execBlockInline(block, gsc);
u64 ens = nsTime();
t = ens-sns;
} else {
u64 sns = nsTime();
for (i64 i = 0; i < time; i++) dec(execBlockInline(block, gsc));
u64 ens = nsTime();
t = (ens-sns)*1.0 / time;
res = m_c32(0);
}
if (t<1e3) printf("%.5gns\n", t);
else if (t<1e6) printf("%.4gus\n", t/1e3);
else if (t<1e9) printf("%.4gms\n", t/1e6);
else printf("%.5gs\n", t/1e9);
} else {
res = execBlockInline(block, gsc);
}
ptr_dec(block);
if (output) {
if (output!=2 && FORMATTER) {
B resFmt = bqn_fmt(res);
printRaw(resFmt); dec(resFmt);
putchar('\n');
} else {
print(res); putchar('\n'); fflush(stdout);
dec(res);
}
} else dec(res);
#ifdef HEAP_VERIFY
heapVerify();
#endif
gc_maybeGC();
goto cont;
} }
popCatch();
} }
#ifdef HEAP_VERIFY #ifdef HEAP_VERIFY
heapVerify(); heapVerify();
@ -339,3 +354,4 @@ int main(int argc, char* argv[]) {
bqn_exit(0); bqn_exit(0);
#undef INIT #undef INIT
} }
#endif