compiler errors

This commit is contained in:
dzaima 2021-06-27 20:23:48 +03:00
parent 27b1e9ed8c
commit a4446716bf
9 changed files with 118 additions and 28 deletions

View File

@ -115,7 +115,7 @@ B asrt_c1(B t, B x) {
if (isI32(x) && 1==(i32)x.u) return x; if (isI32(x) && 1==(i32)x.u) return x;
if (isF64(x) && 1==x.f) return x; if (isF64(x) && 1==x.f) return x;
dec(x); dec(x);
thrM("assertion error"); thrM("Assertion error");
} }
B asrt_c2(B t, B w, B x) { B asrt_c2(B t, B w, B x) {
if (isI32(x) && 1==(u32)x.u) { dec(w); return x; } if (isI32(x) && 1==(u32)x.u) { dec(w); return x; }
@ -123,6 +123,31 @@ B asrt_c2(B t, B w, B x) {
dec(x); dec(x);
thr(w); thr(w);
} }
B casrt_c1(B t, B x) {
if (isI32(x) && 1==(i32)x.u) return x;
if (isF64(x) && 1==x.f) return x;
unwindCompiler();
dec(x);
thrM("Compilation error");
}
B casrt_c2(B t, B w, B x) {
if (isI32(x) && 1==(u32)x.u) { dec(w); return x; }
if (isF64(x) && 1==x.f) { dec(w); return x; }
unwindCompiler();
dec(x);
if (isArr(w) && a(w)->ia==2) {
B w0 = TI(w).getU(w,0);
if (!isArr(w0) || a(w0)->ia<2) goto base;
B s = TI(w).get(w,1);
BS2B w0getU = TI(w0).getU;
AFMT("\n ");
s = vm_fmtPoint(comp_currSrc, s, o2s(w0getU(w0,0)), o2s(w0getU(w0,1))+1);
dec(w);
thr(s);
}
base:
thr(w);
}
B sys_c1(B t, B x); B sys_c1(B t, B x);
B out_c1(B t, B x) { printRaw(x); putchar('\n'); return x; } B out_c1(B t, B x) { printRaw(x); putchar('\n'); return x; }

View File

@ -113,14 +113,14 @@ NOINLINE B append_fmt(B s, char* p, ...) {
char* lp = p; char* lp = p;
while (*p != 0) { c = *p++; while (*p != 0) { c = *p++;
if (c!='%') continue; if (c!='%') continue;
if (lp!=p-1) s = vec_join(s, fromUTF8(lp, p-1-lp)); if (lp!=p-1) AJOIN(fromUTF8(lp, p-1-lp));
switch(c = *p++) { default: printf("Unknown format character '%c'", c); UD; switch(c = *p++) { default: printf("Unknown format character '%c'", c); UD;
case 'R': { // TODO proper case 'R': { // TODO proper
B b = va_arg(a, B); B b = va_arg(a, B);
if (isNum(b)) { if (isNum(b)) {
AFMT("%f", o2f(b)); AFMT("%f", o2f(b));
} else { assert(isArr(b) && rnk(b)==1); } else { assert(isArr(b) && rnk(b)==1);
s = vec_join(s, inc(b)); AJOIN(inc(b));
} }
break; break;
} }
@ -203,7 +203,7 @@ NOINLINE B append_fmt(B s, char* p, ...) {
} }
lp = p; lp = p;
} }
if (lp!=p) s = vec_join(s, fromUTF8(lp, p-lp)); if (lp!=p) AJOIN(fromUTF8(lp, p-lp));
va_end(a); va_end(a);
return s; return s;
} }

View File

@ -103,8 +103,11 @@ static bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
B m_str8l(char* s); B m_str8l(char* s);
B fromUTF8l(char* x); B fromUTF8l(char* x);
#define A8(X) s = vec_join(s,m_str8l(X)) #define AJOIN(X) s = vec_join(s,X) // consumes X
#define AU(X) s = vec_join(s,fromUTF8l(X)) #define AOBJ(X) s = vec_add(s,X) // consumes X
#define ACHR(X) AOBJ(m_c32(X))
#define A8(X) AJOIN(m_str8l(X))
#define AU(X) AJOIN(fromUTF8l(X))
#define AFMT(...) s = append_fmt(s, __VA_ARGS__) #define AFMT(...) s = append_fmt(s, __VA_ARGS__)
NOINLINE B append_fmt(B s, char* p, ...); NOINLINE B append_fmt(B s, char* p, ...);
@ -255,5 +258,7 @@ static inline void onFree(Value* x) {
} }
extern _Thread_local i64 comp_envPos;
extern _Thread_local B comp_currPath; extern _Thread_local B comp_currPath;
extern _Thread_local B comp_currArgs; extern _Thread_local B comp_currArgs;
extern _Thread_local B comp_currSrc;

