guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 43/99: Handle multiple conts in a function body


From: Christopher Allan Webber
Subject: [Guile-commits] 43/99: Handle multiple conts in a function body
Date: Sun, 10 Oct 2021 21:50:55 -0400 (EDT)

cwebber pushed a commit to branch compile-to-js-merge
in repository guile.

commit 8777c20e941d3a927a20c62e42b31f0fbd3a7571
Author: Ian Price <ianprice90@googlemail.com>
AuthorDate: Thu Jun 15 20:21:47 2017 +0100

    Handle multiple conts in a function body
    
    * module/language/cps/compile-js.scm (compile-clause, compile-clauses):
      Extract all conts in the function body, and bind in clauses.
      (extract-and-compile-conts): New Procedure
---
 module/language/cps/compile-js.scm | 53 ++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/module/language/cps/compile-js.scm 
b/module/language/cps/compile-js.scm
index 03e9e7d..e750935 100644
--- a/module/language/cps/compile-js.scm
+++ b/module/language/cps/compile-js.scm
@@ -35,17 +35,45 @@
       (compile-clauses cps clause self)))))
 
 
+(define (extract-and-compile-conts cps)
+  (define (step id body accum)
+    (match body
+      ;; The term in a $kargs is always a $continue
+      (($ $kargs names syms ($ $continue k src exp))
+       (acons (make-kid id)
+              (make-continuation (map make-id syms) (compile-exp exp k))
+              accum))
+      (($ $kreceive ($ $arity req _ (? symbol? rest) _ _) k2)
+       (let ((ids (map make-id (append req (list rest)))))
+         (acons (make-kid id)
+                (make-continuation ids (make-continue (make-kid k2) ids))
+                accum)))
+      (($ $kreceive ($ $arity req _ #f _ _) k2)
+       (let ((ids (map make-id req)))
+         (acons (make-kid id)
+                (make-continuation ids (make-continue (make-kid k2) ids))
+                accum)))
+      (else accum)))
+  (intmap-fold step cps '()))
+
+
 (define (compile-clauses cps clause self)
-  (match (intmap-ref cps clause)
-    (($ $kclause arity body #f)
-     `((,(make-kid clause)
-        ,(arity->params arity self)
-        ,(compile-clause cps arity body self))))
-    (($ $kclause arity body next)
-     `((,(make-kid clause)
-        ,(arity->params arity self)
-        ,(compile-clause cps arity body self))
-       . ,(compile-clauses cps next self)))))
+  ;; FIXME: This duplicates all the conts in each clause, and requires
+  ;; the inliner to remove them. A better solution is to change the
+  ;; function type to contain a separate map of conts, but this requires
+  ;; more code changes, and is should constitute a separate commit.
+  (define function-conts (extract-and-compile-conts cps))
+  (let loop ((clause clause))
+   (match (intmap-ref cps clause)
+     (($ $kclause arity body #f)
+      `((,(make-kid clause)
+         ,(arity->params arity self)
+         ,(compile-clause cps arity body self function-conts))))
+     (($ $kclause arity body next)
+      `((,(make-kid clause)
+         ,(arity->params arity self)
+         ,(compile-clause cps arity body self function-conts))
+        . ,(loop next))))))
 
 
 (define (arity->params arity self)
@@ -63,15 +91,14 @@
                   allow-other-keys?))))
 
 
-(define (compile-clause cps arity body self)
+(define (compile-clause cps arity body self bindings)
   (match arity
     (($ $arity req opt rest ((_ _ kw-syms) ...) _)
      (let ((ids (map make-id
                      (append req opt kw-syms (if rest (list rest) '())))))
        (make-continuation
         (cons (make-id self) ids)
-        (make-local `((,(make-kid body) . ,(compile-cont cps body)))
-                    (make-continue (make-kid body) ids)))))))
+        (make-local bindings (make-continue (make-kid body) ids)))))))
 
 
 (define (compile-cont cps cont)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]