summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-11 17:43:24 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-11 17:43:24 +0000
commit4a92ef13f83ec4fe79d6dd815f1b9fe492a404fe (patch)
treec5c263289354c2e2fd1f4822cfac389c23a9ffb7
parentfe701a61f4d057597dab3d46ba0fe31e550b41df (diff)
Add dyadic function application, and implement dyadic ⍴
-rw-r--r--apl9.h18
-rw-r--r--eval.c29
-rw-r--r--functions.c76
3 files changed, 113 insertions, 10 deletions
diff --git a/apl9.h b/apl9.h
index bc6f894..415620d 100644
--- a/apl9.h
+++ b/apl9.h
@@ -21,13 +21,14 @@ typedef enum
typedef enum
{
AtypeInt,
- AtypeArray
+ AtypeArray,
} arrayDataType;
/* Data types */
typedef struct Array Array;
typedef struct Expr Expr;
+typedef struct Function Function;
typedef struct Datum Datum;
struct Array
@@ -50,6 +51,15 @@ struct Expr
Datum *toks;
};
+struct Function
+{
+ union {
+ int code;
+ Expr *dfn;
+ };
+ Array *left;
+};
+
struct Datum
{
datumTag tag;
@@ -57,10 +67,12 @@ struct Datum
Array *array;
int code;
Expr expr;
+ Function func;
};
};
typedef Array* (*fnmonad)(Array*);
+typedef Array* (*fndyad)(Array*, Array*);
/* Function prototypes for the different source files */
/* print.c */
@@ -90,6 +102,7 @@ Array *fnShape(Array *);
/* Dyadic functions from functions.h */
Array *fnCatenateFirst(Array *, Array *);
+Array *fnReshape(Array *, Array *);
/* Global variables */
extern Rune *errormsg; /* eval.c */
@@ -98,4 +111,5 @@ extern Rune primfuncnames[]; /* function.c */
extern Rune primmonopnames[]; /* lexer.c */
extern Rune primdyadopnames[]; /* lexer.c */
extern Rune primhybridnames[]; /* lexer.c */
-extern fnmonad monadfunctiondefs[]; /* function.c */ \ No newline at end of file
+extern fnmonad monadfunctiondefs[]; /* function.c */
+extern fndyad dyadfunctiondefs[]; /* function.c */ \ No newline at end of file
diff --git a/eval.c b/eval.c
index e50903f..1ff40ce 100644
--- a/eval.c
+++ b/eval.c
@@ -10,18 +10,19 @@ typedef Datum (*evalfn)(Datum, Datum);
Datum strand(Datum, Datum);
Datum monadfun(Datum, Datum);
+Datum dyadfun(Datum, Datum);
Datum lpar(Datum, Datum);
Datum rpar(Datum, Datum);
int bindingstrengths[12][12] = {
/* A F H MO DO AF ( ) { } [ ] */
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
+ 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* FA */
- 3, 3, 3, 3, 3, 3, 0, 4, 3, 3, 3, 3, /* ( */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
+ 4, 4, 4, 4, 4, 4, 0, 5, 4, 4, 4, 4, /* ( */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
@@ -31,12 +32,12 @@ int bindingstrengths[12][12] = {
evalfn evalfns[12][12] = {
/* A F H MO DO AF ( ) { } [ ] */
- strand, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
+ strand, dyadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* FA */
+ monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
lpar, lpar, lpar, lpar, lpar, 0, lpar, rpar, lpar, lpar, lpar, lpar, /* ( */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
@@ -45,7 +46,6 @@ evalfn evalfns[12][12] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
};
-
Datum *
eval(Datum *tokens, int *ntoks)
{
@@ -104,8 +104,23 @@ monadfun(Datum left, Datum right)
print("Monadic function application\n");
Datum result;
result.tag = ArrayTag;
+
/* TODO handle undefined functions here */
- result.array = monadfunctiondefs[left.code](right.array);
+ if(left.func.left)
+ result.array = dyadfunctiondefs[left.code](left.func.left, right.array);
+ else
+ result.array = monadfunctiondefs[left.code](right.array);
+ return result;
+}
+
+Datum
+dyadfun(Datum left, Datum right)
+{
+ print("Applying left argument to function\n");
+ Datum result;
+ result.tag = BoundFunctionTag,
+ result.func = right.func;
+ result.func.left = left.array;
return result;
}
diff --git a/functions.c b/functions.c
index 8a5c959..71e5400 100644
--- a/functions.c
+++ b/functions.c
@@ -58,7 +58,62 @@ fnmonad monadfunctiondefs[] = {
0, /* ⊖ */
0, /* ⍉ */
0, /* ⍎ */
- 0, /* ⍕ */
+ 0, /* ⍕ */
+};
+
+fndyad dyadfunctiondefs[] = {
+ 0, /* + */
+ 0, /* - */
+ 0, /* × */
+ 0, /* ÷ */
+ 0, /* * */
+ 0, /* ⍟ */
+ 0, /* ⌹ */
+ 0, /* ○ */
+ 0, /* ! */
+ 0, /* ? */
+ 0, /* | */
+ 0, /* ⌈ */
+ 0, /* ⌊ */
+ 0, /* ⊥ */
+ 0, /* ⊤ */
+ 0, /* ⊣ */
+ 0, /* ⊢ */
+ 0, /* = */
+ 0, /* ≠ */
+ 0, /* ≤ */
+ 0, /* < */
+ 0, /* > */
+ 0, /* ≥ */
+ 0, /* ≡ */
+ 0, /* ≢ */
+ 0, /* ∨ */
+ 0, /* ∧ */
+ 0, /* ⍲ */
+ 0, /* ⍱ */
+ 0, /* ↑ */
+ 0, /* ↓ */
+ 0, /* ⊂ */
+ 0, /* ⊃ */
+ 0, /* ⊆ */
+ 0, /* ⌷ */
+ 0, /* ⍋ */
+ 0, /* ⍒ */
+ 0, /* ⍳ */
+ 0, /* ⍸ */
+ 0, /* ∊ */
+ 0, /* ⍷ */
+ 0, /* ∪ */
+ 0, /* ∩ */
+ 0, /* ~ */
+ 0, /* , */
+ fnCatenateFirst, /* ⍪ */
+ fnReshape, /* ⍴ */
+ 0, /* ⌽ */
+ 0, /* ⊖ */
+ 0, /* ⍉ */
+ 0, /* ⍎ */
+ 0, /* ⍕ */
};
/* Monadic functions */
@@ -127,4 +182,23 @@ fnCatenateFirst(Array *left, Array *right)
memcpy(res->rawdata, left->rawdata, datasizes[res->type]*left->size);
memcpy(res->rawdata+datasizes[res->type]*left->size, right->rawdata, datasizes[res->type]*right->size);
return res;
+}
+
+Array *
+fnReshape(Array *left, Array *right)
+{
+ vlong size = 1;
+ int i;
+ char *p;
+ for(i = 0; i < left->size; i++)
+ size *= left->intdata[i];
+ if(left->size == 0)
+ size = 0;
+
+ Array *res = mkarray(right->type, left->size, size);
+ for(i = 0; i < left->size; i++)
+ res->shape[i] = left->intdata[i];
+ for(i = 0, p = res->rawdata; i < size; i++, p += datasizes[res->type])
+ memcpy(p, right->rawdata + (datasizes[res->type] * (i % right->size)), datasizes[res->type]);
+ return res;
} \ No newline at end of file