~ chicken-core (chicken-5) e84482088fe82289866967ca66ce4c0aaf48ff67


commit e84482088fe82289866967ca66ce4c0aaf48ff67
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Wed Jun 16 08:35:33 2021 +0200
Commit:     megane <meganeka@gmail.com>
CommitDate: Thu Jun 17 15:19:21 2021 +0300

    Refactor replacing of rest args to make it reusable
    
    This moves the replacing of rest args with corresponding list ops into
    a procedure in support.scm
    
    Signed-off-by: megane <meganeka@gmail.com>
    
    Note: This also removes an unused (test here 'customizable) test:
    
    < sjamaan> Oh, right.  That branch was totally bogus
    < sjamaan> Because customizable refers to the call site, not the procedure

diff --git a/core.scm b/core.scm
index c484071c..630bfd04 100644
--- a/core.scm
+++ b/core.scm
@@ -2649,37 +2649,12 @@
 	     ;; This can be improved, as it can actually introduce
 	     ;; many more cdr calls than necessary.
 	     (cond ((eq? class '##core#rest-cdr)
-		    (let lp ((cdr-calls (add1 (second params)))
-			     (var rest-var))
-		      (if (zero? cdr-calls)
-			  (transform var here closure)
-			  (lp (sub1 cdr-calls)
-			      (make-node '##core#inline (list "C_i_cdr") (list var))))))
-
-		   ;; If customizable, the list is consed up at the
-		   ;; call site and there is no argvector.  So convert
-		   ;; back to list-ref/list-tail calls.
-		   ;;
-		   ;; Alternatively, if n isn't val, this node was
-		   ;; processed and the variable got replaced by a
-		   ;; closure access.
-		   ((or (test here 'customizable)
-			(not (eq? val n)))
-		    (case class
-		      ((##core#rest-car)
-		       (transform (make-node '##core#inline
-					     (list "C_i_list_ref")
-					     (list rest-var (qnode (second params)))) here closure))
-		      ((##core#rest-null?)
-		       (transform (make-node '##core#inline
-					     (list "C_i_greater_or_equalp")
-					     (list (qnode (second params))
-						   (make-node '##core#inline (list "C_i_length") (list rest-var)))) here closure))
-		      ((##core#rest-length)
-		       (transform (make-node '##core#inline
-					     (list "C_i_length")
-					     (list rest-var (qnode (second params)))) here closure))
-		      (else (bomb "Unknown rest op node class while converting to closure. This shouldn't happen!" class))))
+		    (transform (replace-rest-op-with-list-ops class rest-var params) here closure))
+
+		   ;; If n isn't val, this node was processed and the
+		   ;; variable got replaced by a closure access.
+		   ((not (eq? val n))
+		    (transform (replace-rest-op-with-list-ops class rest-var params) here closure))
 
 		   (else val)) ) )
 
diff --git a/support.scm b/support.scm
index b93fb8ef..b56b7d00 100644
--- a/support.scm
+++ b/support.scm
@@ -34,7 +34,7 @@
      debugging-chicken with-debugging-output quit-compiling
      emit-syntax-trace-info check-signature build-lambda-list
      c-ify-string valid-c-identifier? read-expressions
-     bytes->words words->bytes
+     bytes->words words->bytes replace-rest-op-with-list-ops
      check-and-open-input-file close-checked-input-file fold-inner
      constant? collapsable-literal? immediate? basic-literal?
      canonicalize-begin-body string->expr llist-length llist-match?
@@ -779,6 +779,30 @@
 
   (walk node)  )
 
+(define (replace-rest-op-with-list-ops class rest-var-node params)
+  (case class
+    ((##core#rest-car)
+     (make-node '##core#inline
+		(list "C_i_list_ref")
+		(list rest-var-node (qnode (second params)))))
+    ((##core#rest-cdr)
+     (let lp ((cdr-calls (add1 (second params)))
+	      (var rest-var-node))
+       (if (zero? cdr-calls)
+	   var
+	   (lp (sub1 cdr-calls)
+	       (make-node '##core#inline (list "C_i_cdr") (list var))))))
+    ((##core#rest-null?)
+     (make-node '##core#inline
+		(list "C_i_greater_or_equalp")
+		(list (qnode (second params))
+		      (make-node '##core#inline (list "C_i_length") (list rest-var-node)))))
+    ((##core#rest-length)
+     (make-node '##core#inline
+		(list "C_i_length")
+		(list rest-var-node (qnode (second params)))))
+    (else (bomb "Unknown rest op node class while undoing rest op for explicitly consed rest arg. This shouldn't happen!" class))))
+
 ;; Maybe move to scrutinizer.  It's generic enough to keep it here though
 (define (tree-copy t)
   (let rec ([t t])
Trap