diff options
Diffstat (limited to 'operators.c')
-rw-r--r-- | operators.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/operators.c b/operators.c new file mode 100644 index 0000000..ba999bd --- /dev/null +++ b/operators.c @@ -0,0 +1,64 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune primmonopnames[] = L"¨⍨⌸⌶&"; +Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺"; + +opmonad monadoperatordefs[] = { + 0, /* ¨ */ + opSwitch, /* ⍨ */ + 0, /* ⌸ */ + 0, /* ⌶ */ + 0, /* & */ +}; + +opdyad dyadoperatordefs[] = { + 0, /* ⍣ */ + 0, /* . */ + 0, /* ∘ */ + 0, /* ⍤ */ + opOver, /* ⍥ */ + 0, /* @ */ + 0, /* ⍠ */ + 0, /* ⌺ */ +}; + +/* Monadic operators */ +Array * +opSwitch(Datum *lefto, Array *left, Array *right) +{ + if(lefto->tag == ArrayTag){ + incref(lefto->array); + return lefto->array; + }else if(lefto->tag == FunctionTag){ + if(left) + return runfunc(lefto->func, right, left); + else + return runfunc(lefto->func, right, right); + }else + return nil; +} + +/* Dyadic operators */ +Array * +opOver(Datum *lefto, Datum *righto, Array *left, Array *right) +{ + if(lefto->tag != FunctionTag || righto->tag != FunctionTag) + return nil; + if(left){ + Array *r = runfunc(righto->func, nil, right); + Array *l = runfunc(righto->func, nil, left); + Array *res = runfunc(lefto->func, l, r); + freearray(r); + freearray(l); + return res; + }else{ + Array *tmp = runfunc(righto->func, nil, right); + Array *res = runfunc(lefto->func, nil, tmp); + freearray(tmp); + return res; + } +}
\ No newline at end of file |