View File

@ -265,7 +265,6 @@ jmp_buf* prepareCatch();
#endif #endif
void popCatch(); void popCatch();
extern B catchMessage; extern B catchMessage;
extern u64 envPrevHeight; // envStart+prevEnvHeight will give the original envCurr

View File

@ -53,8 +53,10 @@ B r1Objs[rtLen];
B rtWrap_wrap(B x); // consumes B rtWrap_wrap(B x); // consumes
_Thread_local i64 comp_envPos;
_Thread_local B comp_currPath; _Thread_local B comp_currPath;
_Thread_local B comp_currArgs; _Thread_local B comp_currArgs;
_Thread_local B comp_currSrc;
B rt_merge, rt_undo, rt_select, rt_slash, rt_join, rt_ud, rt_pick,rt_take, rt_drop, B rt_merge, rt_undo, rt_select, rt_slash, rt_join, rt_ud, rt_pick,rt_take, rt_drop,
rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_cell; rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_cell;
@ -95,19 +97,24 @@ B bqn_repr(B x) { // consumes
void load_gcFn() { void load_gcFn() {
mm_visit(comp_currPath); mm_visit(comp_currPath);
mm_visit(comp_currArgs); mm_visit(comp_currArgs);
mm_visit(comp_currSrc);
} }
NOINLINE Block* bqn_comp(B str, B path, B args) { // consumes all NOINLINE Block* bqn_comp(B str, B path, B args) { // consumes all
comp_currPath = path; comp_currPath = path;
comp_currArgs = args; comp_currArgs = args;
comp_currSrc = str;
comp_envPos = envCurr-envStart;
Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str, NULL); Block* r = load_compObj(c2(load_comp, inc(load_compArg), inc(str)), str, NULL);
dec(path); dec(args); dec(path); dec(args);
comp_currArgs = comp_currPath = bi_N; comp_currPath = comp_currArgs = comp_currSrc = bi_N;
return r; return r;
} }
NOINLINE Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl) { // consumes str,path,args NOINLINE Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl) { // consumes str,path,args
comp_currPath = path; comp_currPath = path;
comp_currArgs = args; comp_currArgs = args;
comp_currSrc = str;
comp_envPos = envCurr-envStart;
B vName = inc(bi_emptyHVec); B vName = inc(bi_emptyHVec);
B vDepth = inc(bi_emptyIVec); B vDepth = inc(bi_emptyIVec);
if (repl && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope"); if (repl && (!sc || sc->psc)) thrM("VM compiler: REPL mode must be used at top level scope");
@ -129,7 +136,7 @@ NOINLINE Block* bqn_compSc(B str, B path, B args, Scope* sc, bool repl) { // con
} }
Block* r = load_compObj(c2(load_comp, m_v4(inc(load_rtObj), inc(bi_sys), vName, vDepth), inc(str)), str, sc); Block* r = load_compObj(c2(load_comp, m_v4(inc(load_rtObj), inc(bi_sys), vName, vDepth), inc(str)), str, sc);
dec(path); dec(args); dec(path); dec(args);
comp_currArgs = comp_currPath = bi_N; comp_currPath = comp_currArgs = comp_currSrc = bi_N;
return r; return r;
} }
@ -147,6 +154,7 @@ void bqn_setComp(B comp) { // consumes; doesn't unload old comp, but whatever
static inline void load_init() { // very last init function static inline void load_init() { // very last init function
comp_currPath = bi_N; comp_currPath = bi_N;
comp_currArgs = bi_N; comp_currArgs = bi_N;
comp_currSrc = 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_root , bi_floor, bi_ceil , bi_stile , bi_not, /* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_root , bi_floor, bi_ceil , bi_stile , bi_not,
@ -265,9 +273,12 @@ static inline void load_init() { // very last init function
printAllocStats(); printAllocStats();
exit(0); exit(0);
#else // use compiler #else // use compiler
B prevAsrt = runtime[42];
runtime[42] = bi_casrt; // horrible but GC is off so it's fiiiiiine
Block* comp_b = load_compImport( Block* comp_b = load_compImport(
#include "gen/compiler" #include "gen/compiler"
); );
runtime[42] = prevAsrt;
load_comp = m_funBlock(comp_b, 0); ptr_dec(comp_b); load_comp = m_funBlock(comp_b, 0); ptr_dec(comp_b);
gc_add(load_comp); gc_add(load_comp);

View File

@ -141,7 +141,7 @@ int main(int argc, char* argv[]) {
if (startREPL) { if (startREPL) {
repl_init(); repl_init();
while (CATCH) { while (CATCH) {
printf("Error: "); print(catchMessage); putchar('\n'); printf("Error: "); printErrMsg(catchMessage); putchar('\n');
vm_pst(envCurr+1, envStart+envPrevHeight); vm_pst(envCurr+1, envStart+envPrevHeight);
dec(catchMessage); dec(catchMessage);
#ifdef HEAP_VERIFY #ifdef HEAP_VERIFY

View File

@ -7,7 +7,7 @@
/* sfns.c*/A(shape,"") A(pick,"") A(pair,"{𝕨‿𝕩}") A(select,"") A(slash,"/") A(join,"") A(couple,"") A(shiftb,"»") A(shifta,"«") A(take,"") A(drop,"") A(group,"") A(reverse,"") \ /* sfns.c*/A(shape,"") A(pick,"") A(pair,"{𝕨‿𝕩}") A(select,"") A(slash,"/") A(join,"") A(couple,"") A(shiftb,"»") A(shifta,"«") A(take,"") A(drop,"") A(group,"") A(reverse,"") \
/* sort.c*/A(gradeUp,"") A(gradeDown,"") \ /* sort.c*/A(gradeUp,"") A(gradeDown,"") \
/* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \ /* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \
/* sysfn.c*/M(repr,"•Repr") A(asrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(exit,"•Exit") \ /* sysfn.c*/M(repr,"•Repr") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(exit,"•Exit") \
/*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \ /*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \
/*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") /*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare")

View File

@ -5,6 +5,11 @@
#include "ns.h" #include "ns.h"
#include "utils/utf.h" #include "utils/utf.h"
#include "utils/talloc.h" #include "utils/talloc.h"
#include "utils/mut.h"
#ifndef UNWIND_COMPILER // whether to hide stackframes of the compiler in compiling errors
#define UNWIND_COMPILER 1
#endif
#define FOR_BC(F) F(PUSH) F(VARO) F(VARM) F(ARRO) F(ARRM) F(FN1C) F(FN2C) F(OP1D) F(OP2D) F(TR2D) \ #define FOR_BC(F) F(PUSH) F(VARO) F(VARM) F(ARRO) F(ARRM) F(FN1C) F(FN2C) F(OP1D) F(OP2D) F(TR2D) \
F(TR3D) F(SETN) F(SETU) F(SETM) F(POPS) F(DFND) F(FN1O) F(FN2O) F(CHKV) F(TR3O) \ F(TR3D) F(SETN) F(SETU) F(SETM) F(POPS) F(DFND) F(FN1O) F(FN2O) F(CHKV) F(TR3O) \
@ -815,26 +820,50 @@ void popCatch() {
#endif #endif
} }
NOINLINE B vm_fmtPoint(B src, B prepend, usz cs, usz ce) { // consumes prepend
BS2B srcGetU = TI(src).getU;
i64 padEnd = (i64)a(prepend)->ia;
i64 padStart = padEnd;
while (padStart>0 && o2cu(srcGetU(prepend,padStart-1))!='\n') padStart--;
B s = prepend;
usz srcL = a(src)->ia;
usz srcS = cs;
while (srcS>0 && o2cu(srcGetU(src,srcS-1))!='\n') srcS--;
usz srcE = srcS;
while (srcE<srcL) { if(o2cu(srcGetU(src, srcE))=='\n') break; srcE++; }
if (ce>srcE) ce = srcE;
B srcSl = TI(src).slice(inc(src),srcS); arr_shVec(srcSl, srcE-srcS);
AJOIN(srcSl);
cs-= srcS;
ce-= srcS;
ACHR('\n');
for (i64 i = padStart; i < padEnd; i++) ACHR(' ');
for (i32 i = 0; i < cs; i++) ACHR(o2cu(srcGetU(src, srcS+i))=='\t'? '\t' : ' '); // ugh tabs
for (i32 i = cs; i < ce; i++) ACHR('^');
return s;
}
NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) { NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) {
B src = comp->src; B src = comp->src;
if (!isNothing(src) && !isNothing(comp->indices)) { if (!isNothing(src) && !isNothing(comp->indices)) {
B inds = TI(comp->indices).getU(comp->indices, 0); usz cs = o2s(TI(inds).getU(inds,bcPos)); B inds = TI(comp->indices).getU(comp->indices, 0); usz cs = o2s(TI(inds).getU(inds,bcPos));
B inde = TI(comp->indices).getU(comp->indices, 1); usz ce = o2s(TI(inde).getU(inde,bcPos))+1; B inde = TI(comp->indices).getU(comp->indices, 1); usz ce = o2s(TI(inde).getU(inde,bcPos))+1;
int start = pos==-1? 0 : printf(N64d": ", pos); // printf(" bcPos=%d\n", bcPos); // in case the pretty error generator is broken
usz srcL = a(src)->ia; // printf(" inds:%d…%d\n", cs, ce);
BS2B srcGetU = TI(src).getU; // int start = pos==-1? 0 : printf(N64d": ", pos);
usz srcS = cs; // usz srcL = a(src)->ia;
while (srcS>0 && o2cu(srcGetU(src,srcS-1))!='\n') srcS--; // BS2B srcGetU = TI(src).getU;
usz srcE = srcS; // usz srcS = cs; while (srcS>0 && o2cu(srcGetU(src,srcS-1))!='\n') srcS--;
while (srcE<srcL) { u32 chr = o2cu(srcGetU(src, srcE)); if(chr=='\n')break; printUTF8(chr); srcE++; } // usz srcE = srcS; while (srcE<srcL) { u32 chr = o2cu(srcGetU(src, srcE)); if(chr=='\n')break; printUTF8(chr); srcE++; }
if (ce>srcE) ce = srcE; // if (ce>srcE) ce = srcE;
cs-= srcS; // cs-= srcS; ce-= srcS;
ce-= srcS; // putchar('\n');
// for (i32 i = 0; i < cs+start; i++) putchar(' ');
// for (i32 i = cs; i < ce; i++) putchar('^');
// putchar('\n');
B s = inc(bi_emptyCVec); if (pos!=-1) AFMT("%l: ", pos);
printRaw(vm_fmtPoint(src, s, cs, ce));
putchar('\n'); putchar('\n');
for (i32 i = 0; i < cs+start; i++) putchar(' ');
for (i32 i = cs; i < ce; i++) putchar('^');
putchar('\n');
// printf(" inds:%d…%d\n", cinds, cinde);
} else { } else {
if (pos!=-1) printf(N64d": ", pos); if (pos!=-1) printf(N64d": ", pos);
printf("source unknown\n"); printf("source unknown\n");
@ -861,13 +890,31 @@ NOINLINE void vm_pstLive() {
vm_pst(envStart, envCurr+1); vm_pst(envStart, envCurr+1);
} }
static void unwindEnv(Env* envNew) { // envNew==envStart-1 for emptying the env stack void unwindEnv(Env* envNew) {
assert(envNew<=envCurr); assert(envNew<=envCurr);
while (envCurr!=envNew) { while (envCurr!=envNew) {
envCurr->bcV = BCPOS(envCurr->sc->body, envCurr->bcL); envCurr->bcV = BCPOS(envCurr->sc->body, envCurr->bcL);
envCurr--; envCurr--;
} }
} }
void unwindCompiler() {
#if UNWIND_COMPILER
unwindEnv(envStart+comp_envPos);
#endif
}
NOINLINE void printErrMsg(B msg) {
if (isArr(msg)) {
BS2B msgGetU = TI(msg).getU;
usz msgLen = a(msg)->ia;
for (usz i = 0; i < msgLen; i++) if (!isC32(msgGetU(msg,i))) goto base;
printRaw(msg);
return;
}
base:
print(msg);
}
NOINLINE NORETURN void thr(B msg) { NOINLINE NORETURN void thr(B msg) {
// printf("gStack %p-%p:\n", gStackStart, gStack); B* c = gStack; // printf("gStack %p-%p:\n", gStackStart, gStack); B* c = gStack;
@ -888,7 +935,7 @@ NOINLINE NORETURN void thr(B msg) {
longjmp(cf->jmp, 1); longjmp(cf->jmp, 1);
} }
assert(cf==cfStart); assert(cf==cfStart);
printf("Error: "); print(msg); putchar('\n'); fflush(stdout); printf("Error: "); printErrMsg(msg); putchar('\n'); fflush(stdout);
Env* envEnd = envCurr+1; Env* envEnd = envCurr+1;
unwindEnv(envStart-1); unwindEnv(envStart-1);
vm_pst(envCurr+1, envEnd); vm_pst(envCurr+1, envEnd);

View File

@ -167,7 +167,10 @@ static inline void popEnv() {
void vm_pst(Env* s, Env* e); void vm_pst(Env* s, Env* e);
void vm_pstLive(); void vm_pstLive();
void vm_printPos(Comp* comp, i32 bcPos, i64 pos); void vm_printPos(Comp* comp, i32 bcPos, i64 pos);
NOINLINE B vm_fmtPoint(B src, B prepend, usz cs, usz ce); // consumes prepend
NOINLINE void printErrMsg(B msg);
NOINLINE void unwindEnv(Env* envNew); // envNew==envStart-1 for emptying the env stack
NOINLINE void unwindCompiler(); // unwind to the env of the invocation of the compiler; UB when not in compiler!
typedef struct FldAlias { typedef struct FldAlias {