diff options
-rw-r--r-- | apl9.h | 7 | ||||
-rw-r--r-- | eval.c | 24 | ||||
-rw-r--r-- | functions.c | 14 | ||||
-rw-r--r-- | hybrids.c | 21 | ||||
-rw-r--r-- | lexer.c | 6 | ||||
-rw-r--r-- | mkfile | 1 |
6 files changed, 63 insertions, 10 deletions
@@ -29,6 +29,7 @@ typedef enum { OperatortypeDop, OperatortypePrim, + OperatortypeHybrid, } operatorType; typedef enum @@ -37,6 +38,7 @@ typedef enum FunctypePrim, FunctypeOp, FunctypeQuad, + FunctypeHybrid, } functionType; typedef enum @@ -122,6 +124,7 @@ struct Datum Statement stmt; Function func; Operator operator; + int hybrid; Symbol *symbol; }; }; @@ -274,11 +277,13 @@ extern int datasizes[]; /* array.c */ extern Rune primfuncnames[]; /* functions.c */ extern Rune primmonopnames[]; /* operators.c */ extern Rune primdyadopnames[]; /* operators.c */ -extern Rune primhybridnames[]; /* lexer.c */ +extern Rune primhybridnames[]; /* hybrids.c */ extern fnmonad monadfunctiondefs[]; /* functions.c */ extern fndyad dyadfunctiondefs[]; /* functions.c */ extern opmonad monadoperatordefs[]; /* operators.c */ extern opdyad dyadoperatordefs[]; /* operators.c */ +extern fndyad hybridfunctiondefs[]; /* hybrids.c */ +extern opmonad hybridoperatordefs[]; /* hybrids.c */ extern Symtab *globalsymtab; /* symbol.c */ extern Symtab *currentsymtab; /* symbol.c */ extern int alloccounts; /* memory.c */ @@ -22,8 +22,8 @@ Datum *lookup(Datum); int bindingstrengths[11][11] = { /* A F H MO DO AF ( ) ← IS N */ - 6, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, /* A */ - 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, /* F */ + 6, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, /* A */ + 2, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, /* F */ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, /* H */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */ 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */ @@ -37,8 +37,8 @@ int bindingstrengths[11][11] = { evalfn evalfns[11][11] = { /* A F H MO DO AF ( ) ← IS N */ - strand, dyadfun, 0, monadop, 0, 0, 0, 0, 0, 0, 0, /* A */ - monadfun, 0, 0, monadop, 0, 0, 0, 0, 0, 0, 0, /* F */ + strand, dyadfun, dyadfun, monadop, 0, 0, 0, 0, 0, 0, 0, /* A */ + monadfun, 0, monadop, monadop, 0, 0, 0, 0, 0, 0, 0, /* F */ 0, 0, 0, monadop, 0, 0, 0, 0, 0, 0, 0, /* H */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */ dyadop, dyadop, dyadop, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */ @@ -192,8 +192,13 @@ dyadfun(Datum left, Datum right) traceprint("Applying left argument to function\n"); Datum result; result.shy = 0; - result.tag = BoundFunctionTag, - result.func = right.func; + result.tag = BoundFunctionTag; + if(right.tag == FunctionTag) + result.func = right.func; + else if(right.tag == HybridTag){ + result.func.type = FunctypeHybrid; + result.func.code = right.hybrid; + } result.func.left = left.array; incref(left.array); return result; @@ -256,7 +261,12 @@ monadop(Datum left, Datum right) result.shy = 0; result.tag = FunctionTag, result.func.type = FunctypeOp; - result.func.operator = right.operator; + if(right.tag == MonadicOpTag || right.tag == DyadicOpTag) + result.func.operator = right.operator; + else{ + result.func.operator.type = OperatortypeHybrid; + result.func.operator.code = right.hybrid; + } result.func.operator.left = arg; result.func.left = nil; if(arg->tag == ArrayTag) diff --git a/functions.c b/functions.c index 3e5c902..3d62828 100644 --- a/functions.c +++ b/functions.c @@ -158,6 +158,13 @@ runfunc(Function f, Array *left, Array *right) } return m(right); } + }else if(f.type == FunctypeOp && f.operator.type == OperatortypeHybrid){ + opmonad m = hybridoperatordefs[f.operator.code]; + if(m == nil){ + Rune *err = runesmprint("monadic %C", primhybridnames[f.operator.code]); + throwerror(err, ENotImplemented); + } + return m(f.operator.left, left, right); }else if(f.type == FunctypeOp){ /* TODO assumes prim op, not dop */ if(f.operator.dyadic){ @@ -189,6 +196,13 @@ runfunc(Function f, Array *left, Array *right) } return f.quad->monadfn(right); } + }else if(f.type == FunctypeHybrid){ + fndyad d = hybridfunctiondefs[f.code]; + if(d == nil){ + Rune *err = runesmprint("dyadic %C", primhybridnames[f.code]); + throwerror(err, ENotImplemented); + } + return d(left, right); }else return nil; } diff --git a/hybrids.c b/hybrids.c new file mode 100644 index 0000000..3483d42 --- /dev/null +++ b/hybrids.c @@ -0,0 +1,21 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "apl9.h" + +Rune primhybridnames[] = L"/\⌿⍀"; + +fndyad hybridfunctiondefs[] = { + 0, /* / */ + 0, /* \ */ + 0, /* ⌿ */ + 0, /* ⍀ */ +}; + +opmonad hybridoperatordefs[] = { + 0, /* / */ + 0, /* \ */ + 0, /* ⌿ */ + 0, /* ⍀ */ +};
\ No newline at end of file @@ -4,8 +4,6 @@ #include "apl9.h" -Rune primhybridnames[] = L"/\⌿⍀"; - Statement * lexline(Rune *line, int toplevel) { @@ -101,6 +99,10 @@ lexline(Rune *line, int toplevel) stmt->toks[stmt->ntoks].operator.dyadic = 1; stmt->toks[stmt->ntoks].operator.code = p-primdyadopnames; offset++; + }else if(p = runestrchr(primhybridnames, line[offset])){ + stmt->toks[stmt->ntoks].tag = HybridTag; + stmt->toks[stmt->ntoks].hybrid = p-primhybridnames; + offset++; }else if(isdigitrune(line[offset]) || (line[offset] == L'¯' && isdigitrune(line[offset+1]))){ char buf[64]; char *p = buf; @@ -13,6 +13,7 @@ OFILES=\ operators.$O\ quadnames.$O\ error.$O\ + hybrids.$O\ HFILES=\ apl9.h\ |