X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fcompiler.lisp;h=644ac6a18825815b51d469d95aefe7bb82fab701;hb=3517907ed86d25003e1f8ae220ef354296d22416;hp=73223aa47cf89ace0f1145f085ad20adab2bcc08;hpb=dea14bb78b0fc90032373212912a16ed1f6a4a29;p=jscl.git diff --git a/src/compiler/compiler.lisp b/src/compiler/compiler.lisp index 73223aa..644ac6a 100644 --- a/src/compiler/compiler.lisp +++ b/src/compiler/compiler.lisp @@ -42,6 +42,12 @@ ;;; function call. (defvar *multiple-value-p* nil) +;;; It is bound dinamically to the number of nested calls to +;;; `convert'. Therefore, a form is being compiled as toplevel if it +;;; is zero. +(defvar *convert-level* -1) + + ;;; Environment (def!struct binding @@ -510,7 +516,7 @@ (push (cons sexp jsvar) *literal-table*) (toplevel-compilation `(var (,jsvar ,dumped))) (when (keywordp sexp) - (toplevel-compilation `(= ,(get jsvar "value") ,jsvar))) + (toplevel-compilation `(= (get ,jsvar "value") ,jsvar))) jsvar))))))) @@ -578,13 +584,28 @@ ,(convert-block body t)))) +;;; Was the compiler invoked from !compile-file? (defvar *compiling-file* nil) -(define-compilation eval-when-compile (&rest body) - (if *compiling-file* - (progn - (eval (cons 'progn body)) - (convert 0)) - (convert `(progn ,@body)))) + +;;; NOTE: It is probably wrong in many cases but we will not use this +;;; heavily. Please, do not rely on wrong cases of this +;;; implementation. +(define-compilation eval-when (situations &rest body) + ;; TODO: Error checking + (cond + ;; Toplevel form compiled by !compile-file. + ((and *compiling-file* (zerop *convert-level*)) + ;; If the situation `compile-toplevel' is given. The form is + ;; evaluated at compilation-time. + (when (find :compile-toplevel situations) + (eval (cons 'progn body))) + ;; `load-toplevel' is given, then just compile the subforms as usual. + (when (find :load-toplevel situations) + (convert-toplevel `(progn ,@body) *multiple-value-p*))) + ((find :execute situations) + (convert `(progn ,@body) *multiple-value-p*)) + (t + (convert nil)))) (defmacro define-transformation (name args form) `(define-compilation ,name ,args @@ -1220,7 +1241,7 @@ ,@(mapcar (lambda (key) `(progn (= obj (property obj (call |xstring| ,(convert key)))) - (if (=== object undefined) + (if (=== obj undefined) (throw "Impossible to set object property.")))) (butlast keys)) (var (tmp @@ -1361,7 +1382,8 @@ (when expandedp (return-from convert (convert sexp multiple-value-p))) ;; The expression has been macroexpanded. Now compile it! - (let ((*multiple-value-p* multiple-value-p)) + (let ((*multiple-value-p* multiple-value-p) + (*convert-level* (1+ *convert-level*))) (cond ((symbolp sexp) (let ((b (lookup-in-lexenv sexp *environment* 'variable))) @@ -1402,7 +1424,13 @@ (subseq string 0 n))) (defun convert-toplevel (sexp &optional multiple-value-p) - (let ((*toplevel-compilations* nil)) + ;; Macroexpand sexp as much as possible + (multiple-value-bind (sexp expandedp) (!macroexpand-1 sexp) + (when expandedp + (return-from convert-toplevel (convert-toplevel sexp multiple-value-p)))) + ;; Process as toplevel + (let ((*convert-level* -1) + (*toplevel-compilations* nil)) (cond ;; Non-empty toplevel progn ((and (consp sexp)