summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apl9.h14
-rw-r--r--array.c17
-rw-r--r--concurrency.c12
-rw-r--r--lexer.c6
-rw-r--r--print.c5
-rw-r--r--quadnames.c29
-rw-r--r--symbol.c40
7 files changed, 101 insertions, 22 deletions
diff --git a/apl9.h b/apl9.h
index 54d827b..87b65f4 100644
--- a/apl9.h
+++ b/apl9.h
@@ -24,6 +24,7 @@ typedef enum
AtypeRune,
AtypeMixed,
AtypeArray,
+ AtypeNamespace,
} arrayDataType;
typedef enum
@@ -59,6 +60,7 @@ typedef enum
/* Data types */
typedef struct Mixed Mixed;
+typedef struct Namespace Namespace;
typedef struct Array Array;
typedef struct Statement Statement;
typedef struct Operator Operator;
@@ -83,6 +85,12 @@ struct Mixed
};
};
+struct Namespace
+{
+ Rune *displayform;
+ Symtab *syms;
+};
+
#define GetRank(a) ((u8int)((a->info & 0x000000000000000F) >> 0))
#define GetType(a) ((u8int)((a->info & 0x00000000000000F0) >> 4))
#define GetStrand(a) ((u8int)((a->info & 0x0000000000000100) >> 8))
@@ -100,6 +108,7 @@ struct Array
Rune *runedata;
Mixed *mixeddata;
Array **arraydata;
+ Namespace **nsdata;
Array *prototype; /* only in use when size == 0 and type == AtypeArray */
};
uvlong size;
@@ -243,6 +252,7 @@ struct ThreadData
QLock lock;
Rendez newmail;
Array *name;
+ Array *ns;
};
struct Mail
@@ -271,6 +281,7 @@ Array *mkscalarint(vlong);
Array *mkscalarfloat(double);
Array *mkscalarrune(Rune);
Array *mkrunearray(Rune *);
+Array *mkscalarns(Namespace *);
Array *duparray(Array *);
Array *duparrayshape(Array *, int);
int simplearray(Array *);
@@ -489,4 +500,5 @@ extern opmonad hybridoperatordefs[]; /* hybrids.c */
extern int arrayalloccounts; /* memory.c */
extern int datumalloccounts; /* memory.c */
extern QuadnameDef quadnames[]; /* quadnames.c */
-extern int printprecision; /* print.c */ \ No newline at end of file
+extern int printprecision; /* print.c */
+extern Array *rootns; /* symbol.c */ \ No newline at end of file
diff --git a/array.c b/array.c
index 3643ee6..71c35f6 100644
--- a/array.c
+++ b/array.c
@@ -12,7 +12,8 @@ int datasizes[] = {
[AtypeFloat] = sizeof(double),
[AtypeRune] = sizeof(Rune),
[AtypeMixed] = sizeof(Mixed),
- [AtypeArray] = sizeof(Array *)
+ [AtypeArray] = sizeof(Array *),
+ [AtypeNamespace] = sizeof(Namespace *),
};
Array *
@@ -50,6 +51,14 @@ mkrunearray(Rune *str)
}
Array *
+mkscalarns(Namespace *ns)
+{
+ Array *a = allocarray(AtypeNamespace, 0, 1);
+ a->nsdata[0] = ns;
+ return a;
+}
+
+Array *
duparray(Array *a)
{
Array *b = duparrayshape(a, GetType(a));
@@ -198,6 +207,9 @@ arrayitem(Array *a, int index)
res = a->arraydata[index];
incref(res);
break;
+ case AtypeNamespace:
+ res = mkscalarns(a->nsdata[index]);
+ break;
default:
throwerror(L"Unhandled case in arrayitem 2", ENotImplemented);
}
@@ -321,6 +333,9 @@ comparearray(Array *a, Array *b, int checkshapes)
case AtypeArray:
sub = comparearray(a->arraydata[i], b->arraydata[i], checkshapes);
break;
+ case AtypeNamespace:
+ sub = a->nsdata[i] > b->nsdata[i] ? 1 : a->nsdata[i] == b->nsdata[i] ? 0 : -1;
+ break;
default:
print("Missing comparison code for type %d\n", GetType(a));
exits(nil);
diff --git a/concurrency.c b/concurrency.c
index 1c73099..415c39d 100644
--- a/concurrency.c
+++ b/concurrency.c
@@ -13,12 +13,13 @@ struct SpawnData
Array *name;
Array *left;
Array *right;
+ Array *ns;
QLock lock;
Rendez done;
};
static void newprocfn(SpawnData *);
-static ThreadData *newthreaddata(Array *);
+static ThreadData *newthreaddata(Array *, Array *);
extern void **_privates;
@@ -48,7 +49,7 @@ void
initthreads(void)
{
Array *name = mkrunearray(L"main");
- _privates[0] = newthreaddata(name);
+ _privates[0] = newthreaddata(name, nil);
freearray(name);
}
@@ -68,6 +69,7 @@ spawnthread(Function f, Array *name, Array *left, Array *right)
exit proc
*/
+ ThreadData *td = getthreaddata();
SpawnData *sp = emallocz(sizeof(SpawnData), 1);
sp->func = dupfunction(f);
@@ -75,6 +77,7 @@ spawnthread(Function f, Array *name, Array *left, Array *right)
sp->name = duparray(name);
sp->left = left ? duparray(left) : nil;
sp->right = duparray(right);
+ sp->ns = fnSame(td->ns);
sp->done.l = &sp->lock;
qlock(&sp->lock);
@@ -199,7 +202,7 @@ static void
newprocfn(SpawnData *sp)
{
qlock(&sp->lock);
- ThreadData *td = newthreaddata(sp->name);
+ ThreadData *td = newthreaddata(sp->name, sp->ns);
_privates[0] = td;
rwakeup(&sp->done);
qunlock(&sp->lock);
@@ -231,7 +234,7 @@ newprocfn(SpawnData *sp)
}
static ThreadData *
-newthreaddata(Array *name)
+newthreaddata(Array *name, Array *ns)
{
ThreadData *td = emallocz(sizeof(ThreadData), 1);
td->id = getpid();
@@ -243,6 +246,7 @@ newthreaddata(Array *name)
td->timedout = 0;
td->newmail.l = &td->lock;
td->name = fnSame(name);
+ td->ns = ns;
lock(&threadlock);
nthreads++;
diff --git a/lexer.c b/lexer.c
index 198bd42..244ea3a 100644
--- a/lexer.c
+++ b/lexer.c
@@ -65,7 +65,7 @@ lexline(InputStream *input, int toplevel)
if(isspacerune(peek) && peek != '\n'){
peek = getrune(input);
continue;
- }else if(runestrchr(L"←⋄\n⍝⍬", peek)){
+ }else if(runestrchr(L"←⋄\n⍝⍬#", peek)){
switch(peek){
case L'←': stmt->toks[stmt->ntoks] = allocdatum(ArrowTag, 0); break;
case L'\n':
@@ -90,6 +90,10 @@ lexline(InputStream *input, int toplevel)
stmt->toks[stmt->ntoks]->array = allocarray(AtypeInt, 1, 0);
stmt->toks[stmt->ntoks]->array->shape[0] = 0;
break;
+ case L'#':
+ stmt->toks[stmt->ntoks] = allocdatum(ArrayTag, 0);
+ stmt->toks[stmt->ntoks]->array = fnSame(rootns);
+ break;
}
}else if(!toplevel && peek == ':'){
Rune buf[MAX_LINE_LENGTH];
diff --git a/print.c b/print.c
index 3143fcc..1262eb4 100644
--- a/print.c
+++ b/print.c
@@ -84,7 +84,10 @@ pparray(Array *a)
done = 1;
*p-- = 0; /* remove trailing 0's */
}
- }
+ }else if(GetType(e) == AtypeNamespace)
+ elemstrs[i] = runestrdup(e->nsdata[0]->displayform);
+ else
+ throwerror(L"Unhandled case in pparray", ENotImplemented);
if(elemstrs[i][0] == '-' && (GetType(e) == AtypeInt || GetType(e) == AtypeFloat))
elemstrs[i][0] = L'¯';
diff --git a/quadnames.c b/quadnames.c
index 814376e..a44c04d 100644
--- a/quadnames.c
+++ b/quadnames.c
@@ -23,6 +23,7 @@ Datum *geten(void);
Datum *getself(void);
Datum *getsession(void);
void setsession(Datum *);
+Datum *getthis(void);
/* Array *runfile(Array *); in apl9.h */
Array *quadem(Array *);
@@ -42,6 +43,8 @@ Array *quadread(Array *, Array *);
Array *quadwrite(Array *, Array *);
Array *quadpipe(Array *);
Array *quadfd2path(Array *);
+Array *quadns1(Array *);
+Array *quadns2(Array *, Array *);
static Rune *quadquotebuf = nil;
static Array *session = nil;
@@ -58,6 +61,7 @@ QuadnameDef quadnames[] = {
{L"⎕EN", NameTag, geten, nil, nil, nil},
{L"⎕SELF", NameTag, getself, nil, nil, nil},
{L"⎕SESSION", NameTag, getsession, setsession, nil, nil},
+ {L"⎕THIS", NameTag, getthis, nil, nil, nil},
{L"⎕RUN", FunctionTag, nil, nil, runfile, nil},
{L"⎕EM", FunctionTag, nil, nil, quadem, nil},
{L"⎕SIGNAL", FunctionTag, nil, nil, quadsignal1, quadsignal2},
@@ -74,6 +78,7 @@ QuadnameDef quadnames[] = {
{L"⎕WRITE", FunctionTag, nil, nil, nil, quadwrite},
{L"⎕PIPE", FunctionTag, nil, nil, quadpipe, nil},
{L"⎕FD2PATH", FunctionTag, nil, nil, quadfd2path, nil},
+ {L"⎕NS", FunctionTag, nil, nil, quadns1, quadns2},
{nil, 0, nil, nil, nil, nil} /* MUST BE LAST */
};
@@ -330,6 +335,16 @@ setsession(Datum *new)
session = fnSame(new->array);
}
+/* ⎕THIS */
+Datum *
+getthis(void)
+{
+ ThreadData *td = getthreaddata();
+ Datum *d = allocdatum(ArrayTag, 0);
+ d->array = fnSame(td->ns);
+ return d;
+}
+
/* ⎕RUN */
Array *
runfile(Array *a)
@@ -757,4 +772,18 @@ quadfd2path(Array *fd)
free(buf);
free(path);
return res;
+}
+
+/* ⎕NS */
+Array *
+quadns1(Array *)
+{
+ throwerror(L"⎕NS", ENotImplemented);
+ return nil;
+}
+
+Array *quadns2(Array *, Array *)
+{
+ throwerror(L"⎕NS", ENotImplemented);
+ return nil;
} \ No newline at end of file
diff --git a/symbol.c b/symbol.c
index 61629ee..4fc8142 100644
--- a/symbol.c
+++ b/symbol.c
@@ -5,7 +5,7 @@
#include "apl9.h"
-Symtab *globalsymtab;
+Array *rootns;
Symtab *newsymtab(Symtab *);
Symbol *dupsymbol(Symbol *);
@@ -17,6 +17,7 @@ Datum *getalphao(void);
Datum *getomegao(void);
void setalpha(Datum *);
void setsyntaxerr(Datum *);
+Namespace *newnamespace(Rune *, Symtab *);
Symbol *
getsym(Rune *name, int fresh)
@@ -86,9 +87,6 @@ freesymtab(Symtab *tab)
if(tab == nil)
return;
- if(tab == globalsymtab) /* Never free the global symtab */
- return;
-
int i;
for(i = 0; i < tab->nsyms; i++){
Symbol *s = tab->syms[i];
@@ -102,7 +100,10 @@ freesymtab(Symtab *tab)
void
initsymtab(void)
{
- globalsymtab = newsymtab(nil);
+ ThreadData *td = getthreaddata();
+ Namespace *ns = newnamespace(L"#", newsymtab(nil));
+ td->ns = rootns = fnSame(mkscalarns(ns));
+
Symbol *s;
s = getsym(L"⍺", 1);
s->getfn = getalpha;
@@ -205,8 +206,8 @@ globalIO(void)
ThreadData *td = getthreaddata();
if(td->currentdfn)
return td->currentdfn->symtab->io;
- else if(globalsymtab)
- return globalsymtab->io;
+ else if(td->ns)
+ return td->ns->nsdata[0]->syms->io;
else
return 1;
}
@@ -218,7 +219,7 @@ globalIOset(vlong io)
if(td->currentdfn)
td->currentdfn->symtab->io = io;
else
- globalsymtab->io = io;
+ td->ns->nsdata[0]->syms->io = io;
}
int
@@ -227,8 +228,8 @@ globalDIV(void)
ThreadData *td = getthreaddata();
if(td->currentdfn)
return td->currentdfn->symtab->div;
- else if(globalsymtab)
- return globalsymtab->div;
+ else if(td->ns)
+ return td->ns->nsdata[0]->syms->div;
else
return 0;
}
@@ -240,7 +241,7 @@ globalDIVset(int div)
if(td->currentdfn)
td->currentdfn->symtab->div = div;
else
- globalsymtab->div = div;
+ td->ns->nsdata[0]->syms->div = div;
}
/* getters and setters for ⍺⍵⍶⍹ */
@@ -322,10 +323,11 @@ setsyntaxerr(Datum *)
Symtab *
dupscope(Symtab *old)
{
- Symtab *new = newsymtab(globalsymtab);
+ ThreadData *td = getthreaddata();
+ Symtab *new = newsymtab(td->ns->nsdata[0]->syms);
/* copy ALL symbols which are in scope, into the new symtab */
- for(Symtab *o = old; o != globalsymtab; o = o->chain){
+ for(Symtab *o = old; o != td->ns->nsdata[0]->syms; o = o->chain){
/* Add all new symbols */
for(int i = 0; i < o->nsyms; i++){
Symbol *sym = o->syms[i];
@@ -358,9 +360,19 @@ dupscope(Symtab *old)
Symtab *
getcurrentsymtab(void)
{
+ ThreadData *td = getthreaddata();
DfnFrame *dfn = getcurrentdfn();
if(dfn == nil)
- return globalsymtab;
+ return td->ns->nsdata[0]->syms;
else
return dfn->symtab;
+}
+
+Namespace *
+newnamespace(Rune *displayform, Symtab *syms)
+{
+ Namespace *ns = emalloc(sizeof(Namespace));
+ ns->displayform = runestrdup(displayform);
+ ns->syms = syms;
+ return ns;
} \ No newline at end of file