summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-21 16:05:41 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-21 16:05:41 +0000
commit80ebae7887e21f58ef09a18515e5521c5162053c (patch)
tree6b62ff6497d44fc9fe5c05b9a92a65cf2efee386
parente12450d52dce2d6271d12720bf18175d082a0003 (diff)
Get ready for hybrids
-rw-r--r--apl9.h7
-rw-r--r--eval.c24
-rw-r--r--functions.c14
-rw-r--r--hybrids.c21
-rw-r--r--lexer.c6
-rw-r--r--mkfile1
6 files changed, 63 insertions, 10 deletions
diff --git a/apl9.h b/apl9.h
index d51bde1..11643d5 100644
--- a/apl9.h
+++ b/apl9.h
@@ -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 */
diff --git a/eval.c b/eval.c
index bfe211e..1070cb2 100644
--- a/eval.c
+++ b/eval.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
diff --git a/lexer.c b/lexer.c
index 626d181..303951d 100644
--- a/lexer.c
+++ b/lexer.c
@@ -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;
diff --git a/mkfile b/mkfile
index ba72c81..ab00568 100644
--- a/mkfile
+++ b/mkfile
@@ -13,6 +13,7 @@ OFILES=\
operators.$O\
quadnames.$O\
error.$O\
+ hybrids.$O\
HFILES=\
apl9.h\