From e425895a315d65ff9ca1e2d7911c2fd21d49fe5e Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Mon, 9 May 2022 18:59:23 +0000 Subject: =?UTF-8?q?Fix=20some=20nasty=20bugs=20with=20empty=20lines=20in?= =?UTF-8?q?=20dfns,=20and=20with=20stranding=20of=20=E2=8D=BA=20and=20?= =?UTF-8?q?=E2=8D=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- concurrency.c | 5 ++++- error.c | 2 +- eval.c | 2 ++ lexer.c | 8 +++++++- tests/chain.apl | 7 ++++--- tests/demo.apl | 31 +++++++++++++++++++++++++++++++ 6 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 tests/demo.apl diff --git a/concurrency.c b/concurrency.c index 81ff7b1..1d06a9c 100644 --- a/concurrency.c +++ b/concurrency.c @@ -49,7 +49,7 @@ spawnthread(Function f, Array *left, Array *right) */ Channel *setupdone = chancreate(sizeof(int), 0); SpawnData *sp = emalloc(sizeof(SpawnData)); - sp->func = f; + sp->func = dupfunction(f); sp->left = left ? duparray(left) : nil; sp->right = duparray(right); sp->setupdone = setupdone; @@ -87,6 +87,8 @@ messagesend(Array *a, int id) td->lastmail = newmail; rwakeup(&td->empty); qunlock(&td->lock); + }else{ + throwerror(L"Invalid thread id", EDomain); } } @@ -134,6 +136,7 @@ newprocfn(void *data) unlock(&threadlock); freearray(sp->left); freearray(sp->right); + freefunction(sp->func); free(sp); free(td); } diff --git a/error.c b/error.c index ee6ffe9..e12318a 100644 --- a/error.c +++ b/error.c @@ -37,7 +37,7 @@ throwerror(Rune *msg, int err) td->lasterror = err; if(td->lasterrormsg) free(td->lasterrormsg); - td->lasterrormsg = msg; + td->lasterrormsg = runestrdup(msg); while(frame != nil){ for(ErrorGuard *eg = frame->errorguards; eg != nil; eg = eg->next){ diff --git a/eval.c b/eval.c index 3174cd4..cfe5854 100644 --- a/eval.c +++ b/eval.c @@ -202,6 +202,7 @@ monadfun(Datum *left, Datum *right) { traceprint("Monadic function application\n"); Datum *result = allocdatum(ArrayTag, 0); + SetStrand(right->array, 0); result->array = runfunc(left->func, left->func.left, right->array); return result; } @@ -218,6 +219,7 @@ dyadfun(Datum *left, Datum *right) result->func.code = right->hybrid; } result->func.left = fnSame(left->array); + SetStrand(result->func.left, 0); return result; } diff --git a/lexer.c b/lexer.c index 4e9a4e4..9ce251a 100644 --- a/lexer.c +++ b/lexer.c @@ -72,8 +72,14 @@ lexline(InputStream *input, int toplevel) case L'⋄': if(stmt->ntoks == 0) stmt = lexline(input, toplevel); - else + else{ stmt->next = lexline(input, toplevel); + if(stmt->next && stmt->next->ntoks == 0){ // Prevent empty statements + freestatement(*(stmt->next)); + free(stmt->next); + stmt->next = nil; + } + } goto end; case L'⍝': while(peek != '\n' && !inputEOF(input)) diff --git a/tests/chain.apl b/tests/chain.apl index f6ab04b..aeeab52 100644 --- a/tests/chain.apl +++ b/tests/chain.apl @@ -1,8 +1,9 @@ worker←{ - msg←{1}⍇0 - ⎕←'Worker id ',(⍕⎕self),' got message: ',(⍕msg),' forwarding to ',⍕⍵ + msg←1⍨⍇0 ⍵≡⍬: ⎕←'DONE' + ⎕←'Worker id ',(⍕⎕self),' got message: ',(⍕msg) + ⎕←'Forwarding from ',(⍕⎕self), ' to ',⍕⍵ msg⍈⍵ } -last←worker&⍣100⊢⍬ +last←worker&⍣10⊢⍬ 'Hello there'⍈last diff --git a/tests/demo.apl b/tests/demo.apl new file mode 100644 index 0000000..7a6ddca --- /dev/null +++ b/tests/demo.apl @@ -0,0 +1,31 @@ +⍝ The following demonstrates message passing between an 'iota sever', +⍝ and a client (the user of the iota function). The client always initiates +⍝ communication, and the server must be running, but the client should not +⍝ be able to notice a difference between monadic ⍳ and the iota function, +⍝ even though one does the computation in a different thread. + +iotaServer←{ + msg←1⍨⍇0 + msg≡'stop': ⎕←'Bye bye from indexer' + (from num)←msg + _←(⍳num)⍈from + ∇⍵ +} + +id←0 ⍝ this is an invalid thread id, so it is a sane starting point + +start←{ + id=0: iotaServer&⍬ + id +} + +stop←{ + 'stop'⍈id +} + +iota←{ + ⍝ Sending messages to a nonexisting thread throws a domain error (11) + 11::'Sorry, the iota server is not running' + _←(⎕self ⍵)⍈id + 1⍨⍇0 +} -- cgit v1.2.3