3 ;; Copyright (C) 2012, 2013 David Vazquez
4 ;; Copyright (C) 2012 Raimon Grau
6 ;; JSCL is free software: you can redistribute it and/or
7 ;; modify it under the terms of the GNU General Public License as
8 ;; published by the Free Software Foundation, either version 3 of the
9 ;; License, or (at your option) any later version.
11 ;; JSCL is distributed in the hope that it will be useful, but
12 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ;; General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with JSCL. If not, see <http://www.gnu.org/licenses/>.
21 (defun special-symbol-name (s &key uppercase)
23 (dotimes (i (length s))
24 (let ((ch (char s i)))
25 (setf dots-only (and dots-only (char= ch #\.)))
26 (when (or (terminalp ch)
28 (and uppercase (not (char= ch (char (string-upcase (string ch)) 0))))
31 (return-from special-symbol-name t))))
34 (defun potential-number (s)
39 (setf ch (and (< i n) (char s (1- (incf i)))))))
42 ((null ch) (return-from potential-number))
45 ((char= ch #\+) (next))
46 ((char= ch #\-) (next))
47 (t (return-from potential-number)))
49 (while (and ch (digit-char-p ch)) (next))
51 (return-from potential-number t)))
55 (while (and ch (digit-char-p ch)) (next))))
56 (when (or (char= ch #\E) (char= ch #\e)
57 (char= ch #\D) (char= ch #\d)
58 (char= ch #\F) (char= ch #\f)
59 (char= ch #\L) (char= ch #\l))
62 ((null ch) (return-from potential-number))
64 ((char= ch #\+) (next))
65 ((char= ch #\-) (next))
66 (t (return-from potential-number)))
67 (unless (and ch (digit-char-p ch))
68 (return-from potential-number))
69 (while (and ch (digit-char-p ch)) (next)))
72 (defun special-escape (s package)
73 (return-from special-escape s)
74 (if (or (potential-number s)
75 (special-symbol-name s :uppercase (not (eq package (find-package "JS")))))
77 (dotimes (i (length s))
78 (let ((ch (char s i)))
79 (when (or (char= ch #\|)
81 (setf result (concat result "\\")))
82 (setf result (concat result (string ch)))))
86 (defvar *print-escape* t)
88 (defun write-to-string (form)
92 (multiple-value-bind (found-symbol status)
93 (find-symbol (symbol-name form))
94 (if (eq found-symbol form)
95 (special-escape (symbol-name form) *package*)
96 (let ((package (symbol-package form))
97 (name (symbol-name form)))
100 ((eq package (find-package "KEYWORD")) "")
101 (t (package-name package)))
103 (if (eq (cadr (multiple-value-list
108 (special-escape name package))))))
109 ((integerp form) (integer-to-string form))
110 ((floatp form) (float-to-string form))
114 (#\newline "newline")
116 (otherwise (string form)))))
117 ((stringp form) (if *print-escape*
118 (concat "\"" (escape-string form) "\"")
121 (let ((name (oget form "fname")))
123 (concat "#<FUNCTION " name ">")
124 (concat "#<FUNCTION>"))))
127 (join-trailing (mapcar #'write-to-string (butlast form)) " ")
128 (let ((last (last form)))
129 (if (null (cdr last))
130 (write-to-string (car last))
131 (concat (write-to-string (car last)) " . " (write-to-string (cdr last)))))
134 (concat "#" (if (zerop (length form))
136 (write-to-string (vector-to-list form)))))
138 (concat "#<PACKAGE " (package-name form) ">"))
140 (concat "#<javascript object>"))))
142 (defun prin1-to-string (form)
143 (let ((*print-escape* t))
144 (write-to-string form)))
146 (defun princ-to-string (form)
147 (let ((*print-escape* nil))
148 (write-to-string form)))
150 (defun write-line (x)
152 (write-string *newline*)
156 (write-string "WARNING: ")
160 (write-line (prin1-to-string x))
163 (defun format (destination fmt &rest args)
164 (let ((len (length fmt))
169 (let ((c (char fmt i)))
171 (let ((next (char fmt (incf i))))
176 (concatf res *newline*))
178 (concatf res (format-special next (car arguments)))
180 (setq res (concat res (char-to-string c))))
188 (defun format-special (chr arg)
190 (#\S (prin1-to-string arg))
191 (#\a (princ-to-string arg))))