eval-when
authorRobin Templeton <robin@terpri.org>
Tue, 5 Aug 2014 03:16:09 +0000 (23:16 -0400)
committerRobin Templeton <robin@terpri.org>
Fri, 13 Feb 2015 00:18:54 +0000 (19:18 -0500)
module/language/elisp/compile-tree-il.scm

index 87ee486..66247a4 100644 (file)
   (list->seq loc
              (if (null? args)
                  (list (nil-value loc))
-                 (map compile-expr args))))
+                 (map compile-expr-1 args))))
 
 (defspecial eval-when-compile (loc args)
   (make-const loc (compile `(progn ,@args) #:from 'elisp #:to 'value)))
 
+(define toplevel? (make-fluid))
+
+(define compile-time-too? (make-fluid))
+
+(defspecial eval-when (loc args)
+  (pmatch args
+    ((,situations . ,forms)
+     (let ((compile? (memq ':compile-toplevel situations))
+           (load? (memq ':load-toplevel situations))
+           (execute? (memq ':execute situations)))
+       (cond
+        ((not (fluid-ref toplevel?))
+         (if execute?
+             (compile-expr `(progn ,@forms))
+             (make-const loc #nil)))
+        (load?
+         (with-fluids ((compile-time-too?
+                        (cond (compile? #t)
+                              (execute? (fluid-ref compile-time-too?))
+                              (else #f))))
+           (when (fluid-ref compile-time-too?)
+             (eval-elisp `(progn ,@forms)))
+           (compile-expr-1 `(progn ,@forms))))
+        ((or compile? (and execute? (fluid-ref compile-time-too?)))
+         (eval-elisp `(progn ,@forms))
+         (make-const loc #nil))
+        (else
+         (make-const loc #nil)))))))
+
 (defspecial if (loc args)
   (pmatch args
     ((,cond ,then . ,else)
 
 ;;; Compile a single expression to TreeIL.
 
-(define (compile-expr expr)
+(define (compile-expr-1 expr)
   (let ((loc (location expr)))
     (cond
      ((symbol? expr)
       (compile-pair loc expr))
      (else (make-const loc expr)))))
 
+(define (compile-expr expr)
+  (if (fluid-ref toplevel?)
+      (with-fluids ((toplevel? #f))
+        (compile-expr-1 expr))
+      (compile-expr-1 expr)))
+
 (define (compile-tree-il expr env opts)
   (values
-   (with-fluids ((bindings-data (make-bindings)))
-     (compile-expr expr))
+   (with-fluids ((bindings-data (make-bindings))
+                 (toplevel? #t)
+                 (compile-time-too? #f))
+     (compile-expr-1 expr))
    env
    env))