1 (in-package :parenscript
)
3 (defmacro with-new-compilation-environment
((var) &body body
)
4 `(let* ((,var
(make-basic-compilation-environment))
5 (*compilation-environment
* ,var
))
9 (defun translate-ast (compiled-expr
11 (comp-env *compilation-environment
*)
12 (output-stream *standard-output
*)
13 (output-spec :javascript
)
15 "Translates a compiled Parenscript program (compiled with COMPILE-PAREN-FORM)
16 to a Javascript string. Outputs to the stream OUTPUT-STREAM in the language given
17 by OUTPUT-SPEC, pretty printing if PRETTY-PRINT is non-null.
19 OUTPUT-SPEC must be :javascript at the moment."
20 (declare (ignore pretty-print
) (ignore comp-env
))
21 (when (not (eql :javascript output-spec
))
22 (error "Unsupported output-spec for translation: ~A" output-spec
))
23 (when (eql :javascript output-spec
)
24 (write-string (string-join
25 (js-to-statement-strings compiled-expr
0)
29 (defun compile-script (script-form
31 (output-spec :javascript
)
35 (comp-env (make-basic-compilation-environment)))
36 "Compiles the Parenscript form SCRIPT-FORM into the language specified by OUTPUT-SPEC.
37 Non-null PRETTY-PRINT values result in a pretty-printed output code. If OUTPUT-STREAM
38 is NIL, then the result is a string; otherwise code is output to the OUTPUT-STREAM stream.
39 COMP-ENV is the compilation environment in which to compile the form.
41 This is the main function used by Parenscript users to compile their code to Javascript (and
42 potentially other languages)."
43 (macrolet ((with-output-stream ((var) &body body
)
44 `(if (null output-stream
)
45 (with-output-to-string (,var
)
47 (let ((,var output-stream
))
49 (with-output-stream (stream)
50 (let* ((*compilation-environment
* comp-env
)
53 (compile-parenscript-form
55 (compile-parenscript-form comp-env script-form
:toplevel-p t
))
56 (compile-parenscript-form comp-env script-form
:toplevel-p nil
))))
59 ; (compile-script-form script-form :comp-env comp-env)
62 :output-spec output-spec
63 :pretty-print pretty-print
)))))
65 (defun compile-script-file (source-file
67 (output-spec :javascript
)
68 (comp-env (or *compilation-environment
*
69 (make-basic-compilation-environment)))
71 (output-stream *standard-output
*))
72 "Compiles the given Parenscript source file and outputs the results
73 to the given output stream."
74 (setf (comp-env-compiling-toplevel-p comp-env
) t
)
75 (error "NOT IMPLEMENTED."))
80 ;(defun compile-script-file (script-src-file
82 ; (output-spec :javascript)
83 ; (output-stream *standard-out*)
84 ; (comp-env *compilation-environment*))
87 ;;; SEXPs -> Javascript string functionality
88 (defmacro script
(&body body
)
89 "A macro that returns a Javascript string of the supplied Parenscript forms."
90 `(js* '(progn ,@body
)))
92 (defmacro script
* (&body body
)
93 "Return the javascript string representing BODY.
96 `(compile-script (progn ,@body
)))
99 (defmacro js
(&body body
)
100 "A macro that returns a javascript string of the supplied Parenscript forms."
103 (defmacro js
* (&body body
)
106 (defun js-to-string (expr)
107 "Given an AST node, compiles it to a Javascript string."
109 (js-to-statement-strings (compile-script-form expr
) 0)
112 (defun js-to-line (expr)
113 "Given an AST node, compiles it to a Javascript string."
115 (js-to-statement-strings (compile-script-form expr
) 0) " "))
118 ;;; old file compilation functions:
119 (defun compile-parenscript-file-to-string (source-file
124 "Compile SOURCE-FILE (a parenscript file) to a javascript string. (in-package ...) forms
125 behave as expected and all other forms are evaluated according to the value of
126 EVAL-FORMS-P. If the result of the evaluation is not nil then it's compiled with
127 js:js* and written to the output."
128 (with-output-to-string (output)
129 (with-open-file (input source-file
:direction
:input
)
132 (log-message (&rest args
)
134 (apply #'format log-stream args
))))
135 (let ((*package
* *package
*))
136 (loop for form
= (read-form)
138 (if (or (not (listp form
))
139 (not (eq (car form
) 'cl
:in-package
)))
141 (log-message "Processing form:~%~S~%" form
)
149 (setf form
(eval form
)))
150 (log-message "After evaluation:~%~S~%" form
)
152 (let ((compiled (js:js
* form
)))
153 (log-message "Compiled into:~%~A~%~%" compiled
)
154 (write-string compiled output
)
157 (when (and (listp form
)
158 (eq (car form
) 'cl
:in-package
))
159 (log-message "Setting package to: ~S~%" (cadr form
))
160 (setf *package
* (find-package (cadr form
)))))))))))
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
164 compile-parenscript-file-to-string. When DESTINATION-FILE is omitted,
165 then 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")
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
)))