diff options
-rw-r--r-- | lexer.c | 4 | ||||
-rw-r--r-- | quadnames.c | 166 |
2 files changed, 167 insertions, 3 deletions
@@ -194,7 +194,7 @@ get_digits: *p = 0; ungetrune(input); stmt->toks[stmt->ntoks] = allocdatum(ArrayTag, 0); - stmt->toks[stmt->ntoks]->array = floating ? mkscalarfloat(atof(buf)) : mkscalarint(atoll(buf)); + stmt->toks[stmt->ntoks]->array = floating ? mkscalarfloat(atof(buf)) : mkscalarint(strtoull(buf, nil, 0)); }else if(runestrchr(L"⍺⍵⍶⍹", peek)){ Rune name[2] = {peek, 0}; stmt->toks[stmt->ntoks] = allocdatum(NameTag, 0); @@ -216,7 +216,7 @@ get_digits: Rune *p = buf; *p++ = peek; peek = getrune(input); - while(isalpharune(peek)){ + while(isalpharune(peek) || isdigitrune(peek)){ *p++ = toupperrune(peek); peek = getrune(input); } diff --git a/quadnames.c b/quadnames.c index 143eef1..b7c04d0 100644 --- a/quadnames.c +++ b/quadnames.c @@ -34,6 +34,13 @@ Array *quaddl(Array *); Array *quadthreads1(Array *); Array *quadthreads2(Array *, Array *); Array *quadserial(Array *, Array *); +Array *quadopen(Array *, Array *); +Array *quadcreate(Array *, Array *); +Array *quadclose(Array *); +Array *quadread(Array *, Array *); +Array *quadwrite(Array *, Array *); +Array *quadpipe(Array *); +Array *quadfd2path(Array *); static Rune *quadquotebuf = nil; static Array *session = nil; @@ -59,6 +66,13 @@ QuadnameDef quadnames[] = { {L"⎕DL", FunctionTag, nil, nil, quaddl, nil}, {L"⎕THREADS", FunctionTag, nil, nil, quadthreads1, quadthreads2}, {L"⎕SERIAL", FunctionTag, nil, nil, nil, quadserial}, + {L"⎕OPEN", FunctionTag, nil, nil, nil, quadopen}, + {L"⎕CREATE", FunctionTag, nil, nil, nil, quadcreate}, + {L"⎕CLOSE", FunctionTag, nil, nil, quadclose, nil}, + {L"⎕READ", FunctionTag, nil, nil, nil, quadread}, + {L"⎕WRITE", FunctionTag, nil, nil, nil, quadwrite}, + {L"⎕PIPE", FunctionTag, nil, nil, quadpipe, nil}, + {L"⎕FD2PATH", FunctionTag, nil, nil, quadfd2path, nil}, {nil, 0, nil, nil, nil, nil} /* MUST BE LAST */ }; @@ -589,5 +603,155 @@ quadserial(Array *mode, Array *a) } return result; -} +} + +/* ⎕OPEN */ +Array * +quadopen(Array *file, Array *omode) +{ + if(GetType(file) != AtypeRune || GetRank(file) > 1) + throwerror(L"Invalid file name", EDomain); + if(GetType(omode) != AtypeInt || GetSize(omode) != 1) + throwerror(L"Invalid mode", EDomain); + + Rune *tmp = pparray(file); + char *filename = smprint("%S", tmp); + int mode = omode->intdata[0]; + int ret = open(filename, mode); + free(tmp); + free(filename); + return mkscalarint(ret); +} + +/* ⎕CREATE */ +Array * +quadcreate(Array *file, Array *arg) +{ + if(GetType(file) != AtypeRune || GetRank(file) > 1) + throwerror(L"Invalid file name", EDomain); + if(GetType(arg) != AtypeInt || GetRank(arg) != 1 || GetSize(arg) != 2) + throwerror(L"Invalid mode+perm", EDomain); + + Rune *tmp = pparray(file); + char *filename = smprint("%S", tmp); + int ret = create(filename, arg->intdata[0], arg->intdata[1]); + free(tmp); + free(filename); + return mkscalarint(ret); +} + +/* ⎕CLOSE */ +Array * +quadclose(Array *fd) +{ + if(GetSize(fd) != 1 || GetType(fd) != AtypeInt) + throwerror(nil, EDomain); + int ret = close(fd->intdata[0]); + return mkscalarint(ret); +} + +/* ⎕READ */ +Array * +quadread(Array *fd, Array *nbytes) +{ + if(GetType(fd) != AtypeInt || GetSize(fd) != 1) + throwerror(L"Invalid fd", EDomain); + if(GetType(nbytes) != AtypeInt || GetSize(nbytes) != 1 || nbytes->intdata[0] < 1) + throwerror(L"Invalid byte coint", EDomain); + + u8int *buf = emalloc(nbytes->intdata[0]); + long nread = read(fd->intdata[0], buf, nbytes->intdata[0]); + if(nread >= 0) + buf = erealloc(buf, nread); + else{ + free(buf); + throwerror(L"Read failed", EDomain); + } + Array *res = allocarray(AtypeInt, 1, nread); + res->shape[0] = nread; + for(int i = 0; i < nread; i++) + res->intdata[i] = buf[i]; + free(buf); + return res; +} +/* ⎕WRITE */ +Array * +quadwrite(Array *fd, Array *data) +{ + if(GetType(fd) != AtypeInt || GetSize(fd) != 1) + throwerror(L"Invalid fd", EDomain); + if(GetType(data) != AtypeInt || GetRank(fd) > 1) + throwerror(L"Data must be a scalar or vector of bytes", EDomain); + + u8int *raw = emalloc(GetSize(data)); + for(int i = 0; i < GetSize(data); i++){ + u64int v = data->intdata[i]; + if(v > 255){ + free(raw); + throwerror(L"Data values must be bytes", EDomain); + }else + raw[i] = v; + } + long ret = write(fd->intdata[0], raw, GetSize(data)); + free(raw); + return mkscalarint(ret); +} + +/* ⎕PIPE */ +Array * +quadpipe(Array *name) +{ + Array *result; + int p[2]; + + if(GetSize(name) > 0 && (GetType(name) != AtypeRune || GetRank(name) > 1)) + throwerror(L"Invalid pipe name", EDomain); + + if(GetSize(name) == 0){ /* Unnamed pipe */ + pipe(p); + result = allocarray(AtypeInt, 1, 2); + result->shape[0] = 2; + result->intdata[0] = p[0]; + result->intdata[1] = p[1]; + }else{ + /* If the name exists, open that pipe, otherwise create a new one */ + Rune *tmp = pparray(name); + char *name = smprint("/srv/%S", tmp); + free(tmp); + + int fd = open(name, ORDWR); + if(fd > 0) + result = mkscalarint(fd); + else{ + fd = create(name, OWRITE, 0666); + if(fd < 0) + throwerror(L"Named pipe could not be opened", EDomain); + pipe(p); + fprint(fd, "%d", p[0]); + close(fd); + close(p[0]); + result = mkscalarint(p[1]); + } + free(name); + } + return result; +} + +/* ⎕FD2PATH */ +Array * +quadfd2path(Array *fd) +{ + if(GetType(fd) != AtypeInt || GetSize(fd) != 1) + throwerror(L"Invalid fd", EDomain); + char *buf = emalloc(1024); + int ret = fd2path(fd->intdata[0], buf, 1024); + if(ret != 0) + throwerror(nil, EDomain); + + Rune *path = runesmprint("%s", buf); + Array *res = mkrunearray(path); + free(buf); + free(path); + return res; +}
\ No newline at end of file |