1 (in-package :parenscript
)
3 (defmacro with-new-compilation-environment
((var) &body body
)
4 `(let* ((,var
(make-basic-compilation-environment))
5 (*compilation-environment
* ,var
))
8 (defun translate-ast (compiled-expr
10 (comp-env *compilation-environment
*)
11 (output-stream *standard-output
*)
12 (output-spec :javascript
)
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.
18 OUTPUT-SPEC must be :javascript at the moment."
19 (declare (ignore comp-env
))
20 (when (not (eql :javascript output-spec
))
21 (error "Unsupported output-spec for translation: ~A" output-spec
))
22 (when (eql :javascript output-spec
)
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)
30 (defun non-nil-comp-env ()
31 "Returns a sane compilation environment. Either the one currently bound or a new
33 (or *compilation-environment
*
34 (make-basic-compilation-environment)))
37 (defun compile-script (script-form
39 (output-spec :javascript
)
43 (comp-env (non-nil-comp-env)))
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.
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
)
55 (let ((,var output-stream
))
57 (with-output-stream (stream)
58 (let* ((*compilation-environment
* comp-env
)
61 (compile-parenscript-form
63 (compile-parenscript-form comp-env script-form
:toplevel-p t
))
64 (compile-parenscript-form comp-env script-form
:toplevel-p nil
))))
67 ; (compile-script-form script-form :comp-env comp-env)
70 :output-spec output-spec
71 :pretty-print pretty-print
)))))
73 (defun compile-script-file (source-file
75 (output-spec :javascript
)
76 (comp-env (non-nil-comp-env))
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
)
82 (with-open-file (input source-file
:direction
:input
)
83 (let ((end-read-form '#:unique
))
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
)
90 (let ((,var output-stream
))
92 (let* ((*compilation-environment
* comp-env
)
94 (do ((form (read-form) (read-form))
96 ((eql form end-read-form
)
97 (compile-parenscript-form
99 `(progn ,@(nreverse compiled-forms
))
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)
108 :output-stream output
109 :output-spec output-spec
110 :pretty-print pretty-print
))))))))
112 (defun compile-script-system (system
115 (output-spec :javascript
)
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
133 ;(defun compile-script-system-component (system-designator
135 ;(defun compile-script-file (script-src-file
137 ; (output-spec :javascript)
138 ; (output-stream *standard-out*)
139 ; (comp-env *compilation-environment*))
142 ;;; old file compilation functions:
143 (defun compile-parenscript-file-to-string (source-file)
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."
148 (compile-script-file source-file
:output-stream nil
))
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")
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
)))
162 (defun ps-to-string (expr)
163 "Given an AST node, compiles it to a Javascript string."
165 (ps-js::js-to-statement-strings
(compile-script-form expr
) 0)
168 ;;; SEXPs -> Javascript string functionality
169 (defmacro script
(&body body
)
170 "A macro that returns a Javascript string of the supplied Parenscript forms."
171 `(script* '(progn ,@body
)))
173 (defun script* (&rest body
)
174 "Return the javascript string representing BODY.
176 (compile-script `(progn ,@body
)))
179 (defmacro ps
(&body body
)
182 (defmacro ps
* (&body body
)
185 (defmacro js
(&body body
)
188 (defmacro js
* (&body body
)