Allow sequences to contain zero elements.
authorChris Hanson <org/chris-hanson/cph>
Sun, 4 Nov 2018 04:55:19 +0000 (21:55 -0700)
committerChris Hanson <org/chris-hanson/cph>
Sun, 4 Nov 2018 04:55:19 +0000 (21:55 -0700)
src/compiler/fggen/fggen.scm
src/runtime/lambda.scm
src/runtime/library-scode.scm
src/runtime/scan.scm
src/runtime/scode.scm
src/runtime/unsyn.scm
src/runtime/ystep.scm
src/sf/object.scm
src/sf/xform.scm

index fab7c23cb7880aebcfcaad28938cc24fa0511a45..779468d9702b063c439b5c72ce56b10a09b2b4ef 100644 (file)
@@ -503,21 +503,25 @@ USA.
 ;;;; Combinators
 
 (define (generate/sequence block continuation context expression)
-  (if (scode/sequence? expression)
-      ;; This is done in a funny way to enforce processing in sequence order.
-      ;; In this way, compile-by-procedures compiles in a predictable order.
-      (let ((first-action
-            (generate/subproblem/effect
-             block continuation context
-             (car (scode/sequence-actions expression))
-              'SEQUENCE-CONTINUE
-             expression)))
-       ((scfg*ctype->ctype! continuation)
-        first-action
-        (generate/expression
-         block continuation context
-         (scode/make-sequence (cdr (scode/sequence-actions expression))))))
-      (error "Not a sequence" expression)))
+  (if (not (scode/sequence? expression))
+      (error "Not a sequence:" expression))
+  (let ((actions (scode/sequence-actions expression)))
+    (if (pair? actions)
+       (let loop ((actions actions))
+         (let ((action (car actions))
+               (rest (cdr actions)))
+           (if (pair? rest)
+               ;; This is done in a funny way to enforce processing in sequence
+               ;; order.  In this way, compile-by-procedures compiles in a
+               ;; predictable order.
+               (let ((first-action
+                      (generate/subproblem/effect block continuation context
+                                                  action 'sequence-continue
+                                                  expression)))
+                 ((scfg*ctype->ctype! continuation) first-action (loop rest)))
+               (generate/expression block continuation context action))))
+       (continue/rvalue-constant block continuation
+                                 (make-constant unspecific)))))
 
 (define (generate/conditional block continuation context expression)
   (let ((predicate (scode/conditional-predicate expression))
index c42ad2fb792d4c7b00459c088141d5f7e682da43..f4ffd75a0ccea35735741ef086ce108c541c2370 100644 (file)
@@ -444,7 +444,8 @@ USA.
       (let ((actions
             (and (scode-sequence? body)
                  (scode-sequence-actions body))))
-       (if (and actions (scode-block-declaration? (car actions)))
+       (if (and (pair? actions)
+                (scode-block-declaration? (car actions)))
            (receiver name required optional rest auxiliary
                      (scode-block-declaration-text (car actions))
                      (make-scode-sequence (cdr actions)))
index f80cab872ad94fde1aec89d9acfdf449ad8cf5f5..af7ae84a891554fecdd085007bd25828e79db9dd 100644 (file)
@@ -124,7 +124,9 @@ USA.
   (let ((scode (strip-comments scode)))
     (or (scode-library? scode)
        (and (scode-sequence? scode)
-            (every scode-library? (scode-sequence-actions scode))))))
+            (let ((actions (scode-sequence-actions scode)))
+              (and (pair? actions)
+                   (every scode-library? actions)))))))
 (register-predicate! r7rs-scode-file? 'r7rs-scode-file)
 
 (define (r7rs-scode-file-libraries scode)
index 27f2667b330300f44c129578bf2b0091561e7c00..63be3154364394da0ebc521b9d28f6bca3f8237d 100644 (file)
@@ -28,7 +28,7 @@ USA.
 ;;; package: (runtime scode-scan)
 
 (declare (usual-integrations))
-\f
+
 ;;; Scanning of internal definitions is necessary to reduce the number
 ;;; of "real auxiliary" variables in the system.  These bindings are
 ;;; maintained in alists by the microcode, and cannot be compiled as
@@ -41,17 +41,6 @@ USA.
 
 ;;; The Open Block abstraction can be used to store scanned definitions in code,
 ;;; which is extremely useful for code analysis and transformation.
-
-(define-integrable sequence-type
-  (ucode-type sequence))
-
-(define null-sequence
-  '(null-sequence))
-
-(define (cons-sequence action seq)
-  (if (eq? seq null-sequence)
-      action
-      (&typed-pair-cons sequence-type action seq)))
 \f
 ;;;; Scanning
 
@@ -61,7 +50,7 @@ USA.
 ;;; EQUAL?  list.
 
 (define (scan-defines expression receiver)
-  ((scan-loop expression receiver) '() '() null-sequence))
+  ((scan-loop expression receiver) '() '() (make-scode-sequence '())))
 
 (define (scan-loop expression receiver)
   (cond ((scode-open-block? expression)        ;must come before SCODE-SEQUENCE? clause
@@ -74,7 +63,7 @@ USA.
                      body))))
        ((scode-sequence? expression)
         ;; Build the sequence from the tail-end first so that the
-        ;; null-sequence shows up in the tail and is detected by
+        ;; empty sequence shows up in the tail and is detected by
         ;; cons-sequence.
         (let loop
             ((actions (scode-sequence-actions expression))
@@ -102,6 +91,9 @@ USA.
           (receiver names
                     declarations
                     (cons-sequence expression body))))))
+
+(define (cons-sequence action sequence)
+  (make-scode-sequence (cons action (scode-sequence-actions sequence))))
 \f
 (define (unscan-defines names declarations body)
 
@@ -141,7 +133,7 @@ USA.
 
     (if (null? declarations)
        body*
-       (&typed-pair-cons sequence-type
+       (&typed-pair-cons (ucode-type sequence)
                          (make-scode-block-declaration declarations)
                          body*))))
 \f
@@ -162,7 +154,8 @@ USA.
 (define (scode-open-block? object)
   (and (scode-sequence? object)
        (let ((actions (scode-sequence-actions object)))
-        (and (open-block-descriptor? (car actions))
+        (and (pair? actions)
+             (open-block-descriptor? (car actions))
              (let ((names (%open-block-descriptor-names (car actions))))
                (and (fix:> (length (cdr actions)) (length names))
                     (every %open-block-definition-named?
index 037023ae124e43558faee7400cb8238f8f2d3276..63fc9d81fc259413db688494b9e932c28799cd25 100644 (file)
@@ -242,28 +242,39 @@ USA.
 ;;;; Sequence
 
 (define (make-scode-sequence actions)
-  (guarantee non-empty-list? actions 'make-sequence)
-  (let loop ((actions actions))
-    (if (pair? (cdr actions))
-       (system-pair-cons (ucode-type sequence)
-                         (unmap-reference-trap (car actions))
-                         (unmap-reference-trap (loop (cdr actions))))
-       (car actions))))
+  (guarantee list? actions 'make-sequence)
+  (let ((actions (append-map scode-sequence-actions actions)))
+    (if (pair? actions)
+       (let loop ((actions actions))
+         (if (pair? (cdr actions))
+             (system-pair-cons (ucode-type sequence)
+                               (unmap-reference-trap (car actions))
+                               (unmap-reference-trap (loop (cdr actions))))
+             (car actions)))
+       (empty-sequence))))
 
 (define (scode-sequence? object)
   (object-type? (ucode-type sequence) object))
 (register-predicate! scode-sequence? 'scode-sequence)
 
 (define (scode-sequence-actions expression)
-  (if (scode-sequence? expression)
-      (append-map scode-sequence-actions
-                 (list (map-reference-trap
-                        (lambda ()
-                          (system-pair-car expression)))
-                       (map-reference-trap
-                        (lambda ()
-                          (system-pair-cdr expression)))))
-      (list expression)))
+  (cond ((not (scode-sequence? expression)) (list expression))
+       ((sequence-empty? expression) '())
+       (else
+        (append-map scode-sequence-actions
+                    (list (map-reference-trap
+                           (lambda ()
+                             (system-pair-car expression)))
+                          (map-reference-trap
+                           (lambda ()
+                             (system-pair-cdr expression))))))))
+
+(define (empty-sequence)
+  (system-pair-cons (ucode-type sequence) #!unspecific #!unspecific))
+
+(define (sequence-empty? sequence)
+  (and (eq? #!unspecific (system-pair-car sequence))
+       (eq? #!unspecific (system-pair-cdr sequence))))
 
 ;;;; Combination
 
index 1269001a63851aa8a37c0835fc4d88d00c8edc87..66e511f0163308b3b3971e1f4533c0e0cf35e982 100644 (file)
@@ -232,7 +232,8 @@ USA.
 
 (define (unsyntax-sequence-object environment seq)
   (let ((actions (scode-sequence-actions seq)))
-    (if (and (scode-block-declaration? (car actions))
+    (if (and (pair? actions)
+            (scode-block-declaration? (car actions))
             (pair? (cdr actions)))
        `(begin
          (declare ,@(scode-block-declaration-text (car actions)))
@@ -421,7 +422,8 @@ USA.
 (define (unsyntax-lambda-body-sequence environment body)
   (if (scode-sequence? body)
       (let ((actions (scode-sequence-actions body)))
-       (if (and (scode-block-declaration? (car actions))
+       (if (and (pair? actions)
+                (scode-block-declaration? (car actions))
                 (pair? (cdr actions)))
            `((declare ,@(scode-block-declaration-text (car actions)))
              ,@(unsyntax-sequence-for-splicing
index 3c717f7811884e5aa0e6ad57a20ad97f9bcb2087..5ffe6e08409f4a7df3bd1aa6d9da678261caf546 100644 (file)
@@ -284,7 +284,9 @@ USA.
         (or (eq? f1 (scode-conditional-consequent f2))
             (eq? f1 (scode-conditional-alternative f2))))
        ((scode-sequence? f2)
-        (eq? f1 (car (last-pair (scode-sequence-actions f2)))))
+        (let ((actions (scode-sequence-actions f2)))
+          (and (pair? actions)
+               (eq? f1 (car (last-pair actions))))))
        (else #f)))
 \f
 ;;;; Stepper nodes
index ada608a27def11ebbeb6cf998392635de6cd3e9e..32d133ee67ac697e3e19fa4d5e256a6806a65479 100644 (file)
@@ -593,9 +593,12 @@ USA.
                           (cons action filtered)))
                     '()
                     (sequence/collect-actions '() actions))))
-    (if (null? (cdr filtered-actions))
-        (car filtered-actions)
-        (sequence/%make scode filtered-actions))))
+    (cond ((not (pair? filtered-actions))
+          (constant/make unspecific unspecific))
+         ((not (pair? (cdr filtered-actions)))
+           (car filtered-actions))
+         (else
+           (sequence/%make scode filtered-actions)))))
 
 ;; Done specially so we can tweak the print method.
 ;; This makes debugging an awful lot easier.
index e3c88c70d7de108908c57177e65154d2c5480661..78fa6d361b96c954b81624ff57eb19b5a0aa20c8 100644 (file)
@@ -324,10 +324,15 @@ USA.
 (define (transform/sequence block environment expression)
   ;; Don't remove references from sequences here.  We want them
   ;; to signal ignored variables.
-  (sequence/%make
-   expression
-   (transform/expressions block environment
-                         (scode-sequence-actions expression))))
+  (let ((actions
+        (transform/expressions block environment
+                               (scode-sequence-actions expression))))
+    (cond ((not (pair? actions))
+          (transform/constant block environment unspecific))
+         ((not (pair? (cdr actions)))
+          (car actions))
+         (else
+          (sequence/%make expression actions)))))
 
 (define (transform/the-environment block environment expression)
   environment ; ignored