summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c192
1 files changed, 91 insertions, 101 deletions
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;