From 40c021d964bc60d2b60dd78022e180c964ea1b67 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 21 Jan 2022 15:18:22 +0000 Subject: Implement better error handling, but still no error guards --- functions.c | 192 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 91 insertions(+), 101 deletions(-) (limited to 'functions.c') diff --git a/functions.c b/functions.c index 55a72ad..3e5c902 100644 --- a/functions.c +++ b/functions.c @@ -143,21 +143,52 @@ runfunc(Function f, Array *left, Array *right) currentsymtab = tmpsymtab; return (*dfnres).array; /* TODO what if the evaluation failed */ }else if(f.type == FunctypePrim){ - if(left) - return dyadfunctiondefs[f.code](left, right); - else - return monadfunctiondefs[f.code](right); + if(left){ + fndyad d = dyadfunctiondefs[f.code]; + if(d == nil){ + Rune *err = runesmprint("dyadic %C", primfuncnames[f.code]); + throwerror(err, ENotImplemented); + } + return d(left, right); + }else{ + fnmonad m = monadfunctiondefs[f.code]; + if(m == nil){ + Rune *err = runesmprint("monadic %C", primfuncnames[f.code]); + throwerror(err, ENotImplemented); + } + return m(right); + } }else if(f.type == FunctypeOp){ /* TODO assumes prim op, not dop */ - if(f.operator.dyadic) - return dyadoperatordefs[f.operator.code](f.operator.left, f.operator.right, left, right); - else - return monadoperatordefs[f.operator.code](f.operator.left, left, right); + if(f.operator.dyadic){ + opdyad d = dyadoperatordefs[f.operator.code]; + if(d == nil){ + Rune *err = runesmprint("dyadic %C", primdyadopnames[f.operator.code]); + throwerror(err, ENotImplemented); + } + return d(f.operator.left, f.operator.right, left, right); + }else{ + opmonad m = monadoperatordefs[f.operator.code]; + if(m == nil){ + Rune *err = runesmprint("monadic %C", primmonopnames[f.operator.code]); + throwerror(err, ENotImplemented); + } + return m(f.operator.left, left, right); + } }else if(f.type == FunctypeQuad){ - if(left) + if(left){ + if(f.quad->dyadfn == nil){ + Rune *err = runesmprint("dyadic %S", f.quad->name); + throwerror(err, ENotImplemented); + } return f.quad->dyadfn(left, right); - else + }else{ + if(f.quad->monadfn == nil){ + Rune *err = runesmprint("monadic %S", f.quad->name); + throwerror(err, ENotImplemented); + } return f.quad->monadfn(right); + } }else return nil; } @@ -306,10 +337,8 @@ fnEnclose(Array *right) Array * fnGradeUp(Array *right) { - if(right->rank == 0){ - print("Rank 0 not allowed in ⍋\n"); - exits("rank"); - } + if(right->rank == 0) + throwerror(nil, ERank); int i,j; int len = right->shape[0]; @@ -488,16 +517,12 @@ fnPlus(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++){ @@ -519,16 +544,12 @@ fnMinus(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++){ @@ -550,16 +571,12 @@ fnTimes(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++){ @@ -581,16 +598,12 @@ fnDivide(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 1); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++) @@ -608,16 +621,12 @@ fnPower(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++){ @@ -639,16 +648,12 @@ fnLogarithm(Array *left, Array *right) Array *leftarr; Array *rightarr; int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok){ - print("Ranks don't match lol\n"); - exits(nil); - } + if(!rankok) + throwerror(nil, ERank); int typeok = commontype(leftarr, rightarr, &left, &right, 1); - if(!typeok){ - print("Types don't match lol\n"); - exits(nil); - } + if(!typeok) + throwerror(nil, EType); Array *res = duparray(left); for(int i = 0; i < left->size; i++) @@ -686,10 +691,12 @@ fnMatch(Array *left, Array *right) Array * fnTake(Array *left, Array *right) { - if(left->type != AtypeInt || left->rank > 1 || left->size > right->rank){ - print("Invalid left arg to ↑\n"); - exits(nil); - } + if(left->type != AtypeInt) + throwerror(nil, EType); + if(left->rank > 1) + throwerror(nil, ERank); + if(left->size > right->rank) + throwerror(nil, ELength); int i; if(left->size == right->rank) @@ -749,18 +756,12 @@ fnIndex(Array *left, Array *right) int io = currentsymtab->io; int i; - if(left->rank > 1){ - print("Index vector rank too large\n"); - exits(nil); - } - if(left->type != AtypeArray && left->type != AtypeInt){ - print("Index vector wrong type\n"); - exits(nil); - } - if(left->size > right->rank){ - print("Index vector too long\n"); - exits(nil); - } + if(left->rank > 1) + throwerror(nil, ERank); + if(left->type != AtypeArray && left->type != AtypeInt) + throwerror(nil, EType); + if(left->size > right->rank) + throwerror(nil, ELength); /* extend left index vector to full format */ Array *oldleft = left; @@ -772,22 +773,16 @@ fnIndex(Array *left, Array *right) left->arraydata[i] = fnIndexGenerator(n); freearray(n); }else if(oldleft->type == AtypeInt){ - if(oldleft->intdata[i] < io || oldleft->intdata[i] >= io + right->shape[i]){ - print("Index error\n"); - exits(nil); - } + if(oldleft->intdata[i] < io || oldleft->intdata[i] >= io + right->shape[i]) + throwerror(nil, EIndex); left->arraydata[i] = mkscalarint(oldleft->intdata[i]); }else if(oldleft->type == AtypeArray){ Array *sub = oldleft->arraydata[i]; - if(sub->type != AtypeInt){ - print("Type error\n"); - exits(nil); - } + if(sub->type != AtypeInt) + throwerror(nil, EType); for(int j = 0; j < sub->size; j++){ - if(sub->intdata[j] < io || sub->intdata[j] >= io + right->shape[i]){ - print("Index error\n"); - exits(nil); - } + if(sub->intdata[j] < io || sub->intdata[j] >= io + right->shape[i]) + throwerror(nil, EIndex); } left->arraydata[i] = oldleft->arraydata[i]; incref(left->arraydata[i]); @@ -846,8 +841,8 @@ fnIndex(Array *left, Array *right) Array * fnCatenateFirst(Array *left, Array *right) { - Array *leftarr; - Array *rightarr; + Array *leftarr = nil; + Array *rightarr = nil; if(left->rank == 0 && right->rank != 0){ /* extend left to right->rank with first axis=1 */ @@ -890,17 +885,12 @@ fnCatenateFirst(Array *left, Array *right) }else if(right->rank == left->rank){ leftarr = fnSame(left); rightarr = fnSame(right); - }else{ - print("Ranks don't match\n"); - exits(nil); - return nil; - } + }else + throwerror(nil, ERank); for(int i = 1; i < leftarr->rank; i++) - if(leftarr->shape[i] != rightarr->shape[i]){ - print("Shapes don't match, lol\n"); - exits(nil); - } + if(leftarr->shape[i] != rightarr->shape[i]) + throwerror(nil, EShape); } int type, rank, leftsize, rightsize; -- cgit v1.2.3