Skip to content

Instantly share code, notes, and snippets.



Last active Jun 10, 2018
What would you like to do?
;; a plist associating keywords with functions
(defvar *commands*
'(:title title-command))
(defun title-command (params)
(format t "Title command function. Params: ~A" params))
;; I want to read the keyword from the CLI, but it's a char array
;; how can I cast it to keyword?
(apply (getf *commands* (read-line)) '(1 2 3))
;; using (intern (read-line) "KEYWORD") doesn't work
;; NOTE: I want to input `title`in the CLI, not `:title`.
(getf *commands* (intern (read-line) "KEYWORD")) ;; => This returns NIL even if I type "title"

This comment has been minimized.

Copy link

@informatimago informatimago commented Jun 10, 2018

(defvar *commands* (make-hash-table))

(defmacro define-command (name (&rest lambda-list) &body body)
  (let ((fname (intern (format nil "~A-COMMAND" name)))
        (kword (intern (symbol-name name) "KEYWORD")))
      (defun ,fname ,lambda-list ,@body)
      (setf (gethash ',kword *commands*) (function ,fname))

(define-command title (&rest params)
  (format t "Title command function. Params: ~A~&" params)

(defun call-command (command)
  (apply (gethash command *commands*
                  (lambda (&rest parameters)
                    (declare (ignore parameters))
                    (format t "Unknown command ~A~%" command)
         '(1 2 3)))

(defun read-command ()
  (format *query-io* "Prompt: ")
  (finish-output *query-io*)
  (intern (string-upcase (string-trim " " (read-line *query-io*))) "KEYWORD"))

(define-command quit (&rest parameters)
  (declare (ignore parameters))
  (throw 'quit 'done))

(catch 'quit
    (call-command (read-command))))


cl-user> (load "/tmp/c.lisp")
Prompt: foo
Unknown command foo
Prompt: title
Title command function. Params: (1 2 3)
Prompt: quit


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment