Moved package-related code to namespace.lisp, added back *enable-package-system*.
[clinton/parenscript.git] / src / compilation-interface.lisp
CommitLineData
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)
15to a Javascript string. Outputs to the stream OUTPUT-STREAM in the language given
16by OUTPUT-SPEC, pretty printing if PRETTY-PRINT is non-null.
17
18OUTPUT-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
32one."
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.
45Non-null PRETTY-PRINT values result in a pretty-printed output code. If OUTPUT-STREAM
46is NIL, then the result is a string; otherwise code is output to the OUTPUT-STREAM stream.
47COMP-ENV is the compilation environment in which to compile the form.
48
49This is the main function used by Parenscript users to compile their code to Javascript (and
50potentially 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))))
46f794a4
RD
57 ;; we might want to bind this rather than set it
58 (setf (comp-env-compiling-toplevel-p comp-env) toplevel-p)
9da682ca 59 (with-output-stream (stream)
a98e58ee 60 (let* ((*compilation-environment* comp-env)
b506b81b
VS
61 (compiled (let ((first-result (compile-parenscript-form comp-env script-form)))
62 (if (not toplevel-p)
63 first-result
64 (progn
65 (setf (comp-env-compiling-toplevel-p comp-env) nil)
66 (compile-parenscript-form comp-env first-result))))))
a98e58ee
RD
67 (translate-ast
68 compiled
69; (compile-script-form script-form :comp-env comp-env)
70 :comp-env comp-env
71 :output-stream stream
72 :output-spec output-spec
73 :pretty-print pretty-print)))))
74
75(defun compile-script-file (source-file
76 &key
77 (output-spec :javascript)
a9fce0a7 78 (comp-env (non-nil-comp-env))
a98e58ee
RD
79 (pretty-print t)
80 (output-stream *standard-output*))
81 "Compiles the given Parenscript source file and outputs the results
82to the given output stream."
83 (setf (comp-env-compiling-toplevel-p comp-env) t)
171bbab3
RD
84 (with-open-file (input source-file :direction :input)
85 (let ((end-read-form '#:unique))
86 (flet ((read-form ()
87 (parenscript.reader:read input nil end-read-form)))
88 (macrolet ((with-output-stream ((var) &body body)
89 `(if (null output-stream)
90 (with-output-to-string (,var)
91 ,@body)
92 (let ((,var output-stream))
93 ,@body))))
94 (let* ((*compilation-environment* comp-env)
95 (compiled
96 (do ((form (read-form) (read-form))
97 (compiled-forms nil))
98 ((eql form end-read-form)
bbea4c83
RD
99 (progn
100 (setf (comp-env-compiling-toplevel-p comp-env) nil)
101 (compile-parenscript-form
102 comp-env
103 `(progn ,@(nreverse compiled-forms)))))
171bbab3 104 (let ((tl-compiled-form
bbea4c83 105 (compile-parenscript-form comp-env form)))
171bbab3
RD
106 (push tl-compiled-form compiled-forms)))))
107 (with-output-stream (output)
108 (translate-ast
109 compiled
110 :comp-env comp-env
111 :output-stream output
112 :output-spec output-spec
113 :pretty-print pretty-print))))))))
a9fce0a7 114
46f794a4
RD
115;(defun compile-script-asdf-component (component
116; &key
117; (output-spec :javascript)
118; (pretty-print t)
119; (output-to-stream t)
120; (output-stream *standard-output*)
121; output-to-files ;; currently ignored
122; (comp-env (non-nil-comp-env)))
123; "Compiles any ASDF:COMPONENT and its dependencies "
124
a9fce0a7 125(defun compile-script-system (system
a9fce0a7
RD
126 &key
127 (output-spec :javascript)
128 (pretty-print t)
129 (output-to-stream t)
130 (output-stream *standard-output*)
131 output-to-files ;; currently ignored
132 (comp-env (non-nil-comp-env)))
133 "Compiles a collection of parenscripts as described by an ASDF system into files or
134a specified output stream."
135 (asdf:operate 'asdf::parenscript-compile-op system
136 :output-spec output-spec
137 :pretty-print pretty-print
138; :output-to-stream t
139 :output-stream output-stream
140 :comp-env comp-env
141 :force-p t
142 ))
143
144
145;(defun compile-script-system-component (system-designator
146
a98e58ee
RD
147;(defun compile-script-file (script-src-file
148; &key
149; (output-spec :javascript)
150; (output-stream *standard-out*)
151; (comp-env *compilation-environment*))
152
9da682ca 153
a98e58ee 154;;; old file compilation functions:
171bbab3 155(defun compile-parenscript-file-to-string (source-file)
9da682ca
RD
156 "Compile SOURCE-FILE (a parenscript file) to a javascript string. (in-package ...) forms
157behave as expected and all other forms are evaluated according to the value of
158EVAL-FORMS-P. If the result of the evaluation is not nil then it's compiled with
159js:js* and written to the output."
171bbab3
RD
160 (compile-script-file source-file :output-stream nil))
161
9da682ca
RD
162(defun compile-parenscript-file (source-file &rest args &key destination-file &allow-other-keys)
163 "Compile SOURCE-FILE (a parenscript file) to a javascript file with
164compile-parenscript-file-to-string. When DESTINATION-FILE is omitted,
165then it will be named the same as SOURCE-FILE but with js extension."
166 (setf args (copy-list args))
167 (remf args :destination-file)
168 (unless destination-file
169 (setf destination-file (merge-pathnames (make-pathname :type "js")
170 source-file)))
171 (with-open-file (output destination-file :if-exists :supersede :direction :output)
172 (write-string (apply #'compile-parenscript-file-to-string source-file args) output)))
a9fce0a7 173
b5be3f57
VS
174(defun ps-to-string (expr)
175 "Given an AST node, compiles it to a Javascript string."
176 (string-join
177 (ps-js::js-to-statement-strings (compile-script-form expr) 0)
178 (string #\Newline)))
179
a9fce0a7
RD
180;;; SEXPs -> Javascript string functionality
181(defmacro script (&body body)
182 "A macro that returns a Javascript string of the supplied Parenscript forms."
183 `(script* '(progn ,@body)))
184
4b5d1808 185(defun script* (&rest body)
a9fce0a7 186 "Return the javascript string representing BODY.
a9fce0a7 187Body is evaluated."
4b5d1808 188 (compile-script `(progn ,@body)))
a9fce0a7 189
b5be3f57
VS
190;;; Handy synonyms
191(defmacro ps (&body body)
192 `(script ,@body))
193
a9fce0a7 194(defmacro ps* (&body body)
4b5d1808 195 `(script* ,@body))
b5be3f57
VS
196
197(defmacro js (&body body)
198 `(script ,@body))
199
200(defmacro js* (&body body)
201 `(script* ,@body))