Commit | Line | Data |
---|---|---|
9da682ca RD |
1 | (in-package :parenscript) |
2 | ||
3 | (defmacro with-new-compilation-environment ((var) &body body) | |
4 | `(let* ((,var (make-basic-compilation-environment)) | |
5 | (*compilation-environment* ,var)) | |
6 | ,@body)) | |
7 | ||
9da682ca RD |
8 | (defun translate-ast (compiled-expr |
9 | &key | |
10 | (comp-env *compilation-environment*) | |
11 | (output-stream *standard-output*) | |
12 | (output-spec :javascript) | |
13 | (pretty-print t)) | |
14 | "Translates a compiled Parenscript program (compiled with COMPILE-PAREN-FORM) | |
15 | to a Javascript string. Outputs to the stream OUTPUT-STREAM in the language given | |
16 | by OUTPUT-SPEC, pretty printing if PRETTY-PRINT is non-null. | |
17 | ||
18 | OUTPUT-SPEC must be :javascript at the moment." | |
5aa10005 | 19 | (declare (ignore comp-env)) |
9da682ca RD |
20 | (when (not (eql :javascript output-spec)) |
21 | (error "Unsupported output-spec for translation: ~A" output-spec)) | |
22 | (when (eql :javascript output-spec) | |
5aa10005 RD |
23 | ; (if (not pretty-print) |
24 | ; (js-translate compiled-expr :statement output-stream) | |
25 | (write-string (string-join | |
26 | (ps-js::js-to-statement-strings compiled-expr 0) | |
27 | (string #\Newline)) | |
28 | output-stream))) | |
9da682ca | 29 | |
a9fce0a7 RD |
30 | (defun non-nil-comp-env () |
31 | "Returns a sane compilation environment. Either the one currently bound or a new | |
32 | one." | |
33 | (or *compilation-environment* | |
34 | (make-basic-compilation-environment))) | |
35 | ||
36 | ||
9da682ca RD |
37 | (defun compile-script (script-form |
38 | &key | |
39 | (output-spec :javascript) | |
40 | (pretty-print t) | |
41 | (output-stream nil) | |
a98e58ee | 42 | (toplevel-p t) |
a9fce0a7 | 43 | (comp-env (non-nil-comp-env))) |
9da682ca RD |
44 | "Compiles the Parenscript form SCRIPT-FORM into the language specified by OUTPUT-SPEC. |
45 | Non-null PRETTY-PRINT values result in a pretty-printed output code. If OUTPUT-STREAM | |
46 | is NIL, then the result is a string; otherwise code is output to the OUTPUT-STREAM stream. | |
47 | COMP-ENV is the compilation environment in which to compile the form. | |
48 | ||
49 | This is the main function used by Parenscript users to compile their code to Javascript (and | |
50 | potentially other languages)." | |
51 | (macrolet ((with-output-stream ((var) &body body) | |
52 | `(if (null output-stream) | |
53 | (with-output-to-string (,var) | |
54 | ,@body) | |
55 | (let ((,var output-stream)) | |
56 | ,@body)))) | |
57 | (with-output-stream (stream) | |
a98e58ee RD |
58 | (let* ((*compilation-environment* comp-env) |
59 | (compiled | |
60 | (if toplevel-p | |
61 | (compile-parenscript-form | |
62 | comp-env | |
63 | (compile-parenscript-form comp-env script-form :toplevel-p t)) | |
64 | (compile-parenscript-form comp-env script-form :toplevel-p nil)))) | |
65 | (translate-ast | |
66 | compiled | |
67 | ; (compile-script-form script-form :comp-env comp-env) | |
68 | :comp-env comp-env | |
69 | :output-stream stream | |
70 | :output-spec output-spec | |
71 | :pretty-print pretty-print))))) | |
72 | ||
73 | (defun compile-script-file (source-file | |
74 | &key | |
75 | (output-spec :javascript) | |
a9fce0a7 | 76 | (comp-env (non-nil-comp-env)) |
a98e58ee RD |
77 | (pretty-print t) |
78 | (output-stream *standard-output*)) | |
79 | "Compiles the given Parenscript source file and outputs the results | |
80 | to the given output stream." | |
81 | (setf (comp-env-compiling-toplevel-p comp-env) t) | |
171bbab3 RD |
82 | (with-open-file (input source-file :direction :input) |
83 | (let ((end-read-form '#:unique)) | |
84 | (flet ((read-form () | |
85 | (parenscript.reader:read input nil end-read-form))) | |
86 | (macrolet ((with-output-stream ((var) &body body) | |
87 | `(if (null output-stream) | |
88 | (with-output-to-string (,var) | |
89 | ,@body) | |
90 | (let ((,var output-stream)) | |
91 | ,@body)))) | |
92 | (let* ((*compilation-environment* comp-env) | |
93 | (compiled | |
94 | (do ((form (read-form) (read-form)) | |
95 | (compiled-forms nil)) | |
96 | ((eql form end-read-form) | |
97 | (compile-parenscript-form | |
98 | comp-env | |
99 | `(progn ,@(nreverse compiled-forms)) | |
100 | :toplevel-p nil)) | |
101 | (let ((tl-compiled-form | |
102 | (compile-parenscript-form comp-env form :toplevel-p t))) | |
103 | (push tl-compiled-form compiled-forms))))) | |
104 | (with-output-stream (output) | |
105 | (translate-ast | |
106 | compiled | |
107 | :comp-env comp-env | |
108 | :output-stream output | |
109 | :output-spec output-spec | |
110 | :pretty-print pretty-print)))))))) | |
a9fce0a7 RD |
111 | |
112 | (defun compile-script-system (system | |
113 | &rest args | |
114 | &key | |
115 | (output-spec :javascript) | |
116 | (pretty-print t) | |
117 | (output-to-stream t) | |
118 | (output-stream *standard-output*) | |
119 | output-to-files ;; currently ignored | |
120 | (comp-env (non-nil-comp-env))) | |
121 | "Compiles a collection of parenscripts as described by an ASDF system into files or | |
122 | a specified output stream." | |
123 | (asdf:operate 'asdf::parenscript-compile-op system | |
124 | :output-spec output-spec | |
125 | :pretty-print pretty-print | |
126 | ; :output-to-stream t | |
127 | :output-stream output-stream | |
128 | :comp-env comp-env | |
129 | :force-p t | |
130 | )) | |
131 | ||
132 | ||
133 | ;(defun compile-script-system-component (system-designator | |
134 | ||
a98e58ee RD |
135 | ;(defun compile-script-file (script-src-file |
136 | ; &key | |
137 | ; (output-spec :javascript) | |
138 | ; (output-stream *standard-out*) | |
139 | ; (comp-env *compilation-environment*)) | |
140 | ||
9da682ca | 141 | |
a98e58ee | 142 | ;;; old file compilation functions: |
171bbab3 | 143 | (defun compile-parenscript-file-to-string (source-file) |
9da682ca RD |
144 | "Compile SOURCE-FILE (a parenscript file) to a javascript string. (in-package ...) forms |
145 | behave as expected and all other forms are evaluated according to the value of | |
146 | EVAL-FORMS-P. If the result of the evaluation is not nil then it's compiled with | |
147 | js:js* and written to the output." | |
171bbab3 RD |
148 | (compile-script-file source-file :output-stream nil)) |
149 | ||
9da682ca RD |
150 | (defun compile-parenscript-file (source-file &rest args &key destination-file &allow-other-keys) |
151 | "Compile SOURCE-FILE (a parenscript file) to a javascript file with | |
152 | compile-parenscript-file-to-string. When DESTINATION-FILE is omitted, | |
153 | then it will be named the same as SOURCE-FILE but with js extension." | |
154 | (setf args (copy-list args)) | |
155 | (remf args :destination-file) | |
156 | (unless destination-file | |
157 | (setf destination-file (merge-pathnames (make-pathname :type "js") | |
158 | source-file))) | |
159 | (with-open-file (output destination-file :if-exists :supersede :direction :output) | |
160 | (write-string (apply #'compile-parenscript-file-to-string source-file args) output))) | |
a9fce0a7 RD |
161 | |
162 | ;;; SEXPs -> Javascript string functionality | |
163 | (defmacro script (&body body) | |
164 | "A macro that returns a Javascript string of the supplied Parenscript forms." | |
165 | `(script* '(progn ,@body))) | |
166 | ||
167 | (defmacro ps (&body body) | |
168 | `(script ,@body)) | |
169 | ||
4b5d1808 | 170 | (defun script* (&rest body) |
a9fce0a7 | 171 | "Return the javascript string representing BODY. |
a9fce0a7 | 172 | Body is evaluated." |
4b5d1808 | 173 | (compile-script `(progn ,@body))) |
a9fce0a7 RD |
174 | |
175 | (defmacro ps* (&body body) | |
4b5d1808 | 176 | `(script* ,@body)) |