summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 23:57:13 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 23:57:13 +0000
commit1ddd7de5b15f52c13a5c084445253655a94bd970 (patch)
tree4d0f3b8ad18f2c4ceaa175022c42d7f0de093184
parent230aac3c644df9d80c8eba507e6bc7c710b26b52 (diff)
Implement a very basic ⎕RUN command which runs the code from a file
-rw-r--r--apl9.h4
-rw-r--r--functions.c10
-rw-r--r--print.c4
-rw-r--r--quadnames.c31
4 files changed, 45 insertions, 4 deletions
diff --git a/apl9.h b/apl9.h
index acbfcbb..bf74bf4 100644
--- a/apl9.h
+++ b/apl9.h
@@ -36,6 +36,7 @@ typedef enum
FunctypeDfn,
FunctypePrim,
FunctypeOp,
+ FunctypeQuad,
} functionType;
/* Data types */
@@ -91,6 +92,7 @@ struct Function
int code;
Rune *dfn;
Operator operator;
+ QuadnameDef *quad;
};
Array *left;
};
@@ -136,7 +138,7 @@ struct QuadnameDef
Datum *(*get)(void);
int (*set)(Datum);
fnmonad monadfn;
- fnmonad dyadfn;
+ fndyad dyadfn;
opmonad monadop;
opdyad dyadop;
};
diff --git a/functions.c b/functions.c
index 7266f28..55a72ad 100644
--- a/functions.c
+++ b/functions.c
@@ -147,13 +147,19 @@ runfunc(Function f, Array *left, Array *right)
return dyadfunctiondefs[f.code](left, right);
else
return monadfunctiondefs[f.code](right);
- }else{
+ }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);
- }
+ }else if(f.type == FunctypeQuad){
+ if(left)
+ return f.quad->dyadfn(left, right);
+ else
+ return f.quad->monadfn(right);
+ }else
+ return nil;
}
Array *
diff --git a/print.c b/print.c
index 9a924d4..842d9b3 100644
--- a/print.c
+++ b/print.c
@@ -21,8 +21,10 @@ ppdatum(Datum d)
result = runesmprint("%C", primfuncnames[d.func.code]);
else if(d.func.type == FunctypeDfn)
result = runesmprint("{%S}", d.func.dfn);
- else
+ else if(d.func.type == FunctypeOp)
result = runesmprint("%S", ppoperator(d.func.operator));
+ else
+ result = runesmprint("%S", d.func.quad->name);
break;
case HybridTag: result = runesmprint("%C", primhybridnames[d.func.code]); break;
case MonadicOpTag:
diff --git a/quadnames.c b/quadnames.c
index bb191c5..e7ebbdd 100644
--- a/quadnames.c
+++ b/quadnames.c
@@ -11,10 +11,13 @@ int setio(Datum);
Datum *getpp(void);
int setpp(Datum);
+Array *runfile(Array *);
+
QuadnameDef quadnames[] = {
{L"⎕", NameTag, getquad, setquad, nil, nil},
{L"⎕IO", NameTag, getio, setio, nil, nil},
{L"⎕PP", NameTag, getpp, setpp, nil, nil},
+ {L"⎕RUN", FunctionTag, nil, nil, runfile, nil},
{nil, 0, nil, nil, nil, nil} /* MUST BE LAST */
};
@@ -31,6 +34,11 @@ quadnamedatum(QuadnameDef q)
d.symbol->undefined = 0;
break;
case FunctionTag:
+ d.func.type = FunctypeQuad;
+ d.func.quad = malloc(sizeof(QuadnameDef));
+ *d.func.quad = q;
+ d.func.left = nil;
+ break;
case MonadicOpTag:
case DyadicOpTag:
default:
@@ -99,4 +107,27 @@ setpp(Datum new)
printprecision = new.array->intdata[0];
return 1;
}
+}
+
+/* ⎕RUN */
+Array *
+runfile(Array *a)
+{
+ print("Loading file %S\n", pparray(a));
+ if(a->type != AtypeRune || a->rank > 1){
+ return mkscalarint(0);
+ }
+
+ char *filename = smprint("%S", pparray(a));
+ Biobuf *bio = Bopen(filename, OREAD);
+ if(bio == nil)
+ return mkscalarint(0);
+
+ char *charcode = Brdstr(bio, Beof, 1);
+ Rune *code = runesmprint("%s", charcode);
+ evalline(code, 1);
+ free(charcode);
+ free(code);
+ Bterm(bio);
+ return mkscalarint(1);
} \ No newline at end of file