#include #include #include #include #include "apl9.h" ErrorGuard *globalerrorguard; Rune *errorstrs[] = { [ESyntax] = L"SYNTAX ERROR", [EParse] = L"PARSE ERROR", [EValue] = L"VALUE ERROR", [EDomain] = L"DOMAIN ERROR", [ERank] = L"RANK ERROR", [EType] = L"TYPE ERROR", [ELength] = L"LENGTH ERROR", [EIndex] = L"INDEX ERROR", [EShape] = L"SHAPE ERROR", [ENotImplemented] = L"NOT IMPLEMENTED", }; ErrorGuard * newerrorguard(Array *codes, Statement *guard) { DfnFrame *fr = getcurrentdfn(); ErrorGuard *eg = emallocz(sizeof(ErrorGuard), 1); eg->active = 1; eg->guard = guard; if(fr == nil) 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) { ErrorGuard *matching = globalerrorguard; DfnFrame *frame = getcurrentdfn(); ThreadData *td = getthreaddata(); td->lasterror = err; if(td->lasterrormsg) free(td->lasterrormsg); td->lasterrormsg = msg; 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); }