~edwargix/tallyard

5b942166f50034b4ff134e8d93dc3d16243791d7 — David Florness 5 years ago 41b9808
Repl errors should not kill the bulletin
1 files changed, 50 insertions(+), 46 deletions(-)

M bulletin.rkt
M bulletin.rkt => bulletin.rkt +50 -46
@@ 194,49 194,53 @@
  (let loop ()
    (let ([line (readline "> ")])
      (when (not (eq? line eof))
        (let ([sp (open-input-string line)])
          (match (read sp)
            ['add (match (read sp)
                    ['cand
                     (let* ([cand (read sp)]
                            [cand (if (symbol? cand)
                                      (symbol->string cand)
                                      cand)])
                       (hash-update! election->candidates
                                     election
                                     (λ (l)
                                       (cons cand l))))]
                    [else (displayln "cannot add that")])]
            ['list (match (read sp)
                     ['cands
                      (displayln (hash-ref election->candidates election))]
                     ['peers
                      (displayln _peers)])]
            ['set (match (read sp)
                    ['election (let ([election (read sp)])
                                 (election-set! election))]
                    [else (displayln "cannot set that")])]
            ['open
             (if (memq state '(closed registering))
                 (transition 'committing)
                 (displayln "election is not closed"))]
            ['close
             (transition 'closed)
             (reset)]
            ['register
             (transition 'registering)
             (reset)]
            ['kick (if (eq? state 'closed)
                       (let* ([peer-uname (read sp)]
                              [peer-uname (if (symbol? peer-uname)
                                        (symbol->string peer-uname)
                                        peer-uname)])
                         (for ([peer _peers]
                               #:when (equal? (hash-ref peer 'username)
                                              peer-uname))
                           (set-remove! _peers peer)))
                       (displayln "close the election first"))]
            [else (displayln "unknown command")])
          (when (not (equal? line ""))
            (add-history line))
          (loop))))))
        (when (not (equal? line ""))
          (add-history line))
        (with-handlers ([exn:fail? (λ (ex)
                                     (displayln (exn-message ex))
                                     (break-enabled #t)
                                     (loop))])
          (let ([sp (open-input-string line)])
            (match (read sp)
              ['add (match (read sp)
                      ['cand
                       (let* ([cand (read sp)]
                              [cand (if (symbol? cand)
                                        (symbol->string cand)
                                        cand)])
                         (hash-update! election->candidates
                                       election
                                       (λ (l)
                                         (cons cand l))))]
                      [else (displayln "cannot add that")])]
              ['list (match (read sp)
                       ['cands
                        (displayln (hash-ref election->candidates election))]
                       ['peers
                        (displayln _peers)])]
              ['set (match (read sp)
                      ['election (let ([election (read sp)])
                                   (election-set! election))]
                      [else (displayln "cannot set that")])]
              ['open
               (if (memq state '(closed registering))
                   (transition 'committing)
                   (displayln "election is not closed"))]
              ['close
               (transition 'closed)
               (reset)]
              ['register
               (transition 'registering)
               (reset)]
              ['kick (if (eq? state 'closed)
                         (let* ([peer-uname (read sp)]
                                [peer-uname (if (symbol? peer-uname)
                                                (symbol->string peer-uname)
                                                peer-uname)])
                           (for ([peer _peers]
                                 #:when (equal? (hash-ref peer 'username)
                                                peer-uname))
                             (set-remove! _peers peer)))
                         (displayln "close the election first"))]
              [else (displayln "unknown command")])
            (loop)))))))