(in-package #:json) (defun to-string (value) (defun indent (str level) (concatenate 'string (make-string (* 4 level) :initial-element #\Space) str)) (defun to-string-rec (value level) (cond ((stringp value) (format nil "\"~a\"" value)) ((symbolp value) (string-downcase (symbol-name value))) ((arrayp value) (format nil "[~&~{~a~^,~&~}]" (map 'list (lambda (x) (indent (to-string-rec x (1+ level)) level)) value))) ((hash-table-p value) (let (items) (maphash (lambda (k v) (push (indent (format nil "\"~a\": ~a" k (to-string-rec v (1+ level))) level) items)) value) (format nil "{~&~{~a~^,~&~}}" items))) (t value))) (to-string-rec value 0)) (defun to-file (value filename) (with-open-file (s filename :direction :output :if-exists :supersede :if-does-not-exist :create) (princ (to-string value) s) t))