Commit | Line | Data |
---|---|---|
4525e3cd VS |
1 | (in-package "PARENSCRIPT") |
2 | ||
62ddca23 | 3 | (defparameter *js-target-version* 1.3) |
9da682ca | 4 | |
d434e1d5 VS |
5 | (defvar *parenscript-stream* nil) |
6 | ||
4a987e2b | 7 | (defmacro ps (&body body) |
cb8f8e58 VS |
8 | "Given Parenscript forms (an implicit progn), compiles those forms |
9 | to a JavaScript string at macro-expansion time." | |
d434e1d5 VS |
10 | (let ((printed-forms (parenscript-print |
11 | (ps-compile-statement `(progn ,@body)) | |
12 | nil))) | |
13 | (if (and (not (cdr printed-forms)) | |
14 | (stringp (car printed-forms))) | |
15 | (car printed-forms) | |
16 | (let ((s (gensym))) | |
17 | `(with-output-to-string (,s) | |
18 | ,@(mapcar (lambda (x) `(write-string ,x ,s)) printed-forms)))))) | |
19 | ||
20 | (defmacro ps-to-stream (stream &body body) | |
21 | (let ((printed-forms (parenscript-print | |
22 | (ps-compile-statement `(progn ,@body)) | |
23 | nil))) | |
24 | `(let ((*parenscript-stream* ,stream)) | |
25 | ,@(mapcar (lambda (x) `(write-string ,x *parenscript-stream*)) printed-forms)))) | |
26 | ||
5a69278c VS |
27 | (defun ps* (&rest body) |
28 | "Compiles BODY to a JavaScript string. | |
29 | Body is evaluated." | |
d434e1d5 VS |
30 | (let ((*psw-stream* (or *parenscript-stream* |
31 | (make-string-output-stream)))) | |
32 | (parenscript-print (ps-compile-statement `(progn ,@body)) t) | |
33 | (unless *parenscript-stream* | |
34 | (get-output-stream-string *psw-stream*)))) | |
5a69278c | 35 | |
c11d6a09 TC |
36 | (defmacro ps-doc (&body body) |
37 | "Expands Parenscript forms in a clean environment." | |
cb8f8e58 VS |
38 | (let ((*ps-gensym-counter* 0) |
39 | (*ps-special-variables* nil)) | |
40 | (macroexpand-1 `(ps ,@body)))) | |
41 | ||
157cb2d6 VS |
42 | (defun ps-doc* (ps-form) |
43 | (let ((*ps-gensym-counter* 0) | |
44 | (*ps-special-variables* nil)) | |
5a69278c | 45 | (ps* ps-form))) |
8877a380 | 46 | |
c639fe7f VS |
47 | (defvar *js-inline-string-delimiter* #\" |
48 | "Controls the string delimiter char used when compiling Parenscript in ps-inline.") | |
33c100f0 | 49 | |
c639fe7f | 50 | (defun ps-inline* (form &optional (*js-string-delimiter* *js-inline-string-delimiter*)) |
5a69278c | 51 | (concatenate 'string "javascript:" (ps* form))) |
c639fe7f | 52 | |
e69d0a12 VS |
53 | (defmacro/ps ps-inline (form &optional (string-delimiter *js-inline-string-delimiter*)) |
54 | `(concatenate 'string "javascript:" | |
55 | ,@(let ((*js-string-delimiter* string-delimiter)) | |
d434e1d5 | 56 | (parenscript-print (ps-compile form) nil)))) |
5a69278c VS |
57 | |
58 | (defvar *ps-read-function* #'read | |
59 | "This should be a function that takes the same inputs and returns the same | |
60 | outputs as the common lisp read function. We declare it as a variable to allow | |
61 | a user-supplied reader instead of the default lisp reader.") | |
62 | ||
d434e1d5 VS |
63 | (defun compiled-form-to-string (ps-compiled-form) |
64 | (with-output-to-string (*psw-stream*) | |
65 | (parenscript-print ps-compiled-form t))) | |
66 | ||
5a69278c VS |
67 | (defun ps-compile-stream (stream) |
68 | "Compiles a source stream as if it were a file. Outputs a Javascript string." | |
69 | (let ((*ps-compilation-level* :toplevel) | |
70 | (*package* *package*) | |
71 | (end-read-form '#:unique)) | |
72 | (flet ((read-form () (funcall *ps-read-function* stream nil end-read-form))) | |
73 | (let* ((js-string | |
74 | ;; cons up the forms, compiling as we go, and print the result | |
75 | (do ((form (read-form) (read-form)) | |
76 | (compiled-forms nil)) | |
77 | ((eql form end-read-form) | |
78 | (format nil "~{~A~^;~%~}" | |
79 | (remove-if | |
80 | #'(lambda (x) (or (null x) (= 0 (length x)))) | |
81 | (mapcar 'compiled-form-to-string (nreverse compiled-forms))))) | |
4e6c3ba1 | 82 | (push (ps-compile-statement form) compiled-forms)))) |
5a69278c VS |
83 | js-string)))) |
84 | ||
85 | (defun ps-compile-file (source-file) | |
86 | "Compiles the given Parenscript source file and returns a Javascript string." | |
87 | (with-open-file (stream source-file :direction :input) | |
88 | (ps-compile-stream stream))) |