#include #include #include #include #include "apl9.h" ErrorGuard * newerrorguard(Array *codes, Statement *guard) { ThreadData *td = getthreaddata(); DfnFrame *fr = getcurrentdfn(); ErrorGuard *eg = emallocz(sizeof(ErrorGuard), 1); eg->active = 1; eg->guard = guard; if(fr == nil) td->globalerrorguard = eg; else{ eg->next = fr->errorguards; fr->errorguards = eg; eg->frame = dupdfnframe(fr); } for(int i = 0; i < GetSize(codes); i++) eg->code |= (1<intdata[i]); return eg; } void throwerror(Rune *msg, int err) { ThreadData *td = getthreaddata(); ErrorGuard *matching = td->globalerrorguard; DfnFrame *frame = getcurrentdfn(); td->lasterror = err; if(td->lasterrormsg) free(td->lasterrormsg); td->lasterrormsg = msg ? runestrdup(msg) : nil; while(frame != nil){ for(ErrorGuard *eg = frame->errorguards; eg != nil; eg = eg->next){ if(!eg->active) continue; if(((1<code) || (eg->code == 1)){ matching = eg; goto match; } } frame = frame->prev; popdfnframe(); } match: longjmp(matching->jmp, 1); } Rune * errorstr(int code) { Rune *err; switch(code){ case ESyntax: err = L"SYNTAX ERROR"; break; case EIndex: err = L"INDEX ERROR"; break; case ERank: err = L"RANK ERROR"; break; case ELength: err = L"LENGTH ERROR"; break; case EValue: err = L"VALUE ERROR"; break; case EDomain: err = L"DOMAIN ERROR"; break; case ETimeout: err = L"TIMEOUT ERROR"; break; case ENotImplemented: err = L"NOT IMPLEMENTED"; break; default: err = L""; break; } return err; }