fork download
  1. ; your code goes here
  2. ;; PCL chapter 3
  3.  
  4. (defvar *db* nil)
  5.  
  6. (defun add-record (cd) (push cd *db*))
  7.  
  8. (defun dump-db()
  9. (dolist (cd *db*)
  10. (format t "~{~a:~10t~a~%~}~%" cd)))
  11.  
  12. (defun prompt-read (prompt)
  13. (format *query-io* "~a: " prompt)
  14. (force-output *query-io*)
  15. (read-line *query-io*))
  16.  
  17. (defun prompt-for-cd ()
  18. (make-cd
  19. (prompt-read "Title")
  20. (prompt-read "Artist")
  21. (or
  22. (parse-integer (prompt-read "Rating") :junk-allowed t)
  23. 0)
  24. (y-or-n-p "Ripped [y/n]: ")))
  25.  
  26. (defun add-cds()
  27. (loop (add-record (prompt-for-cd))
  28. (if (not (y-or-n-p "Another? [y/n]: ")) (return))))
  29.  
  30. (defun save-db (filename)
  31. (with-open-file (out filename
  32. :direction :output
  33. :if-exists :supersede)
  34. (with-standard-io-syntax
  35. (print *db* out))))
  36.  
  37. (defun load-db (filename)
  38. (with-open-file (in filename)
  39. (with-standard-io-syntax
  40. (setf *db* (read in)))))
  41.  
  42. (defun select (selector-fn)
  43. (remove-if-not selector-fn *db*))
  44.  
  45. (defmacro where (&rest clauses)
  46. `#'(lambda (cd) (and ,@(make-comparison-list clauses))))
  47.  
  48. (defun make-comparison-list (fields)
  49. (loop while fields
  50. collecting (make-comparison-expr (pop fields) (pop fields))))
  51.  
  52. (defun make-comparison-expr (field value)
  53. `(equal (getf cd ,field) ,value))
  54.  
  55. (defun update (selector-fn &key title artist rating (ripped nil ripped-p))
  56. (setf *db*
  57. (mapcar
  58. #'(lambda (row)
  59. (when (funcall selector-fn row)
  60. (if title (setf (getf row :title) title))
  61. (if artist (setf (getf row :artist) artist))
  62. (if rating (setf (getf row :rating) rating))
  63. (if ripped-p (setf (getf row :ripped) ripped)))
  64. row) *db*)))
  65.  
  66. (defun delete-rows (selector-fn)
  67. (setf *db* (remove-if selector-fn *db*)))
  68.  
  69. (defun make-cd (title artist rating ripped)
  70. (list :title title :artist artist :rating rating :ripped ripped))
  71.  
Success #stdin #stdout 0.01s 10552KB
stdin
Standard input is empty
stdout
Standard output is empty