ref: 785a9258b6f284d369b8e018e7f9dccf682a4479
parent: 5a13bf8802eea9663d555a24c90dc0e8c346d97d
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jul 23 16:31:13 EDT 2024
More general work
--- a/array.c
+++ b/array.c
@@ -151,6 +151,75 @@
return buf;
}
+static int
+printexpr(char *start, Ast *e, int left)
+{
+ if(e == nil)
+ return sprint(start, "{?nil?}");
+
+ char *p = start;
+ int paren = 0;
+ if(left){
+ switch(e->tag){
+ case AstAssign:
+ case AstMonadic:
+ case AstDyadic:
+ case AstStrand:
+ p += sprint(p, "(");
+ paren = 1;
+ break;
+ }
+ }
+
+ switch(e->tag){
+ case AstName:
+ if(left)
+ p += sprint(p, " ");
+ p += sprint(p, "%s", e->name);
+ if(left)
+ p += sprint(p, " ");
+ break;
+ case AstAssign:
+ p += printexpr(p, e->left, 0);
+ p += sprint(p, "←");
+ p += printexpr(p, e->right, 0);
+ break;
+ case AstMonadic:
+ p += printexpr(p, e->func, 1);
+ p += printexpr(p, e->right, 0);
+ break;
+ case AstDyadic:
+ p += printexpr(p, e->left, 1);
+ p += printexpr(p, e->func, 1);
+ p += printexpr(p, e->right, 0);
+ break;
+ case AstConst:
+ p += printarraysub(p, e->val, 0);
+ break;
+ case AstPrim:
+ p += sprint(p, "%s", primsymb(e->prim));
+ break;
+ case AstStrand:
+ for(uvlong i = 0; i < e->childcount; i++){
+ if(i != 0)
+ p += sprint(p, " ");
+ p += printexpr(p, e->children[i], 1);
+ }
+ break;
+ case AstLater:
+ p += sprint(p, "{later..}");
+ break;
+ default:
+ p += sprint(p, "{expr %d}", e->tag);
+ break;
+ }
+
+ if(paren)
+ p += sprint(p, ")");
+
+ return p - start;
+}
+
char *
printfunc(Function *f) /* Doesn't really belong here.. */
{
@@ -167,6 +236,10 @@
p += sprint(p, " %s", f->ast->funcrightarg->name);
for(uvlong i = 0; i < f->ast->funclocals->childcount; i++)
p += sprint(p, ";%s", f->ast->funclocals->children[i]->name);
+ for(uvlong i = 0; i < f->ast->childcount; i++){
+ p += sprint(p, "\n ");
+ p += printexpr(p, f->ast->children[i], 0);
+ }
sprint(p, "\n∇");
return buf;
}
--- a/dat.h
+++ b/dat.h
@@ -101,12 +101,6 @@
void **items;
};
-enum Primitive
-{
- PrimPlus,
- PrimMinus,
-};
-
enum TokenTag
{
TokNumber,
--- a/eval.c
+++ b/eval.c
@@ -105,6 +105,11 @@
emitbyte(c, ILookup);
emituvlong(c, sym(m->symtab, a->name));
break;
+ case AstAssign:
+ codegensub(s, m, c, a->right);
+ emitbyte(c, IAssign);
+ emituvlong(c, sym(m->symtab, a->left->name));
+ break;
case AstConst:
emitbyte(c, IPushConst);
emitptr(c, a->val); /* TODO: better to have consts array and emit index? */
@@ -262,11 +267,21 @@
}
break;
case IMonadic:
- appendlog(s, "NOTE: monadic call acts like ⊢\n");
+ {
+ Function *f = popval(values);
+ Array *y = popval(values);
+ Array *z = primmonad(f->prim, y);
+ pushval(values, z);
+ }
break;
case IDyadic:
- appendlog(s, "NOTE: dyadic call acts like ⊢\n");
- popval(values);
+ {
+ Function *f = popval(values);
+ Array *x = popval(values);
+ Array *y = popval(values);
+ Array *z = primdyad(f->prim, x, y);
+ pushval(values, z);
+ }
break;
case ICall:
func = popval(values);
--- a/fns.h
+++ b/fns.h
@@ -28,6 +28,13 @@
/* parse.c */
Ast *parse(TokenList *, Symtab *, char **);
+/* prim.c */
+char *primsymb(int);
+int primclass(int);
+int primid(char *);
+Array *primmonad(int, Array *);
+Array *primdyad(int, Array *, Array *);
+
/* scan.c */
TokenList *scan(char *, char **);
--- a/mkfile
+++ b/mkfile
@@ -10,6 +10,7 @@
memory.$O\
module.$O\
parse.$O\
+ prim.$O\
scan.$O\
session.$O\
symtab.$O\
--- a/parse.c
+++ b/parse.c
@@ -141,10 +141,10 @@
break;
/* more cases here in the future */
}
- }else{
- /* TODO: Check if the name exist in the locallist */
- class = NameclassUndef;
}
+
+ /* TODO: Check if the name exist in the locallist */
+
return class;
}
@@ -265,10 +265,14 @@
if(t->tokens[i].tag != TokName)
continue;
+ if((i+1) < end && t->tokens[i+1].tag == TokLarrow)
+ continue; /* assignment */
+
name = t->tokens[i].name;
class = nameclass(name, symtab, func);
t->tokens[i].nameclass = class;
if(class == 0){ /* We don't know how to parse it until runtime */
+ print("nameclass 0 name: %s funcname: %s\n", name, func ? func->funcname->name : "<no func>");
if(symtab)
error(t, "could not resolve nameclasses");
--- /dev/null
+++ b/prim.c
@@ -1,0 +1,92 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+
+#include "dat.h"
+#include "fns.h"
+
+/* NOTE: In LPA, system functions are treated as primitives as well */
+
+/* monadic functions */
+static Array *primfn_same(Array *);
+
+/* dyadic functions */
+static Array *primfn_left(Array *, Array *);
+static Array *primfn_right(Array *, Array *);
+
+struct {
+ char *spelling;
+ int nameclass;
+ Array *(*monad)(Array *);
+ Array *(*dyad)(Array *, Array *);
+} primspecs[] = {
+ "⊢", NameclassFunc, primfn_same, primfn_right,
+ "⊣", NameclassFunc, primfn_same, primfn_left,
+ "+", NameclassFunc, nil, nil,
+ "-", NameclassFunc, nil, nil,
+};
+
+char *
+primsymb(int id)
+{
+ return primspecs[id].spelling;
+}
+
+int
+primclass(int id)
+{
+ return primspecs[id].nameclass;
+}
+
+int
+primid(char *s)
+{
+ for(int i = 0; i < nelem(primspecs); i++){
+ char *x = primspecs[i].spelling;
+ if(strncmp(s, x, strlen(x)) == 0)
+ return i;
+ }
+ return -1;
+}
+
+Array *
+primmonad(int id, Array *y)
+{
+ if(primspecs[id].monad)
+ return primspecs[id].monad(y);
+ else{
+ print("primitive %s has no monadic definition! (acts like ⊢)\n", primsymb(id));
+ return y;
+ }
+}
+
+Array *
+primdyad(int id, Array *x, Array *y)
+{
+ if(primspecs[id].dyad)
+ return primspecs[id].dyad(x, y);
+ else{
+ print("primitive %s has no dyadic definition! (acts like ⊣)\n", primsymb(id));
+ return x;
+ }
+}
+
+/* monadic functions */
+static Array *
+primfn_same(Array *a)
+{
+ return a;
+}
+
+/* dyadic functions */
+static Array *
+primfn_left(Array *x, Array *)
+{
+ return x;
+}
+
+static Array *
+primfn_right(Array *, Array *y)
+{
+ return y;
+}
\ No newline at end of file
--- a/scan.c
+++ b/scan.c
@@ -5,14 +5,6 @@
#include "dat.h"
#include "fns.h"
-struct {
- Rune spelling;
- int id;
-} primspecs[] = {
- L'+', PrimPlus,
- L'-', PrimMinus,
-};
-
Token *
newtok(TokenList *tokens, int tag)
{
@@ -30,7 +22,7 @@
scan(char *buf, char **errp)
{
Rune r;
- int n;
+ int n, id;
TokenList *tokens = alloc(DataTokenList);
Token *tok;
char *cp = buf;
@@ -55,13 +47,12 @@
newtok(tokens, new);
goto next;
}
- for(int i = 0; i < nelem(primspecs); i++){
- if(r == primspecs[i].spelling){
- tok = newtok(tokens, TokPrimitive);
- tok->prim = primspecs[i].id;
- tok->nameclass = NameclassFunc;
- goto next;
- }
+ if((id = primid(cp)) != -1){
+ n = strlen(primsymb(id));
+ tok = newtok(tokens, TokPrimitive);
+ tok->prim = id;
+ tok->nameclass = primclass(id);
+ goto next;
}
if(isspacerune(r))
goto next;