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