Refactor promises again, to support delay-force.
authorChris Hanson <org/chris-hanson/cph>
Tue, 29 May 2018 06:53:16 +0000 (23:53 -0700)
committerChris Hanson <org/chris-hanson/cph>
Tue, 29 May 2018 06:53:16 +0000 (23:53 -0700)
This no longer uses scode DELAY expressions, which can be deleted after 9.3 is
released.  It does continue to use DELAYED objects for type convenience.

src/runtime/boot.scm
src/runtime/framex.scm
src/runtime/host-adapter.scm
src/runtime/microcode-data.scm
src/runtime/mit-macros.scm
src/runtime/mit-syntax.scm
src/runtime/runtime.pkg
src/runtime/syntax-output.scm

index ad39b52600e9d93df9ecf693108eeb112c6dff28..e614ea6ecff433ecdefec7e19aa4d24df93dfd3d 100644 (file)
@@ -431,6 +431,59 @@ USA.
          (write-string "object satisfying " port)
          (write predicate port)))))
 \f
+;;;; Promises
+
+(define (promise? object)
+  (and (cell? object)
+       (object-type? (ucode-type delayed) (cell-contents object))))
+
+(define (make-promise object)
+  (if (promise? object)
+      object
+      (make-cell (system-pair-cons (ucode-type delayed) #t object))))
+
+(define (make-unforced-promise thunk)
+  ;(guarantee thunk? thunk 'make-unforced-promise)
+  (make-cell (system-pair-cons (ucode-type delayed) #f thunk)))
+
+(define (%promise-parts promise)
+  (without-interrupts
+   (lambda ()
+     (let ((p (cell-contents promise)))
+       (values (system-pair-car p)
+              (system-pair-cdr p))))))
+
+(define (promise-forced? promise)
+  (guarantee promise? promise 'promise-forced?)
+  (system-pair-car (cell-contents promise)))
+
+(define (promise-value promise)
+  (guarantee promise? promise 'promise-value)
+  (receive (forced? value) (%promise-parts promise)
+    (if (not forced?)
+       (error "Promise not yet forced:" promise))
+    value))
+
+(define (force promise)
+  (guarantee promise? promise 'force)
+  (%force promise))
+
+(define (%force promise)
+  (receive (forced? value) (%promise-parts promise)
+    (if forced?
+       value
+       (let ((promise* (value)))
+         (guarantee promise? promise* 'force)
+         (without-interrupts
+          (lambda ()
+            (let ((p (cell-contents promise)))
+              (if (not (system-pair-car p))
+                  (let ((p* (cell-contents promise*)))
+                    (system-pair-set-car! p (system-pair-car p*))
+                    (system-pair-set-cdr! p (system-pair-cdr p*))
+                    (set-cell-contents! promise* p))))))
+         (%force promise)))))
+\f
 ;;;; Miscellany
 
 (define (object-constant? object)
index e493faeb1f1dd1a88a62f1731d33f7c8a9f26fb8..33d745a331fa077ad17fb5ba402d307861f8b8a7 100644 (file)
@@ -133,11 +133,7 @@ USA.
     (values (make-scode-combination (ucode-primitive force 1)
                                    (list (make-evaluated-object promise)))
            undefined-environment
-           (let ((expr (promise-expression promise)))
-             (case expr
-               ((|#[(runtime microcode-data)forced]|) undefined-expression)
-               ((|#[(runtime microcode-data)compiled]|) unknown-expression)
-               (else (validate-subexpression frame expr)))))))
+           undefined-expression)))
 
 (define ((method/application-frame index) frame)
   (values (make-scode-combination
index dd447c6eac607ddf0213f8754c788d473dd9a7fc..109f84e691e5b7b5ec8d03c37932695ae061a8da 100644 (file)
@@ -89,6 +89,18 @@ USA.
                                   (list (cons 'name name) ...)))))
              env))
 
+    (if (unbound? env 'delay-force)
+       (eval '(begin
+                (define-syntax delay-force
+                  (syntax-rules ()
+                    ((delay-force expression)
+                     (make-unforced-promise (lambda () expression)))))
+                (define-syntax delay
+                  (syntax-rules ()
+                    ((delay expression)
+                     (delay-force (make-promise expression))))))
+             env))
+
     (if (unbound? env 'define-print-method)
        (eval '(define (define-print-method predicate print-method)
                 unspecific)
index bdeb69f86f4ce1918b302cfb59dec7ccd13f18b0..06b5d52d4dcdfcf217c7f8f71f62da86f314be15 100644 (file)
@@ -256,50 +256,4 @@ contains constants derived from the source program.
            (filter-potentially-dangerous (cdr aux-list))
            (cons (car aux-list)
                  (filter-potentially-dangerous (cdr aux-list))))
-       '())))
-
-;;;; Promises
-
-(define-integrable (promise? object)
-  (object-type? (ucode-type delayed) object))
-
-(define (make-promise object)
-  (if (promise? object)
-      object
-      (system-pair-cons (ucode-type delayed) #t object)))
-
-(define-integrable (%promise-forced? promise)
-  (eq? #t (system-pair-car promise)))
-
-(define (promise-forced? promise)
-  (guarantee promise? promise 'promise-forced?)
-  (%promise-forced? promise))
-
-(define (promise-value promise)
-  (guarantee promise? promise 'promise-value)
-  (if (not (%promise-forced? promise))
-      (error "Promise not yet forced:" promise))
-  (system-pair-cdr promise))
-
-(define (promise-expression promise)
-  (without-interrupts
-   (lambda ()
-     (case (system-pair-car promise)
-       ((#t) '|#[(runtime microcode-data)forced]|)
-       ((0) '|#[(runtime microcode-data)compiled]|)
-       (else (system-pair-cdr promise))))))
-
-(define (force promise)
-  (guarantee promise? promise 'force)
-  (without-interrupts
-   (lambda ()
-     (case (system-pair-car promise)
-       ((#t)
-       (system-pair-cdr promise))
-       ((0)                            ;compiled
-       (let ((result ((system-pair-cdr promise))))
-         (system-pair-set-cdr! promise result)
-         (system-pair-set-car! promise #t)
-         result))
-       (else                           ;interpreted
-       ((ucode-primitive force 1) promise))))))
\ No newline at end of file
+       '())))
\ No newline at end of file
index 4ae0f6b592072bc151faf711d8e102a571efc078..74aaf03195955bc7494c4196cfaaf4fe519ee74f 100644 (file)
@@ -396,6 +396,16 @@ USA.
      (if (not condition)
         (begin form ...)))))
 
+(define-syntax $delay-force
+  (syntax-rules ()
+    ((delay-force expression)
+     (make-unforced-promise (lambda () expression)))))
+
+(define-syntax $delay
+  (syntax-rules ()
+    ((delay expression)
+     (delay-force (make-promise expression)))))
+
 (define $guard
   (spar-transformer->runtime
    (delay
index fa030125c86d486891cad4dbf0ca90dc6c6be49d..5403f58c56d056250ba2d2a3cdc3c65ac7ee23e6 100644 (file)
@@ -158,15 +158,6 @@ USA.
        (spar-push spar-arg:ctx)
        (spar* (spar-subform spar-push-classified))
        (spar-match-null)))))
-
-(define $delay
-  (spar-classifier->runtime
-   (delay
-     (spar-call-with-values delay-item
-       (spar-subform)
-       (spar-push spar-arg:ctx)
-       (spar-subform spar-push-deferred-classified)
-       (spar-match-null)))))
 \f
 ;;;; Definitions
 
@@ -454,11 +445,6 @@ USA.
     (lambda ()
       (output/declaration (classify)))))
 
-(define (delay-item ctx classify)
-  (expr-item ctx
-    (lambda ()
-      (output/delay (compile-expr-item (classify))))))
-
 (define (if-item ctx predicate consequent alternative)
   (expr-item ctx
     (lambda ()
index 7925f3654162641745893ec89e524908e1a3793a..bdc41fd0b528d24f3c9373678f0b5c2429f8cc42 100644 (file)
@@ -163,6 +163,7 @@ USA.
          define-print-method
          error:not-a
          error:not-a-list-of
+         force                         ;R7RS
          gc-space-status
          guarantee
          guarantee-list-of
@@ -179,10 +180,15 @@ USA.
          interrupt-mask/gc-ok
          interrupt-mask/none
          interrupt-mask/timer-ok
+         make-promise                  ;R7RS
+         make-unforced-promise
          object-constant?
          object-pure?
          predicate->dispatch-tag
          predicate?
+         promise-forced?
+         promise-value
+         promise?                      ;R7RS
          register-predicate!
          set-dispatch-tag<=!
          set-predicate<=!
@@ -806,17 +812,12 @@ USA.
          environment-extension-parent
          environment-extension-procedure
          environment-extension?
-         force                         ;R7RS
          interpreter-return-address?
-         make-promise                  ;R7RS
          make-return-address
          microcode-error
          microcode-return
          microcode-termination
          microcode-type
-         promise-forced?
-         promise-value
-         promise?                      ;R7RS
          return-address/code
          return-address/name
          return-address?
@@ -824,9 +825,7 @@ USA.
          set-environment-extension-parent!
          stack-address->index
          stack-address-offset
-         stack-address?)
-  (export (runtime debugging-info)
-         promise-expression))
+         stack-address?))
 
 (define-package (runtime vector)
   (files "vector")
@@ -4705,7 +4704,6 @@ USA.
          output/constant
          output/declaration
          output/definition
-         output/delay
          output/disjunction
          output/lambda
          output/let
@@ -4741,7 +4739,6 @@ USA.
          (begin $begin)                ;R7RS
          (declare $declare)
          (define-syntax $define-syntax) ;R7RS
-         (delay $delay)                ;R7RS
          (else $else)                  ;R7RS
          (er-macro-transformer $er-macro-transformer)
          (if $if)                      ;R7RS
@@ -4786,6 +4783,8 @@ USA.
          (define-integrable $define-integrable)
          (define-record-type $define-record-type)
          (define-values $define-values) ;R7RS
+         (delay $delay)                ;R7RS
+         (delay-force $delay-force)    ;R7RS
          (do $do)                      ;R7RS
          (fluid-let $fluid-let)
          (guard $guard)                ;R7RS
index f3e4316b9344bbedf20acf52bd4d1eb478a1ea47..985a0c70b222275f2a3d535401a6e63668ecbc1b 100644 (file)
@@ -82,9 +82,6 @@ USA.
   (receive (required optional rest) (parse-mit-lambda-list lambda-list)
     (make-lambda* name required optional rest body)))
 
-(define (output/delay expression)
-  (make-scode-delay expression))
-
 (define (output/unassigned-test name)
   (make-scode-unassigned? name))