Skip to content

Instantly share code, notes, and snippets.

@gosukiwi
Last active June 10, 2018 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gosukiwi/f244f4f455f9b40d4da5c51bec1a903a to your computer and use it in GitHub Desktop.
Save gosukiwi/f244f4f455f9b40d4da5c51bec1a903a to your computer and use it in GitHub Desktop.
;; 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"
@informatimago
Copy link

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")))
   `(progn
      (defun ,fname ,lambda-list ,@body)
      (setf (gethash ',kword *commands*) (function ,fname))
      ',name)))

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

(defun call-command (command)
  (apply (gethash command *commands*
                  (lambda (&rest parameters)
                    (declare (ignore parameters))
                    (format t "Unknown command ~A~%" command)
                    (finish-output)))
         '(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
 (loop
    (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

#P"/private/tmp/c.lisp"
cl-user>

|#

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