Fix bug with `until` and #:collect.
`state` now yields the explicit values given in a termination clause *prepended* to the `#:collect`ed variables of the calling actor at the time the state terminates. `until` now yields zero values in its sole termination clause, and thus yields only the `#:collect`ed values.
This commit is contained in:
parent
e2b7805232
commit
debd191992
|
@ -38,7 +38,7 @@ Just a sketch, at the moment.
|
|||
Patterns, P := ... ;; uses $var as binder
|
||||
|
||||
(define-syntax-rule (until B E O ...)
|
||||
(state [B O ...] [E (final-values-of B)]))
|
||||
(state [B O ...] [E (values)]))
|
||||
|
||||
(define-syntax-rule (forever B O ...)
|
||||
(state [B O ...]))
|
||||
|
@ -47,13 +47,15 @@ Note also that `falling-edge` is encodable using `rising-edge` and
|
|||
`not`, and that `forall` is encodable using `exists` and `not`.
|
||||
|
||||
`state` has the `B` bindings visible in the `I`s, and returns the
|
||||
value of the final `I` from the `E` exit branch that was chosen.
|
||||
value(s) of the final `I` from the `E` exit branch that was chosen
|
||||
*prepended* to the values of the calling actor's variables at the time
|
||||
of `state` termination.
|
||||
|
||||
There are four kinds of actor-spawning `I`s: `actor`, `network`,
|
||||
`state` and `background`. Neither `actor`, `network` nor `background`
|
||||
yield a value; only `state` does so. However, both `state` and
|
||||
`background` link to their invoking contexts, because `state` may
|
||||
return a value or crash, and `background` may crash. Actors using
|
||||
return values or crash, and `background` may crash. Actors using
|
||||
`state` and `background` must therefore have a special continuation
|
||||
table in their private state to link them to their `state` and
|
||||
`background` logical-children-but-physical-siblings. The link
|
||||
|
|
|
@ -227,11 +227,7 @@
|
|||
(define-syntax (until stx)
|
||||
(syntax-parse stx
|
||||
[(_ E init:init bs:bindings O ...)
|
||||
(if (stx-null? #'(bs.id ...))
|
||||
#'(state #:init [init.I ...] [#:collect [] O ...]
|
||||
[E (void)])
|
||||
#'(state #:init [init.I ...] [#:collect [(bs.id bs.init) ...] O ...]
|
||||
[E (values bs.id ...)]))]))
|
||||
#'(state #:init [init.I ...] [#:collect [(bs.id bs.init) ...] O ...] [E (values)])]))
|
||||
|
||||
;; Sugar
|
||||
(define-syntax (forever stx)
|
||||
|
@ -291,7 +287,8 @@
|
|||
;; continuation)
|
||||
(handle-actor-syscall (transition (struct-copy actor-state s [continuation-table new-table])
|
||||
'())
|
||||
(apply continuation (actor-state-variables s) reply-values)))
|
||||
(apply continuation
|
||||
(append reply-values (vector->list (actor-state-variables s))))))
|
||||
|
||||
;; ActorState -> Transition
|
||||
(define (perform-pending-patch s)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
;; Toy file system, based on the example in the ESOP2016 submission.
|
||||
|
||||
(require prospect/actor)
|
||||
(require prospect/drivers/timer)
|
||||
(require (only-in racket/port read-bytes-line-evt))
|
||||
(require (only-in racket/string string-trim string-split))
|
||||
|
||||
|
@ -9,47 +10,65 @@
|
|||
(struct save (file) #:prefab)
|
||||
(struct delete (name) #:prefab)
|
||||
|
||||
(spawn-timer-driver)
|
||||
|
||||
(%%boot
|
||||
(lambda ()
|
||||
(actor
|
||||
|
||||
(actor (forever #:collect [(files (hash))]
|
||||
(on (asserted (observe (file $name _)))
|
||||
(printf "Someone opened ~v\n" name)
|
||||
(until (retracted (observe (file name _)))
|
||||
#:collect [(content (hash-ref files name #f))]
|
||||
(assert (file name content))
|
||||
(on (message (save (file name $content))) content)
|
||||
(on (message (delete name)) #f))
|
||||
;; BUG: files has not been properly updated here
|
||||
files)
|
||||
(printf "At least one reader exists for ~v\n" name)
|
||||
(begin0 (until (retracted (observe (file name _)))
|
||||
#:collect [(content (hash-ref files name #f))]
|
||||
(assert (file name content))
|
||||
(on (message (save (file name $content))) content)
|
||||
(on (message (delete name)) #f))
|
||||
(printf "No remaining readers exist for ~v\n" name)))
|
||||
(on (message (save (file $name $content))) (hash-set files name content))
|
||||
(on (message (delete $name)) (hash-remove files name))))
|
||||
|
||||
(define (sleep sec)
|
||||
(define timer-id (gensym 'sleep))
|
||||
(until (message (timer-expired timer-id _))
|
||||
#:init [(send! (set-timer timer-id (* sec 1000.0) 'relative))]))
|
||||
|
||||
;; Shell
|
||||
(let ((e (read-bytes-line-evt (current-input-port) 'any)))
|
||||
(define (print-prompt)
|
||||
(printf "> ")
|
||||
(flush-output))
|
||||
(define reader-count 0)
|
||||
(define (generate-reader-id)
|
||||
(begin0 reader-count
|
||||
(set! reader-count (+ reader-count 1))))
|
||||
(actor (print-prompt)
|
||||
(until (message (external-event e (list (? eof-object? _))) #:meta-level 1)
|
||||
(on (message (external-event e (list (? bytes? $bs))) #:meta-level 1)
|
||||
(match (string-split (string-trim (bytes->string/utf-8 bs)))
|
||||
[(list "open" name)
|
||||
(actor (printf "Opening file ~a.\n" name)
|
||||
(define reader-id (generate-reader-id))
|
||||
(actor (printf "Reader ~a opening file ~v.\n" reader-id name)
|
||||
(until (message `(stop-watching ,name))
|
||||
(on (asserted (file name $contents))
|
||||
(printf "File ~a contains: ~v\n" name contents)))
|
||||
(printf "Closing file ~a.\n" name))]
|
||||
(printf "Reader ~a sees that ~v contains: ~v\n"
|
||||
reader-id
|
||||
name
|
||||
contents)))
|
||||
(printf "Reader ~a closing file ~v.\n" reader-id name))]
|
||||
[(list "close" name)
|
||||
(send! `(stop-watching ,name))]
|
||||
[(list* "write" name words)
|
||||
(send! (save (file name words)))]
|
||||
[(list "delete" name)
|
||||
(send! (delete name))]
|
||||
[_
|
||||
(printf "I'm afraid I didn't understand that.\n")
|
||||
(printf "Try: open filename\n")
|
||||
(printf " close filename\n")
|
||||
(printf " write filename some text goes here\n")])
|
||||
(printf " write filename some text goes here\n")
|
||||
(printf " delete filename\n")])
|
||||
(sleep 0.1)
|
||||
(print-prompt)))))
|
||||
|
||||
)))
|
||||
|
|
Loading…
Reference in New Issue