<commit_before>;; This file is part of yason, a Common Lisp JSON parser/encoder
;;
;; Copyright (c) 2008 <NAME>
;; All rights reserved.
;;
;; Please see the file LICENSE in the distribution.

(in-package :yason)

(defvar *json-output*)

(defgeneric encode (object &optional stream)

  (:documentation "Encode OBJECT to STREAM in JSON format.  May be
  specialized by applications to perform specific rendering.  STREAM
  defaults to *STANDARD-OUTPUT*."))

(defparameter *char-replacements*
  (alexandria:plist-hash-table
   '(#\\ "\\\\"
     #\" "\\\""
     #\/ "\\/"
     #\Backspace "\\b"
     #\Page "\\f"
     #\Newline "\\n"
     #\Return "\\r"
     #\Tab "\\t")))

(defmethod encode ((string string) &optional (stream *standard-output*))
  (write-char #\")
  (dotimes (i (length string))
    (let* ((char (aref string i))
           (replacement (gethash char *char-replacements*)))
      (if replacement
          (write-string replacement)
          (write-char char))))
  (write-char #\")
  string)

(defmethod encode ((object rational) &optional (stream *standard-output*))
  (encode (float object) stream)
  object)

(defmethod encode ((object double-float) &optional (stream *standard-output*))
  (encode (coerce object 'single-float) stream)
  object)

(defmethod encode ((object float) &optional (stream *standard-output*))
  (princ object stream)
  object)

(defmethod encode ((object integer) &optional (stream *standard-output*))
  (princ object stream))

(defmethod encode ((object hash-table) &optional (stream *standard-output*))
  (write-char #\{)
  (let (printed)
    (maphash (lambda (key value)
               (if printed
                   (write-char #\,)
                   (setf printed t))
               (encode key stream)
               (write-char #\:)
               (encode value stream))
             object))
  (write-char #\})
  object)

(defmethod encode ((object vector) &optional (stream *standard-output*))
  (write-char #\[)
  (let (printed)
    (loop
       for value across object
       do
       (when printed
         (write-char #\,))
       (setf printed t)
       (encode value stream)))
  (write-char #\])
  object)

(defmethod encode ((object list) &optional (stream *standard-output*))
  (write-char #\[)
  (let (printed)
    (dolist (value object)
      (if printed
          (write-char #\,)
          (setf printed t))
      (encode value stream)))
  (write-char #\])
  object)

(defmethod encode ((object (eql 'true)) &optional (stream *standard-output*))
  (write-string "true" stream)
  object)

(defmethod encode ((object (eql 'false)) &optional (stream *standard-output*))
  (write-string "false" stream)<commit_msg>Add stream argument to WRITE-* invocations in ENCODE methods.  Next time, I'll go for "patch" instead of doing patches received by hand.  Thanks to <NAME> for patiently reporting ;).<commit_after>;; This file is part of yason, a Common Lisp JSON parser/encoder
;;
;; Copyright (c) 2008 <NAME>
;; All rights reserved.
;;
;; Please see the file LICENSE in the distribution.

(in-package :yason)

(defvar *json-output*)

(defgeneric encode (object &optional stream)

  (:documentation "Encode OBJECT to STREAM in JSON format.  May be
  specialized by applications to perform specific rendering.  STREAM
  defaults to *STANDARD-OUTPUT*."))

(defparameter *char-replacements*
  (alexandria:plist-hash-table
   '(#\\ "\\\\"
     #\" "\\\""
     #\/ "\\/"
     #\Backspace "\\b"
     #\Page "\\f"
     #\Newline "\\n"
     #\Return "\\r"
     #\Tab "\\t")))

(defmethod encode ((string string) &optional (stream *standard-output*))
  (write-char #\" stream)
  (dotimes (i (length string))
    (let* ((char (aref string i))
           (replacement (gethash char *char-replacements*)))
      (if replacement
          (write-string replacement stream)
          (write-char char stream))))
  (write-char #\" stream)
  string)

(defmethod encode ((object rational) &optional (stream *standard-output*))
  (encode (float object) stream)
  object)

(defmethod encode ((object double-float) &optional (stream *standard-output*))
  (encode (coerce object 'single-float) stream)
  object)

(defmethod encode ((object float) &optional (stream *standard-output*))
  (princ object stream)
  object)

(defmethod encode ((object integer) &optional (stream *standard-output*))
  (princ object stream))

(defmethod encode ((object hash-table) &optional (stream *standard-output*))
  (write-char #\{ stream)
  (let (printed)
    (maphash (lambda (key value)
               (if printed
                   (write-char #\, stream)
                   (setf printed t))
               (encode key stream)
               (write-char #\: stream)
               (encode value stream))
             object))
  (write-char #\} stream)
  object)

(defmethod encode ((object vector) &optional (stream *standard-output*))
  (write-char #\[ stream)
  (let (printed)
    (loop
       for value across object
       do
       (when printed
         (write-char #\, stream))
       (setf printed t)
       (encode value stream)))
  (write-char #\] stream)
  object)

(defmethod encode ((object list) &optional (stream *standard-output*))
  (write-char #\[ stream)
  (let (printed)
    (dolist (value object)
      (if printed
          (write-char #\, stream)
          (setf printed t))
      (encode value stream)))
  (write-char #\] stream)
  object)

(defmethod encode ((object (eql 'true)) &optional (stream *standard-output*))
  (write-string "true" stream)
  object)

(defmethod encode ((object (eql 'false)) &optional (stream *standard-output*))
  (write-string "false" stream)
{'fraction_non_alphanumeric': 0.1495642895251645, 'fraction_numerical': 0.0014227280810955006, 'mean_word_length': 2.8284547311095984, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6455305', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1697, 'n_words': 539}