From ae6471f1c94f51df540d95edc09c7749002f44e8 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Tue, 22 Feb 2022 20:41:56 +0000 Subject: Implement some form of error guards. It may not be perfect yet --- error.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'error.c') diff --git a/error.c b/error.c index 47837a9..2a59553 100644 --- a/error.c +++ b/error.c @@ -5,7 +5,7 @@ #include "apl9.h" -ErrorHandler globalerror; +ErrorGuard *globalerrorguard; Rune *errorstrs[] = { [ESyntax] = L"SYNTAX ERROR", @@ -20,11 +20,52 @@ Rune *errorstrs[] = { [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) { - free(globalerror.msg); - globalerror.msg = msg ? runestrdup(msg) : nil; - longjmp(globalerror.jmp, 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); } -- cgit v1.2.3