nex3 / arc

Paul Graham's Brand New Lisp

This URL has Read+Write access

pg and rtm <> (author)
Sat Jul 04 16:42:33 -0700 2009
rntz (committer)
Sat Jul 04 16:42:33 -0700 2009
arc / prompt.arc
100644 120 lines (103 sloc) 3.26 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
; Prompt: Web-based programming application. 4 Aug 06.
 
(= appdir* "arc/apps/")
 
(defop prompt req
  (let user (get-user req)
    (if (admin user)
        (prompt-page user)
        (pr "Sorry."))))
 
(def prompt-page (user . msg)
  (ensure-dir appdir*)
  (ensure-dir (string appdir* user))
  (whitepage
    (prbold "Prompt")
    (hspace 20)
    (pr user " | ")
    (link "logout")
    (when msg (hspace 10) (apply pr msg))
    (br2)
    (tag (table border 0 cellspacing 10)
      (each app (dir (+ appdir* user))
        (tr (td app)
            (td (ulink user 'edit (edit-app user app)))
            (td (ulink user 'run (run-app user app)))
            (td (hspace 40)
                (ulink user 'delete (rem-app user app))))))
    (br2)
    (aform (fn (req)
             (when-umatch user req
               (aif (goodname (arg req "app"))
                    (edit-app user it)
                    (prompt-page user "Bad name."))))
       (tab (row "name:" (input "app") (submit "create app"))))))
 
(def app-path (user app)
  (and user app (+ appdir* user "/" app)))
 
(def read-app (user app)
  (aand (app-path user app)
        (file-exists it)
        (readfile it)))
 
(def write-app (user app exprs)
  (awhen (app-path user app)
    (w/outfile o it
      (each e exprs (write e o)))))
 
(def rem-app (user app)
  (let file (app-path user app)
    (if (file-exists file)
        (do (rmfile (app-path user app))
            (prompt-page user "Program " app " deleted."))
        (prompt-page user "No such app."))))
 
(def edit-app (user app)
  (whitepage
    (pr "user: " user " app: " app)
    (br2)
    (aform (fn (req)
             (let u2 (get-user req)
               (if (is u2 user)
                   (do (when (is (arg req "cmd") "save")
                         (write-app user app (readall (arg req "exprs"))))
                       (prompt-page user))
                   (login-page 'both nil
                               (fn (u ip) (prompt-page u))))))
      (textarea "exprs" 10 82
        (pprcode (read-app user app)))
      (br2)
      (buts 'cmd "save" "cancel"))))
 
(def pprcode (exprs)
  (each e exprs
    (ppr e)
    (pr "\n\n")))
 
(def view-app (user app)
  (whitepage
    (pr "user: " user " app: " app)
    (br2)
    (tag xmp (pprcode (read-app user app)))))
 
(def run-app (user app)
  (let exprs (read-app user app)
    (if exprs
        (on-err (fn (c) (pr "Error: " (details c)))
          (fn () (map eval exprs)))
        (prompt-page user "Error: No application " app " for user " user))))
 
(wipe repl-history*)
 
(defop repl req
  (if (admin (get-user req))
      (replpage req)
      (pr "Sorry.")))
 
(def replpage (req)
  (whitepage
    (repl (readall (or (arg req "expr") "")) "repl")))
 
(def repl (exprs url)
    (each expr exprs
      (on-err (fn (c) (push (list expr c t) repl-history*))
              (fn ()
                (= that (eval expr) thatexpr expr)
                (push (list expr that) repl-history*))))
    (form url
      (textarea "expr" 8 60)
      (sp)
      (submit))
    (tag xmp
      (each (expr val err) (firstn 20 repl-history*)
        (pr "> ")
        (ppr expr)
        (prn)
        (prn (if err "Error: " "")
             (ellipsize (tostring (write val)) 800)))))