X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler.lisp;h=66a734c231ecba4ebbb4639ecd163b8ad90b8273;hb=dc8d38273bc1d2276e20ca1f18114a78ca4b5639;hp=c14584f866d1732e3dae0148411ee3ddbd0aae11;hpb=1ce47de561f80debf6ffd8efeac4eaf962de65f7;p=jscl.git diff --git a/src/compiler.lisp b/src/compiler.lisp index c14584f..66a734c 100644 --- a/src/compiler.lisp +++ b/src/compiler.lisp @@ -368,8 +368,11 @@ (mapconcat #'parse-keyword keyword-arguments)))) ;; Check for unknown keywords (when keyword-arguments - (code "for (i=" (+ n-required-arguments n-optional-arguments) - "; i "foo's" -;;; "foo" => '"foo"' -;;; which avoids having to escape quotes where possible -(defun js-escape-string (string) - (let ((index 0) - (size (length string)) - (seen-single-quote nil) - (seen-double-quote nil)) - (flet ((%js-escape-string (string escape-single-quote-p) - (let ((output "") - (index 0)) - (while (< index size) - (let ((ch (char string index))) - (when (char= ch #\\) - (setq output (concat output "\\"))) - (when (and escape-single-quote-p (char= ch #\')) - (setq output (concat output "\\"))) - (when (char= ch #\newline) - (setq output (concat output "\\")) - (setq ch #\n)) - (setq output (concat output (string ch)))) - (incf index)) - output))) - ;; First, scan the string for single/double quotes - (while (< index size) - (let ((ch (char string index))) - (when (char= ch #\') - (setq seen-single-quote t)) - (when (char= ch #\") - (setq seen-double-quote t))) - (incf index)) - ;; Then pick the appropriate way to escape the quotes - (cond - ((not seen-single-quote) - (concat "'" (%js-escape-string string nil) "'")) - ((not seen-double-quote) - (concat "\"" (%js-escape-string string nil) "\"")) - (t (concat "'" (%js-escape-string string t) "'")))))) - -(defun lisp-escape-string (string) - (let ((output "") - (index 0) - (size (length string))) - (while (< index size) - (let ((ch (char string index))) - (when (or (char= ch #\") (char= ch #\\)) - (setq output (concat output "\\"))) - (when (or (char= ch #\newline)) - (setq output (concat output "\\")) - (setq ch #\n)) - (setq output (concat output (string ch)))) - (incf index)) - (concat "\"" output "\""))) - ;;; BOOTSTRAP MAGIC: We record the macro definitions as lists during ;;; the bootstrap. Once everything is compiled, we want to dump the ;;; whole global environment to the output file to reproduce it in the @@ -727,6 +670,19 @@ ",") ")"))) +(define-compilation macrolet (definitions &rest body) + (let ((*environment* (copy-lexenv *environment*))) + (dolist (def definitions) + (destructuring-bind (name lambda-list &body body) def + (let ((binding (make-binding :name name :type 'macro :value + (let ((g!form (gensym))) + `(lambda (,g!form) + (destructuring-bind ,lambda-list ,g!form + ,@body)))))) + (push-to-lexenv binding *environment* 'function)))) + (ls-compile `(progn ,@body) *multiple-value-p*))) + + (defun special-variable-p (x) (and (claimp x 'variable 'special) t)) @@ -1293,7 +1249,7 @@ (define-builtin functionp (x) (js!bool (code "(typeof " x " == 'function')"))) -(define-builtin write-string (x) +(define-builtin %write-string (x) (code "lisp.write(" x ")")) @@ -1361,8 +1317,8 @@ (js!selfcall "var tmp = (" (ls-compile object) ")[xstring(" (ls-compile key) ")];" *newline* (mapconcat (lambda (key) - (code "if (tmp === undefined) return " (ls-compile nil) ";" *newline*) - (code "tmp = tmp[xstring(" (ls-compile key) ")];" *newline*)) + (code "if (tmp === undefined) return " (ls-compile nil) ";" *newline* + "tmp = tmp[xstring(" (ls-compile key) ")];" *newline*)) keys) "return tmp === undefined? " (ls-compile nil) " : tmp;" *newline*)) @@ -1371,8 +1327,8 @@ (js!selfcall "var obj = " (ls-compile object) ";" *newline* (mapconcat (lambda (key) - "obj = obj[xstring(" (ls-compile key) ")];" - "if (obj === undefined) throw 'Impossible to set Javascript property.';" *newline*) + (code "obj = obj[xstring(" (ls-compile key) ")];" + "if (obj === undefined) throw 'Impossible to set Javascript property.';" *newline*)) (butlast keys)) "var tmp = obj[xstring(" (ls-compile (car (last keys))) ")] = " (ls-compile value) ";" *newline* "return tmp === undefined? " (ls-compile nil) " : tmp;" *newline*)))