M array.c => array.c +120 -9
@@ 11,6 11,7 @@
struct Array
{
+ int type;
int rank;
usize size;
usize *shape;
@@ 18,6 19,7 @@ struct Array
void *data;
vlong *intdata;
Rune *chardata;
+ Array **arraydata;
};
};
@@ 31,6 33,7 @@ Array *
allocarray(int type, int rank, usize size)
{
Array *a = alloc(DataArray);
+ a->type = type;
a->rank = rank;
a->size = size;
@@ 41,6 44,9 @@ allocarray(int type, int rank, usize size)
case TypeChar:
size *= sizeof(Rune);
break;
+ case TypeArray:
+ size *= sizeof(Array *);
+ break;
}
a->shape = allocextra(a, (sizeof(usize) * rank) + size);
@@ 56,22 62,127 @@ setint(Array *a, usize offset, vlong v)
}
void
+setarray(Array *a, usize offset, Array *v)
+{
+ a->arraydata[offset] = v;
+}
+
+void
setshape(Array *a, int dim, usize size)
{
a->shape[dim] = size;
}
+static int printarraysub(char *, Array *, int);
+static int
+printitem(char *p, Array *a, uvlong i, int depth)
+{
+ switch(a->type){
+ case TypeNumber:
+ return sprint(p, "%lld", a->intdata[i]);
+ case TypeChar:
+ return sprint(p, "%C", a->chardata[i]);
+ case TypeArray:
+ return printarraysub(p, a->arraydata[i], depth);
+ default:
+ return sprint(p, "???");
+ }
+}
+
+static int
+indent(char *buf, int depth)
+{
+ char *p = buf;
+ for(int i = 0; i < depth; i++)
+ p += sprint(p, " ");
+ return p-buf;
+}
+
+static int
+printarraysub(char *buf, Array *a, int depth)
+{
+ char *p = buf;
+
+ if(a->rank == 0){
+ p += printitem(p, a, 0, depth);
+ goto end;
+ }else if(a->rank == 1 && a->type == TypeNumber){
+ if(a->size == 0)
+ p += sprint(p, "⍬");
+ for(uvlong i = 0; i < a->size; i++){
+ if(i != 0)
+ p += sprint(p, " ");
+ p += printitem(p, a, i, depth);
+ }
+ goto end;
+ }else if(a->rank == 1 && a->type == TypeChar){
+ p += sprint(p, "'");
+ for(uvlong i = 0; i < a->size; i++)
+ p += printitem(p, a, i, depth); /* TODO: quoting */
+ p += sprint(p, "'");
+ goto end;
+ }else if(a->rank == 1 && a->type == TypeArray){
+ if(a->size == 0){
+ p += sprint(p, "( ⋄ )");
+ goto end;
+ }
+ p += sprint(p, "(");
+ for(uvlong i = 0; i < a->size; i++){
+ if(i != 0){
+ p += sprint(p, "\n");
+ p += indent(p, depth+1);
+ }
+ p += printitem(p, a, i, depth+1);
+ }
+ p += sprint(p, ")");
+ goto end;
+ }
+
+ p += sprint(p, "Some array I can't print yet");
+end:
+ return p-buf;
+}
+
char *
printarray(Array *a)
{
- /* TODO: this is just for debugging */
- char buf[2048];
- char *p = buf;
- p += sprint(p, "type: %s shape: ", "numeric");
- for(int i = 0; i < a->rank; i++)
- p += sprint(p, "%lld ", a->shape[i]);
- p += sprint(p, "data: ");
- for(uvlong i = 0; i < a->size; i++)
- p += sprint(p, "%lld ", a->intdata[i]);
+ char buf[2048]; /* TODO: fixed size :) */
+ printarraysub(buf, a, 0);
return buf;
+}
+
+Array *
+simplifyarray(Array *a)
+{
+ /* Given an array of type TypeArray, where all the elements are
+ * simple scalars of the same type, return an array of that type
+ */
+
+ Array *b = nil;
+ int type;
+
+ if(a->type != TypeArray || a->size == 0)
+ goto end;
+
+ type = a->arraydata[0]->type;
+ b = allocarray(type, a->rank, a->size);
+ for(uvlong dim = 0; dim < a->rank; dim++)
+ b->shape[dim] = a->shape[dim];
+
+ for(uvlong i = 0; i < a->size; i++){
+ if(a->arraydata[i]->type != type || a->arraydata[i]->rank != 0){
+ b = a;
+ goto end; /* Must be the same type and scalar */
+ }
+ switch(type){
+ case TypeNumber:
+ b->intdata[i] = a->arraydata[i]->intdata[0];
+ break;
+ case TypeChar:
+ b->chardata[i] = a->arraydata[i]->chardata[0];
+ break;
+ }
+ }
+end:
+ return b;
}=
\ No newline at end of file
M dat.h => dat.h +1 -0
@@ 149,6 149,7 @@ enum ArrayType
{
TypeNumber,
TypeChar,
+ TypeArray,
};
typedef struct Array Array;
M fns.h => fns.h +2 -0
@@ 2,7 2,9 @@
void initarrays(void);
Array *allocarray(int, int, usize);
void setint(Array *, usize, vlong);
+void setarray(Array *, usize, Array *);
void setshape(Array *, int, usize);
+Array *simplifyarray(Array *);
char *printarray(Array *);
M fs.c => fs.c +10 -0
@@ 613,6 613,16 @@ static Srv fs = {
void
startfs(char *name, char *mtpt)
{
+ char *srvname = smprint("/srv/%s", name);
+ if(access(srvname, AREAD|AWRITE) == 0){
+ int fd = open(srvname, ORDWR);
+ if(fd < 0)
+ sysfatal("open lpa service");
+ if(mount(fd, -1, mtpt, MREPL, "") != 0)
+ sysfatal("mount lpa service");
+ return;
+ }
+
dataspecs[DataAux].size = sizeof(Aux);
username = getuser();
M lpa => lpa +4 -8
@@ 12,7 12,7 @@ fn usage{
}
fn nosession{
- echo 'session '^$id^' does not exist (or lpafs is not running)'
+ echo 'session '^$id^' does not exist'
exit 'no such session'
}
@@ 43,13 43,9 @@ if(! ~ $#* 0)
usage
# Start LPA if it isn't already running
-if(! test -f /srv/lpa){
- if(! ~ $id 0)
- nosession
- lpafs
-}
-if not
- mount /srv/lpa /mnt/lpa
+lpafs
+# Make /mnt/lpa available to sam and rio..
+plumb 'Local lpafs'
if(~ $printlist 1){
echo `{cd /mnt/lpa; ls | grep -v '^new$'}
M parse.c => parse.c +1 -3
@@ 161,12 161,10 @@ parseprog(TokenList *t)
child = parsefuncdef(t);
else
child = parseexpr(t, nil);
- print("After expr: %d\n", peek(t));
if(peek(t) != TokEnd)
parseseps(t, 1);
addchild(prog, child);
}
- print("got prog, peek is: %d\n", peek(t));
return prog;
}
@@ 324,7 322,7 @@ end:
addchild(strand, val);
val = strand;
}
-
+
return val;
}
M scan.c => scan.c +0 -6
@@ 92,11 92,5 @@ next:
cp += n;
}
newtok(tokens, TokEnd);
- if(tokens){
- print("token tags: ");
- for(uvlong i = 0; i < tokens->count; i++)
- print("%d ", tokens->tokens[i].tag);
- print("\n");
- }
return tokens;
}=
\ No newline at end of file
M session.c => session.c +0 -1
@@ 56,7 56,6 @@ error:
if(err)
goto error;
- debugast(ast, 0);
appendlog(s, "got an AST but can't evaluate it yet\n");
}
}
M value.c => value.c +40 -4
@@ 6,6 6,9 @@
#include "fns.h"
/* Anything that can have a name in LPA: Arrays, functions, ... */
+
+static Array *evalconstast(Ast *);
+
char *
printval(void *v)
{
@@ 34,10 37,11 @@ parseval(char *buf, char **errp)
ast = parse(tokens, errp);
if(ast == nil)
goto end;
-
+ debugast(ast, 0);
/* Check that the ast is either a single function definition,
- * or a single constant.
+ * or a constant (stranding is OK).
*/
+
if(!(ast->tag == AstProg && ast->childcount == 1)){
*errp = "Expected single value or function definition";
goto end;
@@ 46,15 50,47 @@ parseval(char *buf, char **errp)
ast = ast->children[0];
switch(ast->tag){
case AstConst:
- val = ast->val;
+ case AstStrand:
+ val = evalconstast(ast);
+ if(val == nil)
+ *errp = "Expected constant expression";
break;
case AstFunc:
*errp = "Functions not supported yet";
break;
default:
*errp = "Expected constant or function definition";
- goto end;
+ break;
}
end:
return val;
}
+
+static Array *
+evalconstast(Ast *ast)
+{
+ Array *val;
+ switch(ast->tag){
+ case AstConst:
+ val = ast->val;
+ break;
+ case AstStrand:
+ val = allocarray(TypeArray, 1, ast->childcount);
+ setshape(val, 0, ast->childcount);
+ for(uvlong i = 0; i < ast->childcount; i++){
+ Array *x = evalconstast(ast->children[i]);
+ if(x)
+ setarray(val, i, x);
+ else{
+ val = nil; /* abort */
+ break;
+ }
+ }
+ if(val)
+ val = simplifyarray(val);
+ break;
+ default:
+ val = nil;
+ }
+ return val;
+}<
\ No newline at end of file