WIP on tag analysis, annotations, and utilization.
This commit is contained in:
		
							parent
							
								
									d73dfd1287
								
							
						
					
					
						commit
						579b823f44
					
				| 
						 | 
				
			
			@ -24,7 +24,8 @@ EXTRA_DIST=ikarus.boot.prebuilt ikarus.enumerations.ss \
 | 
			
		|||
  psyntax.internal.ss psyntax.library-manager.ss \
 | 
			
		||||
  unicode/unicode-char-cases.ss unicode/unicode-charinfo.ss \
 | 
			
		||||
  ikarus.io.ss ikarus.time-and-date.ss ikarus.not-yet-implemented.ss \
 | 
			
		||||
  ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss
 | 
			
		||||
  ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss \
 | 
			
		||||
  ikarus.compiler.tag-annotation-analysis.ss ikarus.ontology.ss
 | 
			
		||||
 
 | 
			
		||||
all: $(nodist_pkglib_DATA)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,7 +178,8 @@ EXTRA_DIST = ikarus.boot.prebuilt ikarus.enumerations.ss \
 | 
			
		|||
  psyntax.internal.ss psyntax.library-manager.ss \
 | 
			
		||||
  unicode/unicode-char-cases.ss unicode/unicode-charinfo.ss \
 | 
			
		||||
  ikarus.io.ss ikarus.time-and-date.ss ikarus.not-yet-implemented.ss \
 | 
			
		||||
  ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss
 | 
			
		||||
  ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss \
 | 
			
		||||
  ikarus.compiler.tag-annotation-analysis.ss ikarus.ontology.ss
 | 
			
		||||
 | 
			
		||||
revno = "$(shell sed 's/ .*//' ../.bzr/branch/last-revision 2>/dev/null)"
 | 
			
		||||
CLEANFILES = $(nodist_pkglib_DATA) ikarus.config.ss
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -67,6 +67,13 @@
 | 
			
		|||
  (define (mkfuncall op arg*)
 | 
			
		||||
    (import primops)
 | 
			
		||||
    (struct-case op
 | 
			
		||||
      [(known x t)
 | 
			
		||||
       (struct-case x
 | 
			
		||||
         [(primref name)
 | 
			
		||||
          (if (primop? name)
 | 
			
		||||
              (make-primcall name arg*)
 | 
			
		||||
              (make-funcall op arg*))]
 | 
			
		||||
         [else (make-funcall op arg*)])]
 | 
			
		||||
      [(primref name)
 | 
			
		||||
       (cond
 | 
			
		||||
         [(primop? name)
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +81,10 @@
 | 
			
		|||
         [else (make-funcall op arg*)])]
 | 
			
		||||
      [else (make-funcall op arg*)]))
 | 
			
		||||
  ;;;
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (Expr x) t)]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (Expr x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -91,11 +102,9 @@
 | 
			
		|||
      [(forcall op arg*)
 | 
			
		||||
       (make-forcall op (map Expr arg*))]
 | 
			
		||||
      [(funcall rator arg*)
 | 
			
		||||
       (mkfuncall (Expr rator) (map Expr arg*))]
 | 
			
		||||
       (mkfuncall (A rator) (map A arg*))]
 | 
			
		||||
      [(jmpcall label rator arg*)
 | 
			
		||||
       (make-jmpcall label (Expr rator) (map Expr arg*))]
 | 
			
		||||
      [(mvcall rator k)
 | 
			
		||||
       (make-mvcall (Expr rator) (Clambda k))]
 | 
			
		||||
      [else (error who "invalid expr" x)]))
 | 
			
		||||
  ;;;
 | 
			
		||||
  (define (ClambdaCase x)
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +151,10 @@
 | 
			
		|||
          [(closure code free* well-known?) 
 | 
			
		||||
           (make-closure code (map Var free*) well-known?)]))
 | 
			
		||||
      (make-fix lhs* (map handle-closure rhs*) body))
 | 
			
		||||
    (define (A x)
 | 
			
		||||
      (struct-case x
 | 
			
		||||
        [(known x t) (make-known (Expr x) t)]
 | 
			
		||||
        [else (Expr x)]))
 | 
			
		||||
    (define (Expr x)
 | 
			
		||||
      (struct-case x
 | 
			
		||||
        [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -159,15 +172,13 @@
 | 
			
		|||
         (let ([t (unique-var 'tmp)])
 | 
			
		||||
           (Expr (make-fix (list t) (list x) t)))]
 | 
			
		||||
        [(primcall op arg*)
 | 
			
		||||
         (make-primcall op (map Expr arg*))]
 | 
			
		||||
         (make-primcall op (map A arg*))]
 | 
			
		||||
        [(forcall op arg*)
 | 
			
		||||
         (make-forcall op (map Expr arg*))]
 | 
			
		||||
        [(funcall rator arg*)
 | 
			
		||||
         (make-funcall (Expr rator) (map Expr arg*))]
 | 
			
		||||
         (make-funcall (A rator) (map A arg*))]
 | 
			
		||||
        [(jmpcall label rator arg*)
 | 
			
		||||
         (make-jmpcall label (Expr rator) (map Expr arg*))]
 | 
			
		||||
        [(mvcall rator k)
 | 
			
		||||
         (make-mvcall (Expr rator) (Clambda k))]
 | 
			
		||||
        [else (error who "invalid expr" x)]))
 | 
			
		||||
    Expr)
 | 
			
		||||
  ;;;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,20 +219,28 @@
 | 
			
		|||
 | 
			
		||||
(define (insert-engine-checks x)
 | 
			
		||||
  (define who 'insert-engine-checks)
 | 
			
		||||
  (define (known-primref? x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (known-primref? x)]
 | 
			
		||||
      [(primref)   #t]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (Expr x)]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (Expr x) 
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant)                 #f]
 | 
			
		||||
      [(var)                      #f]
 | 
			
		||||
      [(primref)                  #f]
 | 
			
		||||
      [(jmpcall label rator arg*) #t]
 | 
			
		||||
      [(mvcall rator k)           #t] 
 | 
			
		||||
      [(funcall rator arg*)
 | 
			
		||||
       (if (primref? rator) (ormap Expr arg*) #t)]
 | 
			
		||||
       (if (known-primref? rator) (ormap A arg*) #t)]
 | 
			
		||||
      [(bind lhs* rhs* body)      (or (ormap Expr rhs*) (Expr body))]
 | 
			
		||||
      [(fix lhs* rhs* body)       (Expr body)]
 | 
			
		||||
      [(conditional e0 e1 e2)     (or (Expr e0) (Expr e1) (Expr e2))]
 | 
			
		||||
      [(seq e0 e1)                (or (Expr e0) (Expr e1))]
 | 
			
		||||
      [(primcall op arg*)         (ormap Expr arg*)]
 | 
			
		||||
      [(primcall op arg*)         (ormap A arg*)]
 | 
			
		||||
      [(forcall op arg*)          (ormap Expr arg*)]
 | 
			
		||||
      [else (error who "invalid expr" x)]))
 | 
			
		||||
  (define (Main x)
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +264,10 @@
 | 
			
		|||
 | 
			
		||||
(define (insert-stack-overflow-check x)
 | 
			
		||||
  (define who 'insert-stack-overflow-check)
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (NonTail x)]
 | 
			
		||||
      [else (NonTail x)]))
 | 
			
		||||
  (define (NonTail x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant)                 #f]
 | 
			
		||||
| 
						 | 
				
			
			@ -257,8 +280,9 @@
 | 
			
		|||
      [(fix lhs* rhs* body)   (NonTail body)]
 | 
			
		||||
      [(conditional e0 e1 e2) (or (NonTail e0) (NonTail e1) (NonTail e2))]
 | 
			
		||||
      [(seq e0 e1)            (or (NonTail e0) (NonTail e1))]
 | 
			
		||||
      [(primcall op arg*)     (ormap NonTail arg*)]
 | 
			
		||||
      [(primcall op arg*)     (ormap A arg*)]
 | 
			
		||||
      [(forcall op arg*)      (ormap NonTail arg*)]
 | 
			
		||||
      [(known x t v) (NonTail x)]
 | 
			
		||||
      [else (error who "invalid expr" x)]))
 | 
			
		||||
  (define (Tail x) 
 | 
			
		||||
    (struct-case x
 | 
			
		||||
| 
						 | 
				
			
			@ -295,58 +319,6 @@
 | 
			
		|||
       (make-codes (map Clambda code*) (Main body))]))
 | 
			
		||||
  (Program x))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define (insert-dummy-type-annotations x)
 | 
			
		||||
  (define who 'insert-dummy-type-annotations)
 | 
			
		||||
  (define (Closure x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(closure code free*) 
 | 
			
		||||
       x]
 | 
			
		||||
       ;(make-closure (Expr code) (map Var free*))]
 | 
			
		||||
      [else (error who "not a closure" x)]))
 | 
			
		||||
  (define (Expr x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant i) 
 | 
			
		||||
       (make-known x 'constant i)]
 | 
			
		||||
      [(var)      x]
 | 
			
		||||
      [(primref op) 
 | 
			
		||||
       (make-known x 'primitive op)]
 | 
			
		||||
      [(bind lhs* rhs* body)
 | 
			
		||||
       (make-bind lhs* (map Expr rhs*) (Expr body))]
 | 
			
		||||
      [(fix lhs* rhs* body)
 | 
			
		||||
       (make-fix lhs* (map Closure rhs*) (Expr body))]
 | 
			
		||||
      [(conditional e0 e1 e2)
 | 
			
		||||
       (make-conditional (Expr e0) (Expr e1) (Expr e2))]
 | 
			
		||||
      [(seq e0 e1)
 | 
			
		||||
       (make-seq (Expr e0) (Expr e1))]
 | 
			
		||||
      [(primcall op arg*)         
 | 
			
		||||
       (make-primcall op (map Expr arg*))]
 | 
			
		||||
      [(forcall op arg*)
 | 
			
		||||
       (make-forcall op (map Expr arg*))]
 | 
			
		||||
      [(funcall rator arg*)
 | 
			
		||||
       (make-funcall (Expr rator) (map Expr arg*))]
 | 
			
		||||
      [(jmpcall label rator arg*) 
 | 
			
		||||
       (make-jmpcall label (Expr rator) (map Expr arg*))]
 | 
			
		||||
      [(mvcall rator k)
 | 
			
		||||
       (make-mvcall (Expr rator) (Expr k))]
 | 
			
		||||
      [else (error who "invalid expr" x)]))
 | 
			
		||||
  (define (ClambdaCase x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(clambda-case info body)
 | 
			
		||||
       (make-clambda-case info (Expr body))]))
 | 
			
		||||
  (define (Clambda x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(clambda label case* cp free* name)
 | 
			
		||||
       (make-clambda label (map ClambdaCase case*) cp free* name)]))
 | 
			
		||||
  (define (Program x)
 | 
			
		||||
    (struct-case x 
 | 
			
		||||
      [(codes code* body)
 | 
			
		||||
       (make-codes (map Clambda code*) (Expr body))]))
 | 
			
		||||
  (Program x))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(include "pass-specify-rep.ss")
 | 
			
		||||
 | 
			
		||||
(define parameter-registers '(%edi)) 
 | 
			
		||||
| 
						 | 
				
			
			@ -392,6 +364,7 @@
 | 
			
		|||
       (do-bind lhs* rhs* (S body k))]
 | 
			
		||||
      [(seq e0 e1)
 | 
			
		||||
       (make-seq (E e0) (S e1 k))]
 | 
			
		||||
      [(known x) (S x k)]
 | 
			
		||||
      [else
 | 
			
		||||
       (cond
 | 
			
		||||
         [(or (constant? x) (symbol? x)) (k x)]
 | 
			
		||||
| 
						 | 
				
			
			@ -604,6 +577,7 @@
 | 
			
		|||
       (make-shortcut 
 | 
			
		||||
          (V d body)
 | 
			
		||||
          (V d handler))] 
 | 
			
		||||
      [(known x) (V d x)]
 | 
			
		||||
      [else 
 | 
			
		||||
       (if (symbol? x) 
 | 
			
		||||
           (make-set d x)
 | 
			
		||||
| 
						 | 
				
			
			@ -3012,7 +2986,6 @@
 | 
			
		|||
         [x (eliminate-fix x)]
 | 
			
		||||
         [x (insert-engine-checks x)]
 | 
			
		||||
         [x (insert-stack-overflow-check x)]
 | 
			
		||||
         ;[x (insert-dummy-type-annotations x)]
 | 
			
		||||
         [x (specify-representation x)]
 | 
			
		||||
         [x (impose-calling-convention/evaluation-order x)]
 | 
			
		||||
         [x (time-it "frame" (lambda () (assign-frame-sizes x)))]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,9 +106,6 @@
 | 
			
		|||
 | 
			
		||||
  (define cp0-effort-limit (make-parameter 50))
 | 
			
		||||
  (define cp0-size-limit (make-parameter 8))
 | 
			
		||||
  ;(define cp0-effort-limit (make-parameter 100))
 | 
			
		||||
  ;(define cp0-size-limit (make-parameter 10))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  (define primitive-info-list
 | 
			
		||||
    '(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,8 @@
 | 
			
		|||
          assembler-output optimize-cp
 | 
			
		||||
          current-primitive-locations eval-core
 | 
			
		||||
          compile-core-expr expand/optimize optimizer-output
 | 
			
		||||
          cp0-effort-limit cp0-size-limit optimize-level)
 | 
			
		||||
          cp0-effort-limit cp0-size-limit optimize-level 
 | 
			
		||||
          perform-tag-analysis tag-analysis-output)
 | 
			
		||||
  (import 
 | 
			
		||||
    (rnrs hashtables)
 | 
			
		||||
    (ikarus system $fx)
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +33,8 @@
 | 
			
		|||
        compile-core-expr-to-port assembler-output
 | 
			
		||||
        current-primitive-locations eval-core
 | 
			
		||||
        cp0-size-limit cp0-effort-limit 
 | 
			
		||||
        expand/optimize optimizer-output)
 | 
			
		||||
        expand/optimize optimizer-output
 | 
			
		||||
        tag-analysis-output perform-tag-analysis)
 | 
			
		||||
    (ikarus.fasl.write)
 | 
			
		||||
    (ikarus.intel-assembler))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +141,7 @@
 | 
			
		|||
(define-struct assign (lhs rhs))
 | 
			
		||||
(define-struct mvcall (producer consumer))
 | 
			
		||||
 | 
			
		||||
(define-struct known (expr type value))
 | 
			
		||||
(define-struct known (expr type))
 | 
			
		||||
 | 
			
		||||
(define-struct shortcut (body handler))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -440,9 +442,10 @@
 | 
			
		|||
  (define (E x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant c) `(quote ,c)]
 | 
			
		||||
      [(known x t) `(known ,(E x) ,(T:description t))]
 | 
			
		||||
      [(code-loc x) `(code-loc ,x)]
 | 
			
		||||
      [(var x) (string->symbol (format ":~a" x))]
 | 
			
		||||
      [(prelex name) (string->symbol (format ":~a" x))]
 | 
			
		||||
      [(prelex name) (string->symbol (format ":~a" name))]
 | 
			
		||||
      [(primref x) x]
 | 
			
		||||
      [(conditional test conseq altern) 
 | 
			
		||||
       `(if ,(E test) ,(E conseq) ,(E altern))]
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,6 +1124,8 @@
 | 
			
		|||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
  (Expr x))
 | 
			
		||||
 | 
			
		||||
(include "ikarus.compiler.tag-annotation-analysis.ss")
 | 
			
		||||
 | 
			
		||||
(define (introduce-vars x)
 | 
			
		||||
  (define who 'introduce-vars)
 | 
			
		||||
  (define (lookup x)
 | 
			
		||||
| 
						 | 
				
			
			@ -1134,6 +1139,10 @@
 | 
			
		|||
      (set-var-global-loc! v (prelex-global-location x))
 | 
			
		||||
      (set-prelex-operand! x v)
 | 
			
		||||
      v))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (E x) t)]
 | 
			
		||||
      [else (E x)]))
 | 
			
		||||
  (define (E x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,9 +1172,9 @@
 | 
			
		|||
           cls*)
 | 
			
		||||
         cp free name)]
 | 
			
		||||
      [(primcall rator rand*)
 | 
			
		||||
       (make-primcall rator (map E rand*))]
 | 
			
		||||
       (make-primcall rator (map A rand*))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (make-funcall (E rator) (map E rand*))]
 | 
			
		||||
       (make-funcall (A rator) (map A rand*))]
 | 
			
		||||
      [(forcall rator rand*) (make-forcall rator (map E rand*))]
 | 
			
		||||
      [(assign lhs rhs)
 | 
			
		||||
       (make-assign (lookup lhs) (E rhs))]
 | 
			
		||||
| 
						 | 
				
			
			@ -1192,6 +1201,10 @@
 | 
			
		|||
    (if (null? lhs*) 
 | 
			
		||||
        (Expr body)
 | 
			
		||||
        (make-fix lhs* (map CLambda rhs*) (Expr body))))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (Expr x) t)]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (Expr x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1217,12 +1230,22 @@
 | 
			
		|||
      [(forcall op rand*)
 | 
			
		||||
       (make-forcall op (map Expr rand*))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (make-funcall (Expr rator) (map Expr rand*))]
 | 
			
		||||
       (make-funcall (A rator) (map A rand*))]
 | 
			
		||||
      [(mvcall p c) (make-mvcall (Expr p) (Expr c))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
  (Expr x))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define (untag x)
 | 
			
		||||
  (struct-case x 
 | 
			
		||||
    [(known x t) (values x t)]
 | 
			
		||||
    [else        (values x #f)]))
 | 
			
		||||
 | 
			
		||||
(define (tag x t)
 | 
			
		||||
  (if t
 | 
			
		||||
      (make-known x t)
 | 
			
		||||
      x))
 | 
			
		||||
 | 
			
		||||
(define (optimize-for-direct-jumps x)
 | 
			
		||||
  (define who 'optimize-for-direct-jumps)
 | 
			
		||||
  (define (init-var x)
 | 
			
		||||
| 
						 | 
				
			
			@ -1252,20 +1275,24 @@
 | 
			
		|||
                 (cond
 | 
			
		||||
                   [proper
 | 
			
		||||
                    (if (fx= n (length fml*))
 | 
			
		||||
                        (make-jmpcall label rator rand*)
 | 
			
		||||
                        (make-jmpcall label (strip rator) (map strip rand*))
 | 
			
		||||
                        (f (cdr cls*)))]
 | 
			
		||||
                   [else
 | 
			
		||||
                    (if (fx<= (length (cdr fml*)) n)
 | 
			
		||||
                        (make-jmpcall label rator
 | 
			
		||||
                        (make-jmpcall label (strip rator)
 | 
			
		||||
                           (let f ([fml* (cdr fml*)] [rand* rand*])
 | 
			
		||||
                             (cond
 | 
			
		||||
                               [(null? fml*) 
 | 
			
		||||
                                ;;; FIXME: construct list afterwards
 | 
			
		||||
                                (list (make-funcall (make-primref 'list) rand*))]
 | 
			
		||||
                               [else
 | 
			
		||||
                                (cons (car rand*)
 | 
			
		||||
                                (cons (strip (car rand*))
 | 
			
		||||
                                      (f (cdr fml*) (cdr rand*)))])))
 | 
			
		||||
                        (f (cdr cls*)))])])]))])))
 | 
			
		||||
  (define (strip x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) x]
 | 
			
		||||
      [else x]))
 | 
			
		||||
  (define (CLambda x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(clambda g cls* cp free name) 
 | 
			
		||||
| 
						 | 
				
			
			@ -1277,6 +1304,14 @@
 | 
			
		|||
                   (make-clambda-case info (Expr body))]))
 | 
			
		||||
              cls*)
 | 
			
		||||
         cp free name)]))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (Expr x) t)]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (A- x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (Expr x)]
 | 
			
		||||
      [else (Expr x)])) 
 | 
			
		||||
  (define (Expr x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1296,19 +1331,18 @@
 | 
			
		|||
      [(forcall op rand*)
 | 
			
		||||
       (make-forcall op (map Expr rand*))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (let ([rator (Expr rator)])
 | 
			
		||||
       (let-values ([(rator t) (untag (A rator))])
 | 
			
		||||
         (cond
 | 
			
		||||
           [(and (var? rator) (bound-var rator)) =>
 | 
			
		||||
            (lambda (c)
 | 
			
		||||
              (optimize c rator (map Expr rand*)))]
 | 
			
		||||
              (optimize c rator (map A rand*)))]
 | 
			
		||||
           [(and (primref? rator)
 | 
			
		||||
                 (eq? (primref-name rator) '$$apply))
 | 
			
		||||
            (make-jmpcall (sl-apply-label)
 | 
			
		||||
                          (Expr (car rand*))
 | 
			
		||||
                          (map Expr (cdr rand*)))]
 | 
			
		||||
                          (A- (car rand*))
 | 
			
		||||
                          (map A- (cdr rand*)))]
 | 
			
		||||
           [else
 | 
			
		||||
            (make-funcall rator (map Expr rand*))]))]
 | 
			
		||||
      [(mvcall p c) (make-mvcall (Expr p) (Expr c))]
 | 
			
		||||
            (make-funcall (tag rator t) (map A rand*))]))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
  (Expr x))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1335,6 +1369,10 @@
 | 
			
		|||
             (list (make-constant loc) (car lhs*)))
 | 
			
		||||
           (global-assign (cdr lhs*) body)))]
 | 
			
		||||
      [else (global-assign (cdr lhs*) body)]))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (Expr x) t)]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (Expr x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1367,11 +1405,14 @@
 | 
			
		|||
      [(forcall op rand*)
 | 
			
		||||
       (make-forcall op (map Expr rand*))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (make-funcall (Expr rator) (map Expr rand*))]
 | 
			
		||||
      [(mvcall p c) (make-mvcall (Expr p) (Expr c))]
 | 
			
		||||
       (make-funcall (A rator) (map A rand*))]
 | 
			
		||||
      [(jmpcall label rator rand*)
 | 
			
		||||
       (make-jmpcall label (Expr rator) (map Expr rand*))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
  (define (AM x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (Main x) t)]
 | 
			
		||||
      [else (Main x)]))
 | 
			
		||||
  (define (Main x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1397,8 +1438,7 @@
 | 
			
		|||
      [(forcall op rand*)
 | 
			
		||||
       (make-forcall op (map Main rand*))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (make-funcall (Main rator) (map Main rand*))]
 | 
			
		||||
      [(mvcall p c) (make-mvcall (Main p) (Main c))]
 | 
			
		||||
       (make-funcall (AM rator) (map AM rand*))]
 | 
			
		||||
      [(jmpcall label rator rand*)
 | 
			
		||||
       (make-jmpcall label (Main rator) (map Main rand*))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
| 
						 | 
				
			
			@ -1448,6 +1488,19 @@
 | 
			
		|||
              free
 | 
			
		||||
              #f)
 | 
			
		||||
            free))]))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) 
 | 
			
		||||
       (let-values ([(x free) (Expr x)])
 | 
			
		||||
         (values (make-known x t) free))]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (define (A* x*)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(null? x*) (values '() '())]
 | 
			
		||||
      [else
 | 
			
		||||
       (let-values ([(a a-free) (A (car x*))]
 | 
			
		||||
                    [(d d-free) (A* (cdr x*))])
 | 
			
		||||
         (values (cons a d) (union a-free d-free)))]))
 | 
			
		||||
  (define (Expr ex)
 | 
			
		||||
    (struct-case ex
 | 
			
		||||
      [(constant) (values ex '())]
 | 
			
		||||
| 
						 | 
				
			
			@ -1486,19 +1539,25 @@
 | 
			
		|||
       (let-values ([(rand* rand*-free) (Expr* rand*)])
 | 
			
		||||
         (values (make-forcall op rand*)  rand*-free))]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (let-values ([(rator rat-free) (Expr rator)]
 | 
			
		||||
                    [(rand* rand*-free) (Expr* rand*)])
 | 
			
		||||
       (let-values ([(rator rat-free) (A rator)]
 | 
			
		||||
                    [(rand* rand*-free) (A* rand*)])
 | 
			
		||||
         (values (make-funcall rator rand*)
 | 
			
		||||
                 (union rat-free rand*-free)))]
 | 
			
		||||
      [(jmpcall label rator rand*)
 | 
			
		||||
       (let-values ([(rator rat-free)
 | 
			
		||||
                     (if (and (optimize-cp) (var? rator))
 | 
			
		||||
                         (values rator (singleton rator))
 | 
			
		||||
                         (Expr rator))]
 | 
			
		||||
                    [(rand* rand*-free) (Expr* rand*)])
 | 
			
		||||
                     (if (optimize-cp) (Rator rator) (Expr rator))]
 | 
			
		||||
                    [(rand* rand*-free)
 | 
			
		||||
                     (A* rand*)])
 | 
			
		||||
         (values (make-jmpcall label rator rand*) 
 | 
			
		||||
                 (union rat-free rand*-free)))]
 | 
			
		||||
      [else (error who "invalid expression" ex)]))
 | 
			
		||||
  (define (Rator x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(var) (values x (singleton x))]
 | 
			
		||||
      ;[(known x t)
 | 
			
		||||
      ; (let-values ([(x free) (Rator x)])
 | 
			
		||||
      ;   (values (make-known x t) free))]
 | 
			
		||||
      [else (Expr x)]))
 | 
			
		||||
  (let-values ([(prog free) (Expr prog)])
 | 
			
		||||
    (unless (null? free) 
 | 
			
		||||
      (error 'convert-closures "free vars encountered in program"
 | 
			
		||||
| 
						 | 
				
			
			@ -1696,6 +1755,10 @@
 | 
			
		|||
                y)]
 | 
			
		||||
             [else y]))]
 | 
			
		||||
        [else x])))
 | 
			
		||||
  (define (A x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known x t) (make-known (E x) t)]
 | 
			
		||||
      [else (E x)]))
 | 
			
		||||
  (define (E x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant) x]
 | 
			
		||||
| 
						 | 
				
			
			@ -1707,7 +1770,7 @@
 | 
			
		|||
       (make-conditional (E test) (E conseq) (E altern))]
 | 
			
		||||
      [(seq e0 e1)           (make-seq (E e0) (E e1))]
 | 
			
		||||
      [(forcall op rand*)    (make-forcall op (map E rand*))]
 | 
			
		||||
      [(funcall rator rand*) (make-funcall (E rator) (map E rand*))]
 | 
			
		||||
      [(funcall rator rand*) (make-funcall (A rator) (map A rand*))]
 | 
			
		||||
      [(jmpcall label rator rand*)
 | 
			
		||||
       (make-jmpcall label (E rator) (map E rand*))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
| 
						 | 
				
			
			@ -2267,6 +2330,7 @@
 | 
			
		|||
     (printf "    ~s\n" x)]))
 | 
			
		||||
 | 
			
		||||
(define optimizer-output (make-parameter #f))
 | 
			
		||||
(define perform-tag-analysis (make-parameter #f))
 | 
			
		||||
 | 
			
		||||
(define (compile-core-expr->code p)
 | 
			
		||||
  (let* ([p (recordize p)]
 | 
			
		||||
| 
						 | 
				
			
			@ -2280,6 +2344,9 @@
 | 
			
		|||
               (pretty-print (unparse-pretty p)))
 | 
			
		||||
            #f)]
 | 
			
		||||
         [p (rewrite-assignments p)]
 | 
			
		||||
         [p (if (perform-tag-analysis)
 | 
			
		||||
                (introduce-tags p)
 | 
			
		||||
                p)]
 | 
			
		||||
         [p (introduce-vars p)]
 | 
			
		||||
         [p (sanitize-bindings p)]
 | 
			
		||||
         [p (optimize-for-direct-jumps p)]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,434 @@
 | 
			
		|||
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
 | 
			
		||||
;;; Copyright (C) 2006,2007,2008  Abdulaziz Ghuloum
 | 
			
		||||
;;; 
 | 
			
		||||
;;; This program is free software: you can redistribute it and/or modify
 | 
			
		||||
;;; it under the terms of the GNU General Public License version 3 as
 | 
			
		||||
;;; published by the Free Software Foundation.
 | 
			
		||||
;;; 
 | 
			
		||||
;;; This program is distributed in the hope that it will be useful, but
 | 
			
		||||
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
;;; General Public License for more details.
 | 
			
		||||
;;; 
 | 
			
		||||
;;; You should have received a copy of the GNU General Public License
 | 
			
		||||
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;;; THIS IS WIP
 | 
			
		||||
(include "ikarus.ontology.ss")
 | 
			
		||||
 | 
			
		||||
(define tag-analysis-output (make-parameter #f))
 | 
			
		||||
 | 
			
		||||
(define (introduce-tags x)
 | 
			
		||||
  (define who 'introduce-tags)
 | 
			
		||||
  #;
 | 
			
		||||
  (define primitive-return-types 
 | 
			
		||||
    '(
 | 
			
		||||
      [length                fixnum]
 | 
			
		||||
      [bytevector-length     fixnum]
 | 
			
		||||
      [bytevector-u8-ref     fixnum]
 | 
			
		||||
      [bytevector-s8-ref     fixnum]
 | 
			
		||||
      [bytevector-u16-ref    fixnum]
 | 
			
		||||
      [bytevector-s16-ref    fixnum]
 | 
			
		||||
      [bytevector-u16-native-ref    fixnum]
 | 
			
		||||
      [bytevector-s16-native-ref    fixnum]
 | 
			
		||||
      [fixnum-width          fixnum]
 | 
			
		||||
      [greatest-fixnum       fixnum]
 | 
			
		||||
      [least-fixnum          fixnum]
 | 
			
		||||
      [=                     boolean]
 | 
			
		||||
      [<                     boolean]
 | 
			
		||||
      [<=                    boolean]
 | 
			
		||||
      [>                     boolean]
 | 
			
		||||
      [>=                    boolean]
 | 
			
		||||
      [even?                 boolean]
 | 
			
		||||
      [odd?                  boolean]
 | 
			
		||||
      [rational?             boolean]
 | 
			
		||||
      [rational-valued?      boolean]
 | 
			
		||||
      [real?                 boolean]
 | 
			
		||||
      [real-valued?          boolean]
 | 
			
		||||
      [bignum?               boolean]
 | 
			
		||||
      [ratnum?               boolean]
 | 
			
		||||
      [flonum?               boolean]
 | 
			
		||||
      [fixnum?               boolean]
 | 
			
		||||
      [integer?              boolean]
 | 
			
		||||
      [exact?                boolean]
 | 
			
		||||
      [finite?               boolean]
 | 
			
		||||
      [inexact?              boolean]
 | 
			
		||||
      [infinite?             boolean]
 | 
			
		||||
      [positive?             boolean]
 | 
			
		||||
      [negative?             boolean]
 | 
			
		||||
      [nan?                  boolean]
 | 
			
		||||
      [number?               boolean]
 | 
			
		||||
      [compnum?              boolean]
 | 
			
		||||
      [cflonum?              boolean]
 | 
			
		||||
      [complex?              boolean]
 | 
			
		||||
      [list?                 boolean]
 | 
			
		||||
      [eq?                   boolean]
 | 
			
		||||
      [eqv?                  boolean]
 | 
			
		||||
      [equal?                boolean]
 | 
			
		||||
      [gensym?               boolean]
 | 
			
		||||
      [symbol-bound?         boolean]
 | 
			
		||||
      [code?                 boolean]
 | 
			
		||||
      [immediate?            boolean]
 | 
			
		||||
      [pair?                 boolean]
 | 
			
		||||
      [procedure?            boolean]
 | 
			
		||||
      [symbol?               boolean]
 | 
			
		||||
      [symbol=?              boolean]
 | 
			
		||||
      [boolean?              boolean]
 | 
			
		||||
      [boolean=?             boolean]
 | 
			
		||||
      [vector?               boolean]
 | 
			
		||||
      [bitwise-bit-set?      boolean]
 | 
			
		||||
      [bytevector?           boolean]
 | 
			
		||||
      [bytevector=?          boolean]
 | 
			
		||||
      [enum-set=?            boolean]
 | 
			
		||||
      [binary-port?          boolean]
 | 
			
		||||
      [textual-port?         boolean]
 | 
			
		||||
      [input-port?           boolean]
 | 
			
		||||
      [output-port?          boolean]
 | 
			
		||||
      [port?                 boolean]
 | 
			
		||||
      [port-eof?             boolean]
 | 
			
		||||
      [port-closed?          boolean]
 | 
			
		||||
      [char-ready?           boolean]
 | 
			
		||||
      [eof-object?           boolean]
 | 
			
		||||
      [hashtable?            boolean]
 | 
			
		||||
      [hashtable-mutable?    boolean]
 | 
			
		||||
      [file-exists?          boolean]
 | 
			
		||||
      [file-regular?         boolean]
 | 
			
		||||
      [file-directory?       boolean]
 | 
			
		||||
      [file-symbolic-link?   boolean]
 | 
			
		||||
      [record?               boolean]
 | 
			
		||||
      [record-field-mutable? boolean]
 | 
			
		||||
      [record-type-generative? boolean]
 | 
			
		||||
      [record-type-sealed?   boolean]
 | 
			
		||||
      [record-type-descriptor boolean]
 | 
			
		||||
      [free-identifier=?     boolean]
 | 
			
		||||
      [bound-identifier=?    boolean]
 | 
			
		||||
      [identifier?           boolean]
 | 
			
		||||
      [char-lower-case?      boolean]
 | 
			
		||||
      [char-upper-case?      boolean]
 | 
			
		||||
      [char-title-case?      boolean]
 | 
			
		||||
      [char-whitespace?      boolean]
 | 
			
		||||
      [char-numeric?         boolean]
 | 
			
		||||
      [char-alphabetic?      boolean]
 | 
			
		||||
    ))
 | 
			
		||||
 | 
			
		||||
  (define number!
 | 
			
		||||
    (let ([i 0])
 | 
			
		||||
      (lambda (x)
 | 
			
		||||
        (set-prelex-operand! x i)
 | 
			
		||||
        (set! i (+ i 1)))))
 | 
			
		||||
  (define (V* x* env)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(null? x*) (values '() env '())]
 | 
			
		||||
      [else
 | 
			
		||||
       (let-values ([(x env1 t) (V (car x*) env)]
 | 
			
		||||
                    [(x* env2 t*) (V* (cdr x*) env)])
 | 
			
		||||
         (values (cons x x*)
 | 
			
		||||
                 (and-envs env1 env2)
 | 
			
		||||
                 (cons t t*)))]))
 | 
			
		||||
  (define (constant-type x) 
 | 
			
		||||
    (define (numeric x)
 | 
			
		||||
      (define (size x t)
 | 
			
		||||
        (T:and t
 | 
			
		||||
          (cond
 | 
			
		||||
            [(< x 0) T:negative]
 | 
			
		||||
            [(> x 0) T:positive]
 | 
			
		||||
            [(= x 0) T:zero]
 | 
			
		||||
            [else    t])))
 | 
			
		||||
      (cond
 | 
			
		||||
        [(fixnum? x) (size x T:fixnum)]
 | 
			
		||||
        [(flonum? x) (size x T:flonum)]
 | 
			
		||||
        [(or (bignum? x) (ratnum? x)) 
 | 
			
		||||
         (size x (T:and T:exact T:other-number))]
 | 
			
		||||
        [else        T:number]))
 | 
			
		||||
    (cond
 | 
			
		||||
      [(number? x)    (numeric x)]
 | 
			
		||||
      [(boolean? x)   (if x T:true T:false)]
 | 
			
		||||
      [(null? x)      T:null]
 | 
			
		||||
      [(char? x)      T:char]
 | 
			
		||||
      [(string? x)    T:string]
 | 
			
		||||
      [(vector? x)    T:vector]
 | 
			
		||||
      [(pair? x)      T:pair]
 | 
			
		||||
      [(eq? x (void)) T:void]
 | 
			
		||||
      [else           T:object]))
 | 
			
		||||
  (define (V x env)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant k) (values x env (constant-type k))]
 | 
			
		||||
      [(prelex)     (values x env (lookup x env))]
 | 
			
		||||
      [(primref op) (values x env T:procedure)]
 | 
			
		||||
      [(seq e0 e1)
 | 
			
		||||
       (let-values ([(e0 env t) (V e0 env)])
 | 
			
		||||
         (cond
 | 
			
		||||
           [(eq? (T:object? t) 'no)
 | 
			
		||||
            (values e0 env t)]
 | 
			
		||||
           [else
 | 
			
		||||
            (let-values ([(e1 env t) (V e1 env)])
 | 
			
		||||
              (values (make-seq e0 e1) env t))]))]
 | 
			
		||||
      [(conditional e0 e1 e2)
 | 
			
		||||
       (let-values ([(e0 env t) (V e0 env)])
 | 
			
		||||
         (cond
 | 
			
		||||
           [(eq? (T:object? t) 'no)
 | 
			
		||||
            (values e0 env t)]
 | 
			
		||||
           [(eq? (T:false? t) 'yes)
 | 
			
		||||
            (let-values ([(e2 env t) (V e2 env)])
 | 
			
		||||
              (values (make-seq e0 e2) env t))]
 | 
			
		||||
           [(eq? (T:false? t) 'no)
 | 
			
		||||
            (let-values ([(e1 env t) (V e1 env)])
 | 
			
		||||
              (values (make-seq e0 e1) env t))]
 | 
			
		||||
           [else
 | 
			
		||||
            (let-values ([(e1 env1 t1) (V e1 env)]
 | 
			
		||||
                         [(e2 env2 t2) (V e2 env)])
 | 
			
		||||
              (values (make-conditional e0 e1 e2)
 | 
			
		||||
                      (or-envs env1 env2)
 | 
			
		||||
                      (T:or t1 t2)))]))]
 | 
			
		||||
      [(bind lhs* rhs* body)
 | 
			
		||||
       (let-values ([(rhs* env t*) (V* rhs* env)])
 | 
			
		||||
         (for-each number! lhs*)
 | 
			
		||||
         (let ([env (extend-env* lhs* t* env)])
 | 
			
		||||
           (let-values ([(body env t) (V body env)])
 | 
			
		||||
             (values 
 | 
			
		||||
               (make-bind lhs* rhs* body)
 | 
			
		||||
               env t))))]
 | 
			
		||||
      [(fix lhs* rhs* body)
 | 
			
		||||
       (for-each number! lhs*)
 | 
			
		||||
       (let-values ([(rhs* env t*) (V* rhs* env)])
 | 
			
		||||
         (let ([env (extend-env* lhs* t* env)])
 | 
			
		||||
           (let-values ([(body env t) (V body env)])
 | 
			
		||||
             (values 
 | 
			
		||||
               (make-fix lhs* rhs* body)
 | 
			
		||||
               env t))))]
 | 
			
		||||
      [(clambda g cls* cp free name)
 | 
			
		||||
       (values
 | 
			
		||||
         (make-clambda g
 | 
			
		||||
           (map 
 | 
			
		||||
             (lambda (x)
 | 
			
		||||
               (struct-case x 
 | 
			
		||||
                 [(clambda-case info body)
 | 
			
		||||
                  (for-each number! (case-info-args info))
 | 
			
		||||
                  (let-values ([(body env t) (V body env)])
 | 
			
		||||
                    ;;; dropped env and t
 | 
			
		||||
                    (make-clambda-case info body))]))
 | 
			
		||||
             cls*)
 | 
			
		||||
           cp free name)
 | 
			
		||||
         env
 | 
			
		||||
         T:procedure)]
 | 
			
		||||
      [(funcall rator rand*)
 | 
			
		||||
       (let-values ([(rator rator-env rator-val) (V rator env)]
 | 
			
		||||
                    [(rand* rand*-env rand*-val) (V* rand* env)])
 | 
			
		||||
         (apply-funcall rator rand*
 | 
			
		||||
           rator-val rand*-val
 | 
			
		||||
           rator-env rand*-env))]
 | 
			
		||||
      [(forcall rator rand*)
 | 
			
		||||
       (let-values ([(rand* rand*-env rand*-val) (V* rand* env)])
 | 
			
		||||
         (values (make-forcall rator rand*)
 | 
			
		||||
                 rand*-env
 | 
			
		||||
                 T:object))]
 | 
			
		||||
      [else (error who "invalid expression" (unparse x))]))
 | 
			
		||||
  (define (annotate x t)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(T=? t T:object) x]
 | 
			
		||||
      [else (make-known x t)]))
 | 
			
		||||
  (define (apply-funcall rator rand* rator-val rand*-val rator-env rand*-env)
 | 
			
		||||
    (let ([env (and-envs rator-env rand*-env)]
 | 
			
		||||
          [rand* (map annotate rand* rand*-val)])
 | 
			
		||||
      (struct-case rator
 | 
			
		||||
        [(primref op) 
 | 
			
		||||
         (apply-primcall op rand* env)]
 | 
			
		||||
        [else
 | 
			
		||||
         (values (make-funcall (annotate rator rator-val) rand*)
 | 
			
		||||
                 env
 | 
			
		||||
                 T:object)])))
 | 
			
		||||
  (define (apply-primcall op rand* env)
 | 
			
		||||
    (define (return t)
 | 
			
		||||
      (values (make-funcall (make-primref op) rand*) env t))
 | 
			
		||||
    (define (inject ret-t . rand-t*)
 | 
			
		||||
      (define (extend* x* t* env)
 | 
			
		||||
        (define (extend x t env)
 | 
			
		||||
          (struct-case x
 | 
			
		||||
            [(known expr t0)
 | 
			
		||||
             (extend expr (T:and t t0) env)]
 | 
			
		||||
            [(prelex)
 | 
			
		||||
             (extend-env x t env)]
 | 
			
		||||
            [else env]))
 | 
			
		||||
        (cond
 | 
			
		||||
          [(null? x*) env]
 | 
			
		||||
          [else (extend (car x*) (car t*)
 | 
			
		||||
                  (extend* (cdr x*) (cdr t*) env))]))
 | 
			
		||||
      (cond
 | 
			
		||||
        [(= (length rand-t*) (length rand*))
 | 
			
		||||
         (values (make-funcall (make-primref op) rand*)
 | 
			
		||||
                 (extend* rand* rand-t* env)
 | 
			
		||||
                 ret-t)]
 | 
			
		||||
        [else
 | 
			
		||||
         (error 'apply-primcall "invalid extesion" op rand*)]))
 | 
			
		||||
    (define (inject* ret-t arg-t)
 | 
			
		||||
      (define (extend* x* env)
 | 
			
		||||
        (define (extend x t env)
 | 
			
		||||
          (struct-case x
 | 
			
		||||
            [(known expr t0)
 | 
			
		||||
             (extend expr (T:and t t0) env)]
 | 
			
		||||
            [(prelex)
 | 
			
		||||
             (extend-env x t env)]
 | 
			
		||||
            [else env]))
 | 
			
		||||
        (cond
 | 
			
		||||
          [(null? x*) env]
 | 
			
		||||
          [else (extend (car x*) arg-t
 | 
			
		||||
                  (extend* (cdr x*) env))]))
 | 
			
		||||
      (values (make-funcall (make-primref op) rand*)
 | 
			
		||||
              (extend* rand* env)
 | 
			
		||||
              ret-t))
 | 
			
		||||
    (case op
 | 
			
		||||
      [(cons)        
 | 
			
		||||
       (return T:pair)]
 | 
			
		||||
      [(car cdr
 | 
			
		||||
        caar cadr cdar cddr
 | 
			
		||||
        caaar caadr cadar caddr cdaar cdadr cddar cdddr
 | 
			
		||||
        caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
 | 
			
		||||
        cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr)
 | 
			
		||||
       (inject T:object T:pair)]
 | 
			
		||||
      [(set-car! set-cdr!)
 | 
			
		||||
       (inject T:void T:pair T:object)]
 | 
			
		||||
      [(vector make-vector list->vector)
 | 
			
		||||
       (return T:vector)]
 | 
			
		||||
      [(string make-string list->string)
 | 
			
		||||
       (return T:string)]
 | 
			
		||||
      [(string-length)
 | 
			
		||||
       (inject T:fixnum T:string)]
 | 
			
		||||
      [(vector-length)
 | 
			
		||||
       (inject T:fixnum T:vector)]
 | 
			
		||||
      [(string-ref)
 | 
			
		||||
       (inject T:char T:string T:fixnum)]
 | 
			
		||||
      [(string-set!)
 | 
			
		||||
       (inject T:void T:string T:fixnum T:char)]
 | 
			
		||||
      [(vector-ref)
 | 
			
		||||
       (inject T:object T:vector T:fixnum)]
 | 
			
		||||
      [(vector-set!)
 | 
			
		||||
       (inject T:void T:vector T:fixnum T:object)]
 | 
			
		||||
      [(integer->char)
 | 
			
		||||
       (inject T:char T:fixnum)]
 | 
			
		||||
      [(char->integer)
 | 
			
		||||
       (inject T:fixnum T:char)]
 | 
			
		||||
      [(fx+         fx-         fx*         fxadd1      fxsub1
 | 
			
		||||
        fxquotient  fxremainder fxmodulo    fxsll       fxsra
 | 
			
		||||
        fxand       fxdiv       fxdiv0      fxif        fxior
 | 
			
		||||
        fxlength    fxmax       fxmin       fxmod       fxmod0
 | 
			
		||||
        fxnot       fxxor       fxlogand    fxlogor     fxlognot
 | 
			
		||||
        fxlogxor    fxlogand    fxlogand    fxlogand    fxlogand
 | 
			
		||||
        fxlogand    fxlogand)
 | 
			
		||||
       (inject* T:fixnum T:fixnum)]
 | 
			
		||||
      [(fx= fx< fx<= fx> fx>= fx=? fx<? fx<=? fx>? fx>=?
 | 
			
		||||
        fxeven? fxodd? fxnegative? fxpositive? fxzero?
 | 
			
		||||
        fxbit-set?)
 | 
			
		||||
       (inject* T:boolean T:fixnum)]
 | 
			
		||||
      [(fl=? fl<? fl<=? fl>? fl>=?
 | 
			
		||||
        fleven? flodd? flzero? flpositive? flnegative?
 | 
			
		||||
        flfinite? flinfinite? flinteger? flnan?)
 | 
			
		||||
       (inject* T:boolean T:flonum)]
 | 
			
		||||
      [(char=? char<? char<=? char>? char>=? 
 | 
			
		||||
        char-ci=? char-ci<? char-ci<=? char-ci>? char-ci>=?)
 | 
			
		||||
       (inject* T:boolean T:char)]
 | 
			
		||||
      [(string=? string<? string<=? string>? string>=?
 | 
			
		||||
        string-ci=? string-ci<? string-ci<=? string-ci>?
 | 
			
		||||
        string-ci>=?)
 | 
			
		||||
       (inject* T:boolean T:string)]
 | 
			
		||||
      [(make-parameter 
 | 
			
		||||
        record-constructor  
 | 
			
		||||
        record-accessor     
 | 
			
		||||
        record-constructor  
 | 
			
		||||
        record-predicate    
 | 
			
		||||
        condition-accessor  
 | 
			
		||||
        condition-predicate 
 | 
			
		||||
        enum-set-constructor
 | 
			
		||||
        enum-set-indexer    
 | 
			
		||||
        make-guardian)
 | 
			
		||||
       (return T:procedure)]
 | 
			
		||||
      [else
 | 
			
		||||
       (return T:object)]))
 | 
			
		||||
      
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
  ;;;
 | 
			
		||||
  (define (extend-env* x* v* env)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(null? x*) env]
 | 
			
		||||
      [else 
 | 
			
		||||
       (extend-env* (cdr x*) (cdr v*)
 | 
			
		||||
         (extend-env (car x*) (car v*) env))]))
 | 
			
		||||
  (define (extend-env x t env)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(T=? t T:object) env]
 | 
			
		||||
      [else
 | 
			
		||||
       (let ([x (prelex-operand x)])
 | 
			
		||||
         (let f ([env env])
 | 
			
		||||
           (cond
 | 
			
		||||
             [(or (null? env) (< x (caar env)))
 | 
			
		||||
              (cons (cons x t) env)]
 | 
			
		||||
             [else
 | 
			
		||||
              (cons (car env) (f (cdr env)))])))]))
 | 
			
		||||
  (define (or-envs env1 env2)
 | 
			
		||||
    (define (cons-env x v env)
 | 
			
		||||
      (cond
 | 
			
		||||
        [(T=? v T:object) env]
 | 
			
		||||
        [else (cons (cons x v) env)]))
 | 
			
		||||
    (define (merge-envs1 a1 env1 env2)
 | 
			
		||||
      (if (pair? env2)
 | 
			
		||||
          (merge-envs2 a1 env1 (car env2) (cdr env2))
 | 
			
		||||
          empty-env))
 | 
			
		||||
    (define (merge-envs2 a1 env1 a2 env2)
 | 
			
		||||
      (let ([x1 (car a1)] [x2 (car a2)])
 | 
			
		||||
        (if (eq? x1 x2)
 | 
			
		||||
            (cons-env x1 (T:or (cdr a1) (cdr a2))
 | 
			
		||||
              (merge-envs env1 env2))
 | 
			
		||||
            (if (< x2 x1)
 | 
			
		||||
                (merge-envs1 a1 env1 env2)
 | 
			
		||||
                (merge-envs1 a2 env2 env1)))))
 | 
			
		||||
    (define (merge-envs env1 env2)
 | 
			
		||||
      (if (eq? env1 env2)
 | 
			
		||||
          env1
 | 
			
		||||
          (if (pair? env1)
 | 
			
		||||
              (if (pair? env2) 
 | 
			
		||||
                  (merge-envs2 (car env1) (cdr env1) (car env2) (cdr env2))
 | 
			
		||||
                  empty-env)
 | 
			
		||||
              empty-env)))
 | 
			
		||||
    (merge-envs env1 env2))
 | 
			
		||||
  (define (and-envs env1 env2)
 | 
			
		||||
    (define (cons-env x v env)
 | 
			
		||||
      (cond
 | 
			
		||||
        [(T=? v T:object) env]
 | 
			
		||||
        [else (cons (cons x v) env)]))
 | 
			
		||||
    (define (merge-envs1 a1 env1 env2)
 | 
			
		||||
      (if (pair? env2)
 | 
			
		||||
          (merge-envs2 a1 env1 (car env2) (cdr env2))
 | 
			
		||||
          env1))
 | 
			
		||||
    (define (merge-envs2 a1 env1 a2 env2)
 | 
			
		||||
      (let ([x1 (car a1)] [x2 (car a2)])
 | 
			
		||||
        (if (eq? x1 x2)
 | 
			
		||||
            (cons-env x1 (T:and (cdr a1) (cdr a2))
 | 
			
		||||
              (merge-envs env1 env2))
 | 
			
		||||
            (if (< x2 x1)
 | 
			
		||||
                (cons a2 (merge-envs1 a1 env1 env2))
 | 
			
		||||
                (cons a1 (merge-envs1 a2 env2 env1))))))
 | 
			
		||||
    (define (merge-envs env1 env2)
 | 
			
		||||
      (if (eq? env1 env2)
 | 
			
		||||
          env1
 | 
			
		||||
          (if (pair? env1)
 | 
			
		||||
              (if (pair? env2) 
 | 
			
		||||
                  (merge-envs2 (car env1) (cdr env1) (car env2) (cdr env2))
 | 
			
		||||
                  env1)
 | 
			
		||||
              env2)))
 | 
			
		||||
    (merge-envs env1 env2))
 | 
			
		||||
  (define empty-env '())
 | 
			
		||||
  (define (lookup x env)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(eq? env 'bottom) #f]
 | 
			
		||||
      [else
 | 
			
		||||
       (let ([x (prelex-operand x)])
 | 
			
		||||
         (cond
 | 
			
		||||
           [(assq x env) => cdr]
 | 
			
		||||
           [else T:object]))]))
 | 
			
		||||
  (let-values ([(x env t) (V x empty-env)])
 | 
			
		||||
    (when (tag-analysis-output)
 | 
			
		||||
      (pretty-print (unparse x)))
 | 
			
		||||
    x))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,13 +72,6 @@
 | 
			
		|||
          &i/o-encoding-rcd &no-infinities-rtd &no-infinities-rcd
 | 
			
		||||
          &no-nans-rtd &no-nans-rcd
 | 
			
		||||
          &interrupted-rtd &interrupted-rcd 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          &i/o-would-block-rtd
 | 
			
		||||
          &i/o-would-block-rcd
 | 
			
		||||
          make-i/o-would-block-condition
 | 
			
		||||
          i/o-would-block-condition?
 | 
			
		||||
          i/o-would-block-port
 | 
			
		||||
          )
 | 
			
		||||
  (import
 | 
			
		||||
    (rnrs records inspection)
 | 
			
		||||
| 
						 | 
				
			
			@ -131,11 +124,6 @@
 | 
			
		|||
          i/o-encoding-error? i/o-encoding-error-char
 | 
			
		||||
          no-infinities-violation? make-no-infinities-violation
 | 
			
		||||
          no-nans-violation? make-no-nans-violation
 | 
			
		||||
          
 | 
			
		||||
          &i/o-would-block
 | 
			
		||||
          make-i/o-would-block-condition
 | 
			
		||||
          i/o-would-block-condition?
 | 
			
		||||
          i/o-would-block-port
 | 
			
		||||
          ))
 | 
			
		||||
  
 | 
			
		||||
  (define-record-type &condition 
 | 
			
		||||
| 
						 | 
				
			
			@ -344,10 +332,6 @@
 | 
			
		|||
  (define-condition-type &interrupted &serious
 | 
			
		||||
    make-interrupted-condition interrupted-condition?)
 | 
			
		||||
 | 
			
		||||
  (define-condition-type &i/o-would-block &condition
 | 
			
		||||
    make-i/o-would-block-condition i/o-would-block-condition?
 | 
			
		||||
    (port i/o-would-block-port))
 | 
			
		||||
 | 
			
		||||
  (define print-condition 
 | 
			
		||||
    (let ()
 | 
			
		||||
      (define (print-simple-condition x p)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1309,8 +1309,6 @@
 | 
			
		|||
                              (cond
 | 
			
		||||
                                [(fx>= bytes 0) bytes]
 | 
			
		||||
                                [(fx= bytes EAGAIN-error-code)
 | 
			
		||||
                                 ;(raise-continuable 
 | 
			
		||||
                                 ;  (make-i/o-would-block-condition port))
 | 
			
		||||
                                 (call/cc 
 | 
			
		||||
                                   (lambda (k) 
 | 
			
		||||
                                     (add-io-event fd k 'r)
 | 
			
		||||
| 
						 | 
				
			
			@ -1351,8 +1349,6 @@
 | 
			
		|||
                              (cond
 | 
			
		||||
                                [(fx>= bytes 0) bytes]
 | 
			
		||||
                                [(fx= bytes EAGAIN-error-code)
 | 
			
		||||
                                 ;(raise-continuable 
 | 
			
		||||
                                 ;  (make-i/o-would-block-condition port))
 | 
			
		||||
                                 (call/cc 
 | 
			
		||||
                                   (lambda (k)
 | 
			
		||||
                                     (add-io-event fd k 'w)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,273 @@
 | 
			
		|||
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
 | 
			
		||||
;;; Copyright (C) 2006,2007,2008  Abdulaziz Ghuloum
 | 
			
		||||
;;; 
 | 
			
		||||
;;; This program is free software: you can redistribute it and/or modify
 | 
			
		||||
;;; it under the terms of the GNU General Public License version 3 as
 | 
			
		||||
;;; published by the Free Software Foundation.
 | 
			
		||||
;;; 
 | 
			
		||||
;;; This program is distributed in the hope that it will be useful, but
 | 
			
		||||
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
;;; General Public License for more details.
 | 
			
		||||
;;; 
 | 
			
		||||
;;; You should have received a copy of the GNU General Public License
 | 
			
		||||
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
(define-syntax define-ontology
 | 
			
		||||
  (lambda (x)
 | 
			
		||||
    (define (make-ontology main ls)
 | 
			
		||||
      (define (set-cons x ls)
 | 
			
		||||
        (cond
 | 
			
		||||
          [(memq x ls) ls]
 | 
			
		||||
          [else (cons x ls)]))
 | 
			
		||||
      (define (union ls1 ls2)
 | 
			
		||||
        (cond
 | 
			
		||||
          [(null? ls1) ls2]
 | 
			
		||||
          [else (union (cdr ls1) (set-cons (car ls1) ls2))]))
 | 
			
		||||
      (define (difference ls1 ls2)
 | 
			
		||||
        (cond
 | 
			
		||||
          [(null? ls1) '()]
 | 
			
		||||
          [(memq (car ls1) ls2) (difference (cdr ls1) ls2)]
 | 
			
		||||
          [else (cons (car ls1) (difference (cdr ls1) ls2))]))
 | 
			
		||||
      (define (collect-names ls)
 | 
			
		||||
        (syntax-case ls ()
 | 
			
		||||
          [() '()]
 | 
			
		||||
          [((name (of name* ...)) . rest)
 | 
			
		||||
           (union (cons #'name #'(name* ...)) (collect-names #'rest))]))
 | 
			
		||||
      (define (expand x all)
 | 
			
		||||
        (define (lookup x ls)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? ls) (values 'tag '())]
 | 
			
		||||
            [else
 | 
			
		||||
             (let ([a (car ls)])
 | 
			
		||||
               (cond
 | 
			
		||||
                 [(eq? x (car a)) 
 | 
			
		||||
                  (values (cadr a) (cdr ls))]
 | 
			
		||||
                 [else
 | 
			
		||||
                  (let-values ([(xp ls) (lookup x (cdr ls))])
 | 
			
		||||
                    (values xp (cons a ls)))]))]))
 | 
			
		||||
        (let f ([x x] [ls ls])
 | 
			
		||||
          (let-values ([(xp ls) (lookup x ls)])
 | 
			
		||||
            (cond
 | 
			
		||||
              [(pair? xp)
 | 
			
		||||
               (cons (car xp) (map (lambda (x) (f x ls)) (cdr xp)))]
 | 
			
		||||
              [(eq? xp 'tag) x]
 | 
			
		||||
              [else (error 'expand-lookup "invalid" xp)]))))
 | 
			
		||||
      (define (rename alist x)
 | 
			
		||||
        (cond
 | 
			
		||||
          [(symbol? x) (cdr (assq x alist))]
 | 
			
		||||
          [else (cons (car x) (map (lambda (x) (rename alist x)) (cdr x)))]))
 | 
			
		||||
      (define (enumerate ls)
 | 
			
		||||
        (let f ([i 1] [ls ls])
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? ls) '()]
 | 
			
		||||
            [else (cons i (f (* i 2) (cdr ls)))])))
 | 
			
		||||
      (define (unique-elements x)
 | 
			
		||||
        (define (exclude m ls)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? ls) '()]
 | 
			
		||||
            [(zero? (bitwise-and m (car ls)))
 | 
			
		||||
             (cons (car ls) (exclude m (cdr ls)))]
 | 
			
		||||
            [else (exclude m (cdr ls))]))
 | 
			
		||||
        (define (exclusive* m* x**)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? (cdr m*)) (values (car m*) (car x**))]
 | 
			
		||||
            [else
 | 
			
		||||
             (let-values ([(m1 x1*) (values (car m*) (car x**))]
 | 
			
		||||
                          [(m2 x2*) (exclusive* (cdr m*) (cdr x**))])
 | 
			
		||||
               (let ([x1* (exclude m2 x1*)]
 | 
			
		||||
                     [x2* (exclude m1 x2*)])
 | 
			
		||||
                 (values (bitwise-ior m1 m2) (append x1* x2*))))]))
 | 
			
		||||
        (define (inclusive* m* x**)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? (cdr m*)) (values (car m*) (car x**))]
 | 
			
		||||
            [else
 | 
			
		||||
             (let-values ([(m1 x1*) (values (car m*) (car x**))]
 | 
			
		||||
                          [(m2 x2*) (inclusive* (cdr m*) (cdr x**))])
 | 
			
		||||
               (values (bitwise-ior m1 m2)
 | 
			
		||||
                       (remp not
 | 
			
		||||
                         (apply append
 | 
			
		||||
                           (map (lambda (x)
 | 
			
		||||
                                  (map (lambda (y)
 | 
			
		||||
                                         (if (= (bitwise-and m1 m2 x)
 | 
			
		||||
                                                (bitwise-and m1 m2 y))
 | 
			
		||||
                                             (bitwise-ior x y)
 | 
			
		||||
                                             #f))
 | 
			
		||||
                                       x2*))
 | 
			
		||||
                                x1*)))))]))
 | 
			
		||||
        (define (f* ls)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(null? ls) (values '() '())]
 | 
			
		||||
            [else
 | 
			
		||||
             (let-values ([(m x*) (f (car ls))]
 | 
			
		||||
                          [(m* x**) (f* (cdr ls))])
 | 
			
		||||
               (values (cons m m*) (cons x* x**)))]))
 | 
			
		||||
        (define (f x)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(integer? x) (values x (list x))]
 | 
			
		||||
            [else
 | 
			
		||||
             (let ([tag (car x)] [ls (cdr x)])
 | 
			
		||||
               (let-values ([(m* x**) (f* ls)])
 | 
			
		||||
                 (case tag
 | 
			
		||||
                   [(exclusive) (exclusive* m* x**)]
 | 
			
		||||
                   [(inclusive) (inclusive* m* x**)]
 | 
			
		||||
                   [else (error 'f "invalid")])))]))
 | 
			
		||||
        (let-values ([(m ls) (f x)])
 | 
			
		||||
          ls))
 | 
			
		||||
      (define (expand-names alist)
 | 
			
		||||
        (lambda (n)
 | 
			
		||||
          (let f ([alist alist])
 | 
			
		||||
            (cond
 | 
			
		||||
              [(null? alist) '()]
 | 
			
		||||
              [(zero? (bitwise-and n (cdar alist)))
 | 
			
		||||
               (f (cdr alist))]
 | 
			
		||||
              [else 
 | 
			
		||||
               (cons (caar alist) (f (cdr alist)))]))))
 | 
			
		||||
      (define (extend-alist* ls alist)
 | 
			
		||||
        (define (extend-alist x alist)
 | 
			
		||||
          (define (lookup x)
 | 
			
		||||
            (cond
 | 
			
		||||
              [(assq x alist) => cdr]
 | 
			
		||||
              [else (error 'lookup "cannot find" x alist)]))
 | 
			
		||||
          (let ([name (car x)] [info (cadr x)])
 | 
			
		||||
            (let ([tag (car info)] [x* (map lookup (cdr info))])
 | 
			
		||||
              (case tag
 | 
			
		||||
                [(exclusive) 
 | 
			
		||||
                 (cons (cons name (apply bitwise-ior x*)) alist)]
 | 
			
		||||
                [(inclusive)
 | 
			
		||||
                 (assert (= (apply bitwise-ior x*) (apply bitwise-and x*)))
 | 
			
		||||
                 (cons (cons name (apply bitwise-ior x*)) alist)]
 | 
			
		||||
                [else (assert #f)]))))
 | 
			
		||||
        (cond
 | 
			
		||||
          [(null? ls) alist]
 | 
			
		||||
          [else
 | 
			
		||||
           (extend-alist (car ls)
 | 
			
		||||
             (extend-alist* (cdr ls) alist))]))
 | 
			
		||||
      (let* ([names (difference (collect-names ls) (map car ls))]
 | 
			
		||||
             [names-alist (map cons names (enumerate names))])
 | 
			
		||||
        (let* ([expanded (expand main ls)]
 | 
			
		||||
               [renamed (rename names-alist expanded)])
 | 
			
		||||
          (let* ([unique* (list-sort < (unique-elements renamed))]
 | 
			
		||||
                 [canonicals (map (expand-names names-alist) unique*)])
 | 
			
		||||
            (let* ([canonical-alist (map cons canonicals (enumerate canonicals))]
 | 
			
		||||
                   [seed-alist
 | 
			
		||||
                    (map 
 | 
			
		||||
                      (lambda (x) 
 | 
			
		||||
                        (let ([ls (filter (lambda (y) (memq x (car y))) canonical-alist)])
 | 
			
		||||
                          (cons x (apply bitwise-ior (map cdr ls)))))
 | 
			
		||||
                      names)])
 | 
			
		||||
              (extend-alist* ls seed-alist))))))
 | 
			
		||||
    (define (property-names ls)
 | 
			
		||||
      (cond
 | 
			
		||||
        [(null? ls) '()]
 | 
			
		||||
        [else
 | 
			
		||||
         (let ([fst (car ls)] [rest (property-names (cdr ls))])
 | 
			
		||||
           (let ([name (car fst)] [info (cadr fst)])
 | 
			
		||||
             (case (car info)
 | 
			
		||||
               [(exclusive) rest]
 | 
			
		||||
               [(inclusive) (append (cdr info) rest)]
 | 
			
		||||
               [else (assert #f)])))]))
 | 
			
		||||
    (define (generate-base-cases T main ls)
 | 
			
		||||
      (define (value-name x)
 | 
			
		||||
        (datum->syntax T
 | 
			
		||||
          (string->symbol
 | 
			
		||||
            (string-append 
 | 
			
		||||
              (symbol->string (syntax->datum T))
 | 
			
		||||
              ":" 
 | 
			
		||||
              (symbol->string x)))))
 | 
			
		||||
      (define (predicate-name x)
 | 
			
		||||
        (datum->syntax T
 | 
			
		||||
          (string->symbol
 | 
			
		||||
            (string-append 
 | 
			
		||||
              (symbol->string (syntax->datum T))
 | 
			
		||||
              ":" 
 | 
			
		||||
              (symbol->string x)
 | 
			
		||||
              "?"))))
 | 
			
		||||
      (let ([maind (syntax->datum main)] [lsd (syntax->datum ls)])
 | 
			
		||||
        (let ([alist (make-ontology maind lsd)]
 | 
			
		||||
              [pnames (property-names lsd)])
 | 
			
		||||
          (let ([alist (remp (lambda (x) (memq (car x) pnames)) alist)])
 | 
			
		||||
            (map 
 | 
			
		||||
              (lambda (x) (list (value-name (car x))
 | 
			
		||||
                                (predicate-name (car x))
 | 
			
		||||
                                (cdr x)))
 | 
			
		||||
              alist)))))
 | 
			
		||||
    (syntax-case x ()
 | 
			
		||||
      [(_ T T:description T? T:=? T:and T:or [name cls] [name* cls*] ...)
 | 
			
		||||
       (with-syntax ([((name* predname* val*) ...)
 | 
			
		||||
                      (generate-base-cases #'T #'name
 | 
			
		||||
                        #'([name cls] [name* cls*] ...))])
 | 
			
		||||
         #'(begin
 | 
			
		||||
             (define-record-type (T make-T T?)
 | 
			
		||||
               (sealed     #t)
 | 
			
		||||
               (fields (immutable n T-n)))
 | 
			
		||||
             (define (T:and x0 x1)
 | 
			
		||||
               (make-T (bitwise-and (T-n x0) (T-n x1))))
 | 
			
		||||
             (define (T:or x0 x1)
 | 
			
		||||
               (make-T (bitwise-ior (T-n x0) (T-n x1))))
 | 
			
		||||
             (define (test x v)
 | 
			
		||||
               (let ([bits (bitwise-and x v)])
 | 
			
		||||
                 (cond
 | 
			
		||||
                   [(= 0 (bitwise-and x v))  'no]
 | 
			
		||||
                   [(= v (bitwise-ior x v)) 'yes]
 | 
			
		||||
                   [else                  'maybe])))
 | 
			
		||||
             (define name* (make-T val*)) ...
 | 
			
		||||
             (define (predname* x) (test (T-n x) val*)) ...
 | 
			
		||||
             (define (T:description x)
 | 
			
		||||
               (let* ([ls '()]
 | 
			
		||||
                      [ls
 | 
			
		||||
                       (case (predname* x)
 | 
			
		||||
                         [(yes) (cons '(name* yes) ls)]
 | 
			
		||||
                         [else  ls])]
 | 
			
		||||
                      ...)
 | 
			
		||||
                 ls))
 | 
			
		||||
             (define (T:=? x y)
 | 
			
		||||
               (= (T-n x) (T-n y)))
 | 
			
		||||
             ))])))
 | 
			
		||||
 | 
			
		||||
(define-ontology T T:description T? T=? T:and T:or
 | 
			
		||||
  [object        (inclusive obj-tag obj-immediacy obj-truth)]
 | 
			
		||||
  [obj-immediacy (exclusive nonimmediate immediate)]
 | 
			
		||||
  [immediate     (exclusive fixnum boolean null char void)]
 | 
			
		||||
  [obj-truth     (exclusive false non-false)]
 | 
			
		||||
  [obj-tag       (exclusive procedure string vector pair null
 | 
			
		||||
                            boolean char number void other-object)]
 | 
			
		||||
  [boolean       (exclusive true false)]
 | 
			
		||||
  [number        (inclusive number-tag number-size number-exactness)]
 | 
			
		||||
  [number-size   (exclusive negative zero positive)]
 | 
			
		||||
  [number-tag    (exclusive fixnum flonum other-number)]
 | 
			
		||||
  [number-exactness (exclusive exact inexact)]
 | 
			
		||||
  [exact         (exclusive fixnum other-exact)]
 | 
			
		||||
  [inexact       (exclusive flonum other-inexact)]
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
#!eof
 | 
			
		||||
 | 
			
		||||
(define (do-test expr result expected)
 | 
			
		||||
  (if (equal? result expected)
 | 
			
		||||
      (printf "OK: ~s -> ~s\n" expr expected)
 | 
			
		||||
      (error 'test "failed/got/expected" expr result expected)))
 | 
			
		||||
 | 
			
		||||
(define-syntax test
 | 
			
		||||
  (syntax-rules ()
 | 
			
		||||
    [(_ expr expected) (do-test 'expr expr 'expected)]))
 | 
			
		||||
 | 
			
		||||
(test (T:object? T:object) yes)
 | 
			
		||||
(test (T:object? T:true)   yes)
 | 
			
		||||
(test (T:true? T:object)   maybe)
 | 
			
		||||
(test (T:true? T:true)     yes)
 | 
			
		||||
(test (T:true? T:false)    no)
 | 
			
		||||
(test (T:true? T:null)     no)
 | 
			
		||||
(test (T:non-false? T:true) yes)
 | 
			
		||||
(test (T:non-false? T:null) yes)
 | 
			
		||||
(test (T:non-false? T:false) no)
 | 
			
		||||
(test (T:non-false? T:boolean) maybe)
 | 
			
		||||
(test (T:non-false? T:object) maybe)
 | 
			
		||||
(test (T:boolean? T:true) yes)
 | 
			
		||||
(test (T:boolean? T:false) yes)
 | 
			
		||||
(test (T:boolean? (T:or T:true T:false)) yes)
 | 
			
		||||
(test (T:boolean? (T:and T:true T:false)) no)
 | 
			
		||||
(test (T:object? (T:and T:true T:false)) no)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
1526
 | 
			
		||||
1527
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
(import (except (ikarus) 
 | 
			
		||||
          assembler-output optimize-cp optimize-level
 | 
			
		||||
          cp0-size-limit cp0-effort-limit expand/optimize
 | 
			
		||||
          optimizer-output))
 | 
			
		||||
          optimizer-output tag-analysis-output perform-tag-analysis))
 | 
			
		||||
(import (ikarus.compiler))
 | 
			
		||||
(import (except (psyntax system $bootstrap)
 | 
			
		||||
                eval-core 
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
                compile-core-expr-to-port))
 | 
			
		||||
(import (ikarus.compiler)) ; just for fun
 | 
			
		||||
(optimize-level 2)
 | 
			
		||||
(perform-tag-analysis #t)
 | 
			
		||||
(pretty-width 160)
 | 
			
		||||
((pretty-format 'fix) ((pretty-format 'letrec)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1414,8 +1415,6 @@
 | 
			
		|||
    [&no-nans-rcd]
 | 
			
		||||
    [&interrupted-rtd]
 | 
			
		||||
    [&interrupted-rcd]
 | 
			
		||||
    [&i/o-would-block-rtd]
 | 
			
		||||
    [&i/o-would-block-rcd]
 | 
			
		||||
    [tcp-connect                      i]
 | 
			
		||||
    [udp-connect                      i]
 | 
			
		||||
    [tcp-connect-nonblocking          i]
 | 
			
		||||
| 
						 | 
				
			
			@ -1429,15 +1428,13 @@
 | 
			
		|||
    [input-socket-buffer-size         i]
 | 
			
		||||
    [output-socket-buffer-size        i]
 | 
			
		||||
 | 
			
		||||
    ;[&i/o-would-block                 i]
 | 
			
		||||
    ;[make-i/o-would-block-condition   i]
 | 
			
		||||
    ;[i/o-would-block-condition?       i]
 | 
			
		||||
    ;[i/o-would-block-port             i]
 | 
			
		||||
    [ellipsis-map ]
 | 
			
		||||
    [optimize-cp i]
 | 
			
		||||
    [optimize-level i]
 | 
			
		||||
    [cp0-size-limit i]
 | 
			
		||||
    [cp0-effort-limit i]
 | 
			
		||||
    [tag-analysis-output i]
 | 
			
		||||
    [perform-tag-analysis i]
 | 
			
		||||
  ))
 | 
			
		||||
 | 
			
		||||
(define (macro-identifier? x) 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,11 +39,6 @@
 | 
			
		|||
    (tag-test (prm 'mref x (K (- ptag))) smask stag)
 | 
			
		||||
    (make-constant #f)))
 | 
			
		||||
 | 
			
		||||
(define (safe-ref x disp mask tag)
 | 
			
		||||
  (seq*
 | 
			
		||||
    (interrupt-unless (tag-test x mask tag))
 | 
			
		||||
    (prm 'mref x (K (- disp tag)))))
 | 
			
		||||
 | 
			
		||||
(define (dirty-vector-set address)
 | 
			
		||||
  (define shift-bits 2)
 | 
			
		||||
  (prm 'mset 
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +54,14 @@
 | 
			
		|||
     (if (or (fixnum? t) (immediate? t))
 | 
			
		||||
         (prm 'nop)
 | 
			
		||||
         (dirty-vector-set addr))]
 | 
			
		||||
    [(known x t)
 | 
			
		||||
     (cond
 | 
			
		||||
       [(eq? (T:immediate? t) 'yes)
 | 
			
		||||
        (record-optimization 'smart-dirty-vec t)
 | 
			
		||||
        (nop)]
 | 
			
		||||
       [else (smart-dirty-vector-set addr x)])]
 | 
			
		||||
    [else (dirty-vector-set addr)]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define (slow-mem-assign v x i)
 | 
			
		||||
  (with-tmp ([t (prm 'int+ x (K i))])
 | 
			
		||||
    (make-seq 
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +74,12 @@
 | 
			
		|||
     (if (or (fixnum? t) (immediate? t))
 | 
			
		||||
         (prm 'mset x (K i) (T v))
 | 
			
		||||
         (slow-mem-assign v x i))]
 | 
			
		||||
    [(known expr t)
 | 
			
		||||
     (cond
 | 
			
		||||
       [(eq? (T:immediate? t) 'yes)
 | 
			
		||||
        (record-optimization 'mem-assign v)
 | 
			
		||||
        (prm 'mset x (K i) (T expr))]
 | 
			
		||||
       [else (slow-mem-assign expr x i)])]
 | 
			
		||||
    [else (slow-mem-assign v x i)]))
 | 
			
		||||
 | 
			
		||||
(define (align-code unknown-amt known-amt)
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +117,7 @@
 | 
			
		|||
(define (equable-constant? x)
 | 
			
		||||
  (struct-case x 
 | 
			
		||||
    [(constant xv) (equable? xv)]
 | 
			
		||||
    [(known x t) (equable-constant? x)]
 | 
			
		||||
    [else #f]))
 | 
			
		||||
 | 
			
		||||
(define-primop eqv? safe
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +158,8 @@
 | 
			
		|||
  [(E x) (nop)])
 | 
			
		||||
 | 
			
		||||
(define-primop boolean? safe
 | 
			
		||||
  [(P x) (tag-test (T x) bool-mask bool-tag)]
 | 
			
		||||
  [(P x) 
 | 
			
		||||
   (tag-test (T x) bool-mask bool-tag)]
 | 
			
		||||
  [(E x) (nop)])
 | 
			
		||||
 | 
			
		||||
(define-primop bwp-object? safe
 | 
			
		||||
| 
						 | 
				
			
			@ -195,6 +203,8 @@
 | 
			
		|||
                  (prm '= x (T (K (car ls))))
 | 
			
		||||
                  (K #t)
 | 
			
		||||
                  (f (cdr ls)))])))])]
 | 
			
		||||
     [(known expr t) 
 | 
			
		||||
      (cogen-pred-$memq x expr)]
 | 
			
		||||
     [else (interrupt)])]
 | 
			
		||||
  [(V x ls)
 | 
			
		||||
   (struct-case ls
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +221,8 @@
 | 
			
		|||
                  (prm '= x (T (K (car ls))))
 | 
			
		||||
                  (T (K ls))
 | 
			
		||||
                  (f (cdr ls)))])))])]
 | 
			
		||||
     [(known expr t) 
 | 
			
		||||
      (cogen-value-$memq x expr)]
 | 
			
		||||
     [else (interrupt)])]
 | 
			
		||||
  [(E x ls) (nop)])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +235,7 @@
 | 
			
		|||
      (cond
 | 
			
		||||
        [(list? ls) (nop)]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [(known) (error 'translate "memq")]
 | 
			
		||||
     [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
(define (equable? x)
 | 
			
		||||
| 
						 | 
				
			
			@ -236,6 +249,7 @@
 | 
			
		|||
        [(and (list? lsv) (andmap equable? lsv))
 | 
			
		||||
         (cogen-value-$memq x ls)]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [(known) (error 'translate "memv")]
 | 
			
		||||
     [else (interrupt)])]
 | 
			
		||||
  [(P x ls) 
 | 
			
		||||
   (struct-case ls
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +258,7 @@
 | 
			
		|||
        [(and (list? lsv) (andmap equable? lsv))
 | 
			
		||||
         (cogen-pred-$memq x ls)]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [(known) (error 'translate "memv")]
 | 
			
		||||
     [else (interrupt)])]
 | 
			
		||||
  [(E x ls)
 | 
			
		||||
   (struct-case ls
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +266,7 @@
 | 
			
		|||
      (cond
 | 
			
		||||
        [(list? lsv) (nop)]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [(known) (error 'translate "memv")]
 | 
			
		||||
     [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
/section)
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +274,8 @@
 | 
			
		|||
(section ;;; pairs 
 | 
			
		||||
 | 
			
		||||
(define-primop pair? safe
 | 
			
		||||
  [(P x) (tag-test (T x) pair-mask pair-tag)]
 | 
			
		||||
  [(P x)
 | 
			
		||||
   (tag-test (T x) pair-mask pair-tag)]
 | 
			
		||||
  [(E x) (nop)])
 | 
			
		||||
 | 
			
		||||
(define-primop cons safe
 | 
			
		||||
| 
						 | 
				
			
			@ -290,29 +307,41 @@
 | 
			
		|||
     (prm 'mset x (K (- disp-cdr pair-tag)) (T v))
 | 
			
		||||
     (smart-dirty-vector-set x v))])
 | 
			
		||||
 | 
			
		||||
(define (assert-pair x)
 | 
			
		||||
  (struct-case x
 | 
			
		||||
    [(known x t)
 | 
			
		||||
     (case (T:pair? t)
 | 
			
		||||
       [(yes) (record-optimization 'assert-pair x) (nop)]
 | 
			
		||||
       [(no)  (interrupt)]
 | 
			
		||||
       [else  (assert-pair x)])]
 | 
			
		||||
    [else
 | 
			
		||||
     (interrupt-unless (tag-test x pair-mask pair-tag))]))
 | 
			
		||||
 | 
			
		||||
(define-primop car safe
 | 
			
		||||
  [(V x)
 | 
			
		||||
   (safe-ref (T x) disp-car pair-mask pair-tag)]
 | 
			
		||||
  [(E x)
 | 
			
		||||
   (interrupt-unless (tag-test (T x) pair-mask pair-tag))])
 | 
			
		||||
   (with-tmp ([x (T x)])
 | 
			
		||||
     (assert-pair x)
 | 
			
		||||
     (prm 'mref x (K (- disp-car pair-tag))))]
 | 
			
		||||
  [(E x) (assert-pair (T x))])
 | 
			
		||||
 | 
			
		||||
(define-primop cdr safe
 | 
			
		||||
  [(V x)
 | 
			
		||||
   (safe-ref (T x) disp-cdr pair-mask pair-tag)]
 | 
			
		||||
  [(E x)
 | 
			
		||||
   (interrupt-unless (tag-test (T x) pair-mask pair-tag))])
 | 
			
		||||
   (with-tmp ([x (T x)])
 | 
			
		||||
     (assert-pair x)
 | 
			
		||||
     (prm 'mref x (K (- disp-cdr pair-tag))))]
 | 
			
		||||
  [(E x) (assert-pair (T x))])
 | 
			
		||||
 | 
			
		||||
(define-primop set-car! safe
 | 
			
		||||
  [(E x v)
 | 
			
		||||
   (with-tmp ([x (T x)])
 | 
			
		||||
     (interrupt-unless (tag-test x pair-mask pair-tag))
 | 
			
		||||
     (assert-pair x)
 | 
			
		||||
     (prm 'mset x (K (- disp-car pair-tag)) (T v))
 | 
			
		||||
     (smart-dirty-vector-set x v))])
 | 
			
		||||
 | 
			
		||||
(define-primop set-cdr! safe
 | 
			
		||||
  [(E x v)
 | 
			
		||||
   (with-tmp ([x (T x)])
 | 
			
		||||
     (interrupt-unless (tag-test x pair-mask pair-tag))
 | 
			
		||||
     (assert-pair x)
 | 
			
		||||
     (prm 'mset x (K (- disp-cdr pair-tag)) (T v))
 | 
			
		||||
     (smart-dirty-vector-set x v))])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +351,7 @@
 | 
			
		|||
    [(null? ls) (T val)]
 | 
			
		||||
    [else 
 | 
			
		||||
     (with-tmp ([x (expand-cxr val (cdr ls))]) 
 | 
			
		||||
       (interrupt-unless (tag-test x pair-mask pair-tag))
 | 
			
		||||
       (assert-pair x)
 | 
			
		||||
       (prm 'mref x 
 | 
			
		||||
          (case (car ls) 
 | 
			
		||||
            [(a)  (K (- disp-car pair-tag))]
 | 
			
		||||
| 
						 | 
				
			
			@ -408,11 +437,12 @@
 | 
			
		|||
(section ;;; vectors
 | 
			
		||||
  (section ;;; helpers
 | 
			
		||||
    (define (vector-range-check x idx)
 | 
			
		||||
      (define (check-fx i)
 | 
			
		||||
      (define (check-non-vector x idx)
 | 
			
		||||
        (define (check-fx idx)
 | 
			
		||||
          (seq*
 | 
			
		||||
             (interrupt-unless (tag-test (T x) vector-mask vector-tag))
 | 
			
		||||
             (with-tmp ([len (cogen-value-$vector-length x)])
 | 
			
		||||
             (interrupt-unless (prm 'u< (K (* i wordsize)) len))
 | 
			
		||||
               (interrupt-unless (prm 'u< (T idx) len))
 | 
			
		||||
               (interrupt-unless-fixnum len))))
 | 
			
		||||
        (define (check-? idx)
 | 
			
		||||
          (seq*
 | 
			
		||||
| 
						 | 
				
			
			@ -424,9 +454,43 @@
 | 
			
		|||
        (struct-case idx
 | 
			
		||||
          [(constant i)
 | 
			
		||||
           (if (and (fixnum? i) (fx>= i 0)) 
 | 
			
		||||
             (check-fx i)
 | 
			
		||||
               (check-fx idx)
 | 
			
		||||
               (check-? idx))]
 | 
			
		||||
          [(known idx idx-t)
 | 
			
		||||
           (case (T:fixnum? idx-t)
 | 
			
		||||
             [(yes) (check-fx idx)]
 | 
			
		||||
             [(maybe) (vector-range-check x idx)]
 | 
			
		||||
             [else
 | 
			
		||||
              (printf "vector check with mismatch index tag ~s" idx-t)
 | 
			
		||||
              (vector-range-check x idx)])]
 | 
			
		||||
          [else (check-? idx)]))
 | 
			
		||||
      (define (check-vector x idx)
 | 
			
		||||
        (define (check-fx idx)
 | 
			
		||||
          (with-tmp ([len (cogen-value-$vector-length x)])
 | 
			
		||||
            (interrupt-unless (prm 'u< (T idx) len))))
 | 
			
		||||
        (define (check-? idx)
 | 
			
		||||
          (seq*
 | 
			
		||||
            (interrupt-unless-fixnum (T idx)) 
 | 
			
		||||
            (with-tmp ([len (cogen-value-$vector-length x)])
 | 
			
		||||
              (interrupt-unless (prm 'u< (T idx) len)))))
 | 
			
		||||
        (struct-case idx
 | 
			
		||||
          [(constant i)
 | 
			
		||||
           (if (and (fixnum? i) (fx>= i 0)) 
 | 
			
		||||
               (check-fx idx)
 | 
			
		||||
               (check-? idx))]
 | 
			
		||||
          [(known idx idx-t)
 | 
			
		||||
           (case (T:fixnum? idx-t)
 | 
			
		||||
             [(yes) (check-fx idx)]
 | 
			
		||||
             [(no)  (interrupt)]
 | 
			
		||||
             [else  (check-vector x idx)])]
 | 
			
		||||
          [else (check-? idx)])) 
 | 
			
		||||
      (struct-case x
 | 
			
		||||
        [(known x t)
 | 
			
		||||
         (case (T:vector? t)
 | 
			
		||||
           [(yes) (record-optimization 'check-vector x) (check-vector x idx)]
 | 
			
		||||
           [(no) (interrupt)]
 | 
			
		||||
           [else (check-non-vector x idx)])]
 | 
			
		||||
        [else (check-non-vector x idx)]))
 | 
			
		||||
    /section)
 | 
			
		||||
 | 
			
		||||
(define-primop vector? unsafe
 | 
			
		||||
| 
						 | 
				
			
			@ -437,14 +501,17 @@
 | 
			
		|||
  [(V len)
 | 
			
		||||
   (struct-case len
 | 
			
		||||
     [(constant i)
 | 
			
		||||
      (unless (fixnum? i) (interrupt))
 | 
			
		||||
      (if (fixnum? i)
 | 
			
		||||
          (interrupt)
 | 
			
		||||
          (with-tmp ([v (prm 'alloc
 | 
			
		||||
                            (K (align (+ (* i wordsize) disp-vector-data)))
 | 
			
		||||
                            (K vector-tag))])
 | 
			
		||||
              (prm 'mset v 
 | 
			
		||||
                   (K (- disp-vector-length vector-tag))
 | 
			
		||||
                   (K (* i fx-scale)))
 | 
			
		||||
          v)]
 | 
			
		||||
              v))]
 | 
			
		||||
     [(known expr t)
 | 
			
		||||
      (cogen-value-$make-vector expr)]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([alen (align-code (T len) disp-vector-data)])
 | 
			
		||||
        (with-tmp ([v (prm 'alloc alen (K vector-tag))])
 | 
			
		||||
| 
						 | 
				
			
			@ -459,8 +526,6 @@
 | 
			
		|||
      (interrupt-when (prm '= x (K 0)))
 | 
			
		||||
      x)])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop $vector-ref unsafe
 | 
			
		||||
  [(V x i)
 | 
			
		||||
   (or 
 | 
			
		||||
| 
						 | 
				
			
			@ -470,6 +535,8 @@
 | 
			
		|||
             (fx>= i 0)
 | 
			
		||||
             (prm 'mref (T x) 
 | 
			
		||||
                  (K (+ (* i wordsize) (- disp-vector-data vector-tag)))))]
 | 
			
		||||
       [(known i t)
 | 
			
		||||
        (cogen-value-$vector-ref x i)]
 | 
			
		||||
       [else #f])
 | 
			
		||||
     (prm 'mref (T x) 
 | 
			
		||||
        (prm 'int+ (T i) (K (- disp-vector-data vector-tag)))))]
 | 
			
		||||
| 
						 | 
				
			
			@ -482,16 +549,30 @@
 | 
			
		|||
 | 
			
		||||
(define-primop vector-length safe
 | 
			
		||||
  [(V x)
 | 
			
		||||
   (struct-case x
 | 
			
		||||
     [(known x t)
 | 
			
		||||
      (case (T:vector? t)
 | 
			
		||||
        [(yes) (record-optimization 'vector-length x) (cogen-value-$vector-length x)]
 | 
			
		||||
        [(no)  (interrupt)]
 | 
			
		||||
        [else  (cogen-value-vector-length x)])]
 | 
			
		||||
     [else
 | 
			
		||||
      (seq*
 | 
			
		||||
        (interrupt-unless (tag-test (T x) vector-mask vector-tag))
 | 
			
		||||
        (with-tmp ([t (cogen-value-$vector-length x)])
 | 
			
		||||
          (interrupt-unless-fixnum t)
 | 
			
		||||
       t))]
 | 
			
		||||
          t))])]
 | 
			
		||||
  [(E x)
 | 
			
		||||
   (struct-case x
 | 
			
		||||
     [(known x t)
 | 
			
		||||
      (case (T:vector? t)
 | 
			
		||||
        [(yes) (record-optimization 'vector-length x) (nop)]
 | 
			
		||||
        [(no)  (interrupt)]
 | 
			
		||||
        [else  (cogen-effect-vector-length x)])]
 | 
			
		||||
     [else
 | 
			
		||||
      (seq*
 | 
			
		||||
        (interrupt-unless (tag-test (T x) vector-mask vector-tag))
 | 
			
		||||
        (with-tmp ([t (cogen-value-$vector-length x)])
 | 
			
		||||
       (interrupt-unless-fixnum t)))]
 | 
			
		||||
          (interrupt-unless-fixnum t)))])]
 | 
			
		||||
  [(P x) 
 | 
			
		||||
   (seq* (cogen-effect-vector-length x) (K #t))])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -512,6 +593,8 @@
 | 
			
		|||
      (mem-assign v (T x) 
 | 
			
		||||
         (+ (* i wordsize)
 | 
			
		||||
            (- disp-vector-data vector-tag)))]
 | 
			
		||||
     [(known i t)
 | 
			
		||||
      (cogen-effect-$vector-set! x i v)]
 | 
			
		||||
     [else
 | 
			
		||||
      (mem-assign v 
 | 
			
		||||
         (prm 'int+ (T x) (T i))
 | 
			
		||||
| 
						 | 
				
			
			@ -558,6 +641,7 @@
 | 
			
		|||
      (prm 'mref (T x)
 | 
			
		||||
         (K (+ (- disp-closure-data closure-tag)
 | 
			
		||||
               (* i wordsize))))]
 | 
			
		||||
     [(known) (error 'translate "$cpref")]
 | 
			
		||||
     [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
/section)
 | 
			
		||||
| 
						 | 
				
			
			@ -635,6 +719,7 @@
 | 
			
		|||
            (interrupt-when (cogen-pred-$unbound-object? v))
 | 
			
		||||
            v)
 | 
			
		||||
          (interrupt))]
 | 
			
		||||
     [(known) (error 'translate "top-level-value")]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([x (T x)])
 | 
			
		||||
        (interrupt-unless (cogen-pred-symbol? x))
 | 
			
		||||
| 
						 | 
				
			
			@ -648,6 +733,7 @@
 | 
			
		|||
          (with-tmp ([v (cogen-value-$symbol-value x)])
 | 
			
		||||
            (interrupt-when (cogen-pred-$unbound-object? v)))
 | 
			
		||||
          (interrupt))]
 | 
			
		||||
     [(known) (error 'translate "top-level-value")]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([x (T x)])
 | 
			
		||||
        (interrupt-unless (cogen-pred-symbol? x))
 | 
			
		||||
| 
						 | 
				
			
			@ -659,7 +745,6 @@
 | 
			
		|||
  [(E x v)
 | 
			
		||||
   (with-tmp ([x (T x)] [v (T v)])
 | 
			
		||||
     (prm 'mset x (K (- disp-symbol-record-proc symbol-ptag)) v)
 | 
			
		||||
     ;(prm 'mset x (K (- disp-symbol-error-function symbol-tag)) v)
 | 
			
		||||
     (dirty-vector-set x))])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -737,11 +822,13 @@
 | 
			
		|||
    [(constant a)
 | 
			
		||||
     (unless (fixnum? a) (interrupt))
 | 
			
		||||
     (prm 'int* (T b) (K a))]
 | 
			
		||||
    [(known a t) (cogen-value-$fx* a b)]
 | 
			
		||||
    [else
 | 
			
		||||
     (struct-case b
 | 
			
		||||
       [(constant b)
 | 
			
		||||
        (unless (fixnum? b) (interrupt))
 | 
			
		||||
        (prm 'int* (T a) (K b))]
 | 
			
		||||
       [(known b t) (cogen-value-$fx* a b)]
 | 
			
		||||
       [else
 | 
			
		||||
        (prm 'int* (T a) (prm 'sra (T b) (K fx-shift)))])])]
 | 
			
		||||
  [(P x y) (K #t)]
 | 
			
		||||
| 
						 | 
				
			
			@ -778,6 +865,7 @@
 | 
			
		|||
     [(constant i) 
 | 
			
		||||
      (unless (fixnum? i) (interrupt))
 | 
			
		||||
      (prm 'sll (T x) (K i))]
 | 
			
		||||
     [(known i t) (cogen-value-$fxsll x i)]
 | 
			
		||||
     [else 
 | 
			
		||||
      (prm 'sll (T x) (prm 'sra (T i) (K fx-shift)))])]
 | 
			
		||||
  [(P x i) (K #t)]
 | 
			
		||||
| 
						 | 
				
			
			@ -791,6 +879,7 @@
 | 
			
		|||
      (prm 'logand 
 | 
			
		||||
           (prm 'sra (T x) (K (if (> i 31) 31 i)))
 | 
			
		||||
           (K (* -1 fx-scale)))]
 | 
			
		||||
     [(known i t) (cogen-value-$fxsra x i)]
 | 
			
		||||
     [else 
 | 
			
		||||
      (with-tmp ([i (prm 'sra (T i) (K fx-shift))])
 | 
			
		||||
        (with-tmp ([i (make-conditional
 | 
			
		||||
| 
						 | 
				
			
			@ -880,6 +969,7 @@
 | 
			
		|||
             (K (+ i (- disp-bignum-data record-tag))))
 | 
			
		||||
           (K 255))
 | 
			
		||||
        (K fx-shift))]
 | 
			
		||||
     [(known i t) (cogen-value-$bignum-byte-ref s i)]
 | 
			
		||||
     [else
 | 
			
		||||
      (prm 'sll
 | 
			
		||||
        (prm 'srl ;;; FIXME: bref
 | 
			
		||||
| 
						 | 
				
			
			@ -950,6 +1040,7 @@
 | 
			
		|||
             (K (+ (- 7 i) (- disp-flonum-data record-tag))))
 | 
			
		||||
           (K 255))
 | 
			
		||||
        (K fx-shift))]
 | 
			
		||||
     [(known) (error 'translate "$flonum-u8-ref")]
 | 
			
		||||
     [else (interrupt)])]
 | 
			
		||||
  [(P s i) (K #t)]
 | 
			
		||||
  [(E s i) (nop)])
 | 
			
		||||
| 
						 | 
				
			
			@ -971,6 +1062,7 @@
 | 
			
		|||
      (prm 'bset/h (T x)
 | 
			
		||||
         (K (+ (- 7 i) (- disp-flonum-data vector-tag)))
 | 
			
		||||
            (prm 'sll (T v) (K (- 8 fx-shift))))]
 | 
			
		||||
     [(known) (error 'translate "$flonum-set!")]
 | 
			
		||||
     [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
(define-primop $fixnum->flonum unsafe
 | 
			
		||||
| 
						 | 
				
			
			@ -992,6 +1084,13 @@
 | 
			
		|||
        (if (flonum? v) 
 | 
			
		||||
            (check-flonums (cdr ls) code)
 | 
			
		||||
            (interrupt))]
 | 
			
		||||
       [(known x t)
 | 
			
		||||
        (case (T:flonum? t)
 | 
			
		||||
          [(yes)
 | 
			
		||||
           (record-optimization 'check-flonum x)
 | 
			
		||||
           (check-flonums (cdr ls) code)]
 | 
			
		||||
          [(no) (interrupt)]
 | 
			
		||||
          [else (check-flonums (cons x (cdr ls)) code)])]
 | 
			
		||||
       [else
 | 
			
		||||
        (check-flonums (cdr ls) 
 | 
			
		||||
          (with-tmp ([x (T (car ls))])
 | 
			
		||||
| 
						 | 
				
			
			@ -1188,31 +1287,36 @@
 | 
			
		|||
 | 
			
		||||
(section ;;; generic arithmetic
 | 
			
		||||
 | 
			
		||||
(define (non-fixnum? x)
 | 
			
		||||
  (struct-case x
 | 
			
		||||
    [(constant i) (not (fixnum? i))]
 | 
			
		||||
    [else #f]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define (assert-fixnums a a*)
 | 
			
		||||
  (define (or* a a*)
 | 
			
		||||
    (cond
 | 
			
		||||
      [(null? a*) a]
 | 
			
		||||
    [(constant? (car a*)) (or* a (cdr a*))]
 | 
			
		||||
      [else (or* (prm 'logor a (T (car a*))) (cdr a*))]))
 | 
			
		||||
 | 
			
		||||
(define (assert-fixnums a a*)
 | 
			
		||||
  (define (known-fixnum? x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant i) (fixnum? i)]
 | 
			
		||||
      [(known x t) 
 | 
			
		||||
       (case (T:fixnum? t)
 | 
			
		||||
         [(yes) (record-optimization 'assert-fixnum x) #t]
 | 
			
		||||
         [else  #f])]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (define (known-non-fixnum? x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant i) (not (fixnum? i))]
 | 
			
		||||
      [(known x t) (eq? (T:fixnum? t) 'no)]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (let-values ([(fx* others) (partition known-fixnum? (cons a a*))])
 | 
			
		||||
    (let-values ([(nfx* others) (partition known-non-fixnum?  others)])
 | 
			
		||||
      (cond
 | 
			
		||||
    [(constant? a) 
 | 
			
		||||
     (if (null? a*) 
 | 
			
		||||
         (nop)
 | 
			
		||||
         (assert-fixnums (car a*) (cdr a*)))]
 | 
			
		||||
        [(not (null? nfx*)) (interrupt)]
 | 
			
		||||
        [(null? others)     (nop)]
 | 
			
		||||
        [else
 | 
			
		||||
         (interrupt-unless 
 | 
			
		||||
       (tag-test (or* (T a) a*) fx-mask fx-tag))]))
 | 
			
		||||
           (tag-test (or* (T (car others)) (cdr others)) fx-mask fx-tag))]))))
 | 
			
		||||
 | 
			
		||||
(define (fixnum-fold-p op a a*)
 | 
			
		||||
  (cond
 | 
			
		||||
    [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)]
 | 
			
		||||
    [else
 | 
			
		||||
  (seq*
 | 
			
		||||
    (assert-fixnums a a*)
 | 
			
		||||
    (let f ([a a] [a* a*])
 | 
			
		||||
| 
						 | 
				
			
			@ -1223,56 +1327,45 @@
 | 
			
		|||
           (make-conditional
 | 
			
		||||
             (prm op (T a) (T b))
 | 
			
		||||
             (f b (cdr a*))
 | 
			
		||||
                (K #f)))])))]))
 | 
			
		||||
 | 
			
		||||
(define (fixnum-fold-e a a*)
 | 
			
		||||
  (cond
 | 
			
		||||
    [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)]
 | 
			
		||||
    [else (assert-fixnums a a*)]))
 | 
			
		||||
             (K #f)))]))))
 | 
			
		||||
 | 
			
		||||
(define-primop = safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (fixnum-fold-p '= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (fixnum-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop < safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (fixnum-fold-p '< a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (fixnum-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop <= safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (fixnum-fold-p '<= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (fixnum-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop > safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (fixnum-fold-p '> a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (fixnum-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop >= safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (fixnum-fold-p '>= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (fixnum-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop - safe
 | 
			
		||||
  [(V a) 
 | 
			
		||||
   (cond
 | 
			
		||||
     [(non-fixnum? a) (interrupt)]
 | 
			
		||||
     [else
 | 
			
		||||
   (interrupt)
 | 
			
		||||
   (seq*
 | 
			
		||||
     (assert-fixnums a '())
 | 
			
		||||
        (prm 'int-/overflow (K 0) (T a)))])]
 | 
			
		||||
     (prm 'int-/overflow (K 0) (T a)))]
 | 
			
		||||
  [(V a . a*)
 | 
			
		||||
   (cond
 | 
			
		||||
     [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)]
 | 
			
		||||
     [else
 | 
			
		||||
   (interrupt)
 | 
			
		||||
   (seq*
 | 
			
		||||
     (assert-fixnums a a*)
 | 
			
		||||
| 
						 | 
				
			
			@ -1280,16 +1373,13 @@
 | 
			
		|||
       (cond
 | 
			
		||||
         [(null? a*) a]
 | 
			
		||||
         [else
 | 
			
		||||
             (f (prm 'int-/overflow a (T (car a*))) (cdr a*))])))])]
 | 
			
		||||
          (f (prm 'int-/overflow a (T (car a*))) (cdr a*))])))]
 | 
			
		||||
  [(P a . a*) (seq* (assert-fixnums a a*) (K #t))]
 | 
			
		||||
  [(E a . a*) (assert-fixnums a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop + safe
 | 
			
		||||
  [(V) (K 0)]
 | 
			
		||||
  [(V a . a*)
 | 
			
		||||
   (cond
 | 
			
		||||
     [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)]
 | 
			
		||||
     [else
 | 
			
		||||
   (interrupt)
 | 
			
		||||
   (seq*
 | 
			
		||||
     (assert-fixnums a a*)
 | 
			
		||||
| 
						 | 
				
			
			@ -1297,7 +1387,7 @@
 | 
			
		|||
       (cond
 | 
			
		||||
         [(null? a*) a]
 | 
			
		||||
         [else
 | 
			
		||||
             (f (prm 'int+/overflow a (T (car a*))) (cdr a*))])))])]
 | 
			
		||||
          (f (prm 'int+/overflow a (T (car a*))) (cdr a*))])))]
 | 
			
		||||
  [(P) (K #t)]
 | 
			
		||||
  [(P a . a*) (seq* (assert-fixnums a a*) (K #t))]
 | 
			
		||||
  [(E) (nop)]
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,27 +1404,34 @@
 | 
			
		|||
  [(V x) (cogen-value-+ x (K -1))])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop * safe
 | 
			
		||||
  [(V) (K (fxsll 1 fx-shift))]
 | 
			
		||||
  [(V a b) 
 | 
			
		||||
(define (cogen-binary-* a b)
 | 
			
		||||
  (define (cogen-*-non-constants a b)
 | 
			
		||||
    (interrupt)
 | 
			
		||||
    (with-tmp ([a (T a)] [b (T b)])
 | 
			
		||||
      (assert-fixnum a)
 | 
			
		||||
      (assert-fixnum b)
 | 
			
		||||
      (prm 'int*/overflow a 
 | 
			
		||||
        (prm 'sra b (K fx-shift)))))
 | 
			
		||||
  (define (cogen-*-constant a b)
 | 
			
		||||
    (struct-case a
 | 
			
		||||
      [(constant ak)
 | 
			
		||||
      (cond
 | 
			
		||||
        [(fx? ak)
 | 
			
		||||
       (if (fx? ak)
 | 
			
		||||
           (begin
 | 
			
		||||
             (interrupt)
 | 
			
		||||
             (with-tmp ([b (T b)])
 | 
			
		||||
                (assert-fixnum b)
 | 
			
		||||
           (prm 'int*/overflow b a))]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [else 
 | 
			
		||||
      (struct-case b
 | 
			
		||||
        [(constant bk)
 | 
			
		||||
         (cond
 | 
			
		||||
           [(fx? bk) 
 | 
			
		||||
            (with-tmp ([a (T a)])
 | 
			
		||||
              (assert-fixnum a)
 | 
			
		||||
              (prm 'int*/overflow a b))]
 | 
			
		||||
           [else (interrupt)])]
 | 
			
		||||
        [else (interrupt)])])]
 | 
			
		||||
                (prm 'int*/overflow a b)))
 | 
			
		||||
           (interrupt))]
 | 
			
		||||
      [(known x t) (cogen-*-constant x b)]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (or (cogen-*-constant a b)
 | 
			
		||||
      (cogen-*-constant b a)
 | 
			
		||||
      (cogen-*-non-constants a b)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop * safe
 | 
			
		||||
  [(V) (K (fxsll 1 fx-shift))]
 | 
			
		||||
  [(V a b) (cogen-binary-* a b)]
 | 
			
		||||
  [(P) (K #t)]
 | 
			
		||||
  [(P a . a*) (seq* (assert-fixnums a a*) (K #t))]
 | 
			
		||||
  [(E) (nop)]
 | 
			
		||||
| 
						 | 
				
			
			@ -1343,9 +1440,6 @@
 | 
			
		|||
(define-primop bitwise-and safe
 | 
			
		||||
  [(V) (K (fxsll -1 fx-shift))]
 | 
			
		||||
  [(V a . a*)
 | 
			
		||||
   (cond
 | 
			
		||||
     [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)]
 | 
			
		||||
     [else
 | 
			
		||||
   (interrupt)
 | 
			
		||||
   (seq*
 | 
			
		||||
     (assert-fixnums a a*)
 | 
			
		||||
| 
						 | 
				
			
			@ -1353,7 +1447,7 @@
 | 
			
		|||
       (cond
 | 
			
		||||
         [(null? a*) a]
 | 
			
		||||
         [else
 | 
			
		||||
             (f (prm 'logand a (T (car a*))) (cdr a*))])))])]
 | 
			
		||||
          (f (prm 'logand a (T (car a*))) (cdr a*))])))]
 | 
			
		||||
  [(P) (K #t)]
 | 
			
		||||
  [(P a . a*) (seq* (assert-fixnums a a*) (K #t))]
 | 
			
		||||
  [(E) (nop)]
 | 
			
		||||
| 
						 | 
				
			
			@ -1367,37 +1461,14 @@
 | 
			
		|||
  [(V x y) (cogen-value-- x y)])
 | 
			
		||||
 | 
			
		||||
(define-primop fx* safe
 | 
			
		||||
  [(V a b) 
 | 
			
		||||
   (struct-case a
 | 
			
		||||
     [(constant ak) 
 | 
			
		||||
      (cond
 | 
			
		||||
        [(fx? ak)
 | 
			
		||||
         (with-tmp ([b (T b)])
 | 
			
		||||
           (assert-fixnum b)
 | 
			
		||||
           (prm 'int*/overflow b a))]
 | 
			
		||||
        [else (interrupt)])]
 | 
			
		||||
     [else 
 | 
			
		||||
      (struct-case b
 | 
			
		||||
        [(constant bk)
 | 
			
		||||
         (cond
 | 
			
		||||
           [(fx? bk) 
 | 
			
		||||
            (with-tmp ([a (T a)])
 | 
			
		||||
              (assert-fixnum a)
 | 
			
		||||
              (prm 'int*/overflow a b))]
 | 
			
		||||
           [else (interrupt)])]
 | 
			
		||||
        [else 
 | 
			
		||||
         (with-tmp ([a (T a)] [b (T b)])
 | 
			
		||||
           (assert-fixnum a)
 | 
			
		||||
           (assert-fixnum b)
 | 
			
		||||
           (prm 'int*/overflow 
 | 
			
		||||
             (prm 'sra a (K fx-shift)) b))])])])
 | 
			
		||||
  [(V a b) (cogen-binary-* a b)])
 | 
			
		||||
 | 
			
		||||
(define-primop zero? safe
 | 
			
		||||
  [(P x)
 | 
			
		||||
   (seq*
 | 
			
		||||
     (interrupt-unless (cogen-pred-fixnum? x))
 | 
			
		||||
     (assert-fixnum x)
 | 
			
		||||
     (cogen-pred-$fxzero? x))]
 | 
			
		||||
  [(E x) (interrupt-unless (cogen-pred-fixnum? x))])
 | 
			
		||||
  [(E x) (assert-fixnum x)])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop fxarithmetic-shift-left safe
 | 
			
		||||
| 
						 | 
				
			
			@ -1444,7 +1515,6 @@
 | 
			
		|||
      [else #f])))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop div safe
 | 
			
		||||
  [(V x n) 
 | 
			
		||||
   (struct-case n 
 | 
			
		||||
| 
						 | 
				
			
			@ -1459,6 +1529,7 @@
 | 
			
		|||
               (K fx-shift))))]
 | 
			
		||||
        [else
 | 
			
		||||
         (interrupt)])]
 | 
			
		||||
     [(known) (error 'translate "div")]
 | 
			
		||||
     [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
(define-primop quotient safe
 | 
			
		||||
| 
						 | 
				
			
			@ -1479,6 +1550,7 @@
 | 
			
		|||
               (prm 'sra (T x) (K 1))
 | 
			
		||||
               (K (fxsll -1 fx-shift)))))
 | 
			
		||||
         (interrupt))]
 | 
			
		||||
    [(known expr t) (cogen-value-quotient x expr)]
 | 
			
		||||
    [else (interrupt)])])
 | 
			
		||||
 | 
			
		||||
/section)
 | 
			
		||||
| 
						 | 
				
			
			@ -1507,6 +1579,8 @@
 | 
			
		|||
                         (K vector-tag))])
 | 
			
		||||
        (prm 'mset t (K (- disp-struct-rtd vector-tag)) (T rtd))
 | 
			
		||||
        t)]
 | 
			
		||||
     [(known expr t)
 | 
			
		||||
      (cogen-value-$make-struct rtd expr)]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([ln (align-code len disp-struct-data)])
 | 
			
		||||
        (with-tmp ([t (prm 'alloc ln (K vector-tag))])
 | 
			
		||||
| 
						 | 
				
			
			@ -1594,25 +1668,32 @@
 | 
			
		|||
  [(P x) (K #t)]
 | 
			
		||||
  [(E x) (nop)])
 | 
			
		||||
 | 
			
		||||
(define (non-char? x)
 | 
			
		||||
  (struct-case x
 | 
			
		||||
    [(constant i) (not (char? i))]
 | 
			
		||||
    [else #f]))
 | 
			
		||||
 | 
			
		||||
(define (assert-chars a a*)
 | 
			
		||||
  (define (or* a a*)
 | 
			
		||||
    (cond
 | 
			
		||||
    [(constant? a) 
 | 
			
		||||
     (if (null? a*) 
 | 
			
		||||
         (nop)
 | 
			
		||||
         (assert-chars (car a*) (cdr a*)))]
 | 
			
		||||
      [(null? a*) a]
 | 
			
		||||
      [else (or* (prm 'logor a (T (car a*))) (cdr a*))]))
 | 
			
		||||
  (define (known-char? x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant i) (char? i)]
 | 
			
		||||
      [(known x t) (eq? (T:char? t) 'yes)]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (define (known-non-char? x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(constant i) (not (char? i))]
 | 
			
		||||
      [(known x t) (eq? (T:char? t) 'no)]
 | 
			
		||||
      [else #f]))
 | 
			
		||||
  (let-values ([(fx* others) (partition known-char? (cons a a*))])
 | 
			
		||||
    (let-values ([(nfx* others) (partition known-non-char?  others)])
 | 
			
		||||
      (cond
 | 
			
		||||
        [(not (null? nfx*)) (interrupt)]
 | 
			
		||||
        [(null? others)     (nop)]
 | 
			
		||||
        [else
 | 
			
		||||
         (interrupt-unless 
 | 
			
		||||
       (tag-test (or* (T a) a*) char-mask char-tag))]))
 | 
			
		||||
           (tag-test (or* (T (car others)) (cdr others)) char-mask char-tag))]))))
 | 
			
		||||
 | 
			
		||||
(define (char-fold-p op a a*)
 | 
			
		||||
  (cond
 | 
			
		||||
    [(or (non-char? a) (ormap non-char? a*)) (interrupt)]
 | 
			
		||||
    [else
 | 
			
		||||
  (seq*
 | 
			
		||||
    (assert-chars a a*)
 | 
			
		||||
    (let f ([a a] [a* a*])
 | 
			
		||||
| 
						 | 
				
			
			@ -1623,42 +1704,38 @@
 | 
			
		|||
           (make-conditional
 | 
			
		||||
             (prm op (T a) (T b))
 | 
			
		||||
             (f b (cdr a*))
 | 
			
		||||
                (K #f)))])))]))
 | 
			
		||||
             (K #f)))]))))
 | 
			
		||||
 | 
			
		||||
(define (char-fold-e a a*)
 | 
			
		||||
  (cond
 | 
			
		||||
    [(or (non-char? a) (ormap non-char? a*)) (interrupt)]
 | 
			
		||||
    [else (assert-chars a a*)]))
 | 
			
		||||
 | 
			
		||||
(define-primop char=? safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (char-fold-p '= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (char-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-chars a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop char<? safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (char-fold-p '< a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (char-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-chars a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop char<=? safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (char-fold-p '<= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (char-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-chars a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop char>? safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (char-fold-p '> a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (char-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-chars a a*)])
 | 
			
		||||
 | 
			
		||||
(define-primop char>=? safe
 | 
			
		||||
  [(P) (interrupt)]
 | 
			
		||||
  [(P a . a*) (char-fold-p '>= a a*)]
 | 
			
		||||
  [(E) (interrupt)]
 | 
			
		||||
  [(E a . a*) (char-fold-e a a*)])
 | 
			
		||||
  [(E a . a*) (assert-chars a a*)])
 | 
			
		||||
 | 
			
		||||
/section)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1683,6 +1760,8 @@
 | 
			
		|||
             (K (+ n (- disp-bytevector-data bytevector-tag)))
 | 
			
		||||
             (K 0))
 | 
			
		||||
         s)]
 | 
			
		||||
     [(known expr t)
 | 
			
		||||
      (cogen-value-$make-bytevector expr)]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([s (prm 'alloc 
 | 
			
		||||
                      (align-code 
 | 
			
		||||
| 
						 | 
				
			
			@ -1937,6 +2016,8 @@
 | 
			
		|||
             (K (- disp-string-length string-tag))
 | 
			
		||||
             (K (* n fx-scale)))
 | 
			
		||||
         s)]
 | 
			
		||||
     [(known expr) 
 | 
			
		||||
      (cogen-value-$make-string expr)]
 | 
			
		||||
     [else
 | 
			
		||||
      (with-tmp ([s (prm 'alloc 
 | 
			
		||||
                      (align-code (T n) disp-string-data)
 | 
			
		||||
| 
						 | 
				
			
			@ -1973,15 +2054,27 @@
 | 
			
		|||
  [(P s i) (K #t)]
 | 
			
		||||
  [(E s i) (nop)])
 | 
			
		||||
 | 
			
		||||
(define (assert-fixnum x)
 | 
			
		||||
(define assert-fixnum 
 | 
			
		||||
  (case-lambda 
 | 
			
		||||
    [(x)
 | 
			
		||||
     (struct-case x
 | 
			
		||||
       [(constant i) 
 | 
			
		||||
        (if (fixnum? i) (nop) (interrupt))]
 | 
			
		||||
    [else (interrupt-unless (cogen-pred-fixnum? x))]))
 | 
			
		||||
       [(known expr t)
 | 
			
		||||
        (case (T:fixnum? t)
 | 
			
		||||
          [(yes) (nop)]
 | 
			
		||||
          [(no)  (interrupt)]
 | 
			
		||||
          [else  (assert-fixnum expr)])]
 | 
			
		||||
       [else (interrupt-unless (cogen-pred-fixnum? x))])]))
 | 
			
		||||
 | 
			
		||||
(define (assert-string x)
 | 
			
		||||
  (struct-case x
 | 
			
		||||
    [(constant s) (if (string? s) (nop) (interrupt))]
 | 
			
		||||
    [(known expr t)
 | 
			
		||||
     (case (T:string? t)
 | 
			
		||||
       [(yes) (record-optimization 'assert-string x) (nop)]
 | 
			
		||||
       [(no)  (interrupt)]
 | 
			
		||||
       [else  (assert-string expr)])]
 | 
			
		||||
    [else (interrupt-unless (cogen-pred-string? x))]))
 | 
			
		||||
 | 
			
		||||
(define-primop string-ref safe
 | 
			
		||||
| 
						 | 
				
			
			@ -2003,7 +2096,6 @@
 | 
			
		|||
     (assert-string s)
 | 
			
		||||
     (interrupt-unless (prm 'u< (T i) (cogen-value-$string-length s))))])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
(define-primop $string-set! unsafe
 | 
			
		||||
  [(E x i c)
 | 
			
		||||
   (struct-case i
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,6 @@
 | 
			
		|||
  )
 | 
			
		||||
 | 
			
		||||
(module (specify-representation)
 | 
			
		||||
  ;(import object-representation)
 | 
			
		||||
  (import primops)
 | 
			
		||||
  (define-struct PH
 | 
			
		||||
    (interruptable? p-handler p-handled? v-handler v-handled? e-handler e-handled?))
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +107,14 @@
 | 
			
		|||
                     (prm '!= (make-no-interrupt-call x args) (K bool-f))
 | 
			
		||||
                     (make-shortcut body h)))]
 | 
			
		||||
             [else (error 'with-interrupt-handler "invalid context" ctxt)])))]))
 | 
			
		||||
  (define (copy-tag orig new)
 | 
			
		||||
    (struct-case orig
 | 
			
		||||
      [(known _ t) (make-known new t)]
 | 
			
		||||
      [else new]))
 | 
			
		||||
  (define (remove-tag x)
 | 
			
		||||
    (struct-case x
 | 
			
		||||
      [(known expr t) expr]
 | 
			
		||||
      [else x]))
 | 
			
		||||
  (define-syntax with-tmp
 | 
			
		||||
    (lambda (x)
 | 
			
		||||
      (syntax-case x ()
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +123,7 @@
 | 
			
		|||
           #'(let ([lhs* rhs*] ...)
 | 
			
		||||
               (let ([n* (unique-var 'lhs*)] ...)
 | 
			
		||||
                 (make-bind (list n* ...) (list lhs* ...)
 | 
			
		||||
                    (let ([lhs* n*] ...)
 | 
			
		||||
                    (let ([lhs* (copy-tag lhs* n*)] ...)
 | 
			
		||||
                      (seq* b b* ...))))))])))
 | 
			
		||||
  ;;; if ctxt is V:
 | 
			
		||||
  ;;;   if cogen-value, then V
 | 
			
		||||
| 
						 | 
				
			
			@ -140,11 +147,17 @@
 | 
			
		|||
         (let-values ([(lhs* rhs* arg*) (S* (cdr ls))])
 | 
			
		||||
           (let ([a (car ls)])
 | 
			
		||||
             (struct-case a
 | 
			
		||||
               [(known expr type v)
 | 
			
		||||
               [(known expr type)
 | 
			
		||||
                (struct-case expr
 | 
			
		||||
                  [(constant i)
 | 
			
		||||
                   ;;; erase known tag
 | 
			
		||||
                   (values lhs* rhs* (cons expr arg*))]
 | 
			
		||||
                  [else
 | 
			
		||||
                   ;(printf "known ~s ~s\n" type expr)
 | 
			
		||||
                   (let ([tmp (unique-var 'tmp)])
 | 
			
		||||
                     (values (cons tmp lhs*)
 | 
			
		||||
                             (cons (V expr) rhs*)
 | 
			
		||||
                          (cons (make-known tmp type v) arg*)))]
 | 
			
		||||
                             (cons (make-known tmp type) arg*)))])]
 | 
			
		||||
               [(constant i)
 | 
			
		||||
                (values lhs* rhs* (cons a arg*))]
 | 
			
		||||
               [else
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +366,7 @@
 | 
			
		|||
 | 
			
		||||
  (define (V x) ;;; erase known values
 | 
			
		||||
    (struct-case x 
 | 
			
		||||
      [(known x type value)
 | 
			
		||||
      [(known x t)
 | 
			
		||||
       (unknown-V x)]
 | 
			
		||||
      [else (unknown-V x)]))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +452,10 @@
 | 
			
		|||
      [else (error 'cogen-E "invalid effect expr" x)]))
 | 
			
		||||
 | 
			
		||||
  (define (Function x)
 | 
			
		||||
    (define (nonproc x)
 | 
			
		||||
    (define (Function x check?)
 | 
			
		||||
      (define (nonproc x check?)
 | 
			
		||||
        (cond
 | 
			
		||||
          [check?
 | 
			
		||||
           (with-tmp ([x (V x)])
 | 
			
		||||
             (make-shortcut
 | 
			
		||||
               (make-seq
 | 
			
		||||
| 
						 | 
				
			
			@ -449,33 +465,46 @@
 | 
			
		|||
                   (prm 'interrupt))
 | 
			
		||||
                 x)
 | 
			
		||||
               (V (make-funcall (make-primref 'error)
 | 
			
		||||
               (list (K 'apply) (K "not a procedure") x))))))
 | 
			
		||||
                    (list (K 'apply) (K "not a procedure") x)))))]
 | 
			
		||||
          [else
 | 
			
		||||
           (V x)]))
 | 
			
		||||
      (struct-case x
 | 
			
		||||
         [(primcall op args)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(and (eq? op 'top-level-value)
 | 
			
		||||
                  (= (length args) 1)
 | 
			
		||||
                (struct-case (car args)
 | 
			
		||||
                  [(constant t) 
 | 
			
		||||
                   (and (symbol? t) t)]
 | 
			
		||||
                  [else #f])) =>
 | 
			
		||||
                  (let f ([x (car args)])
 | 
			
		||||
                    (struct-case x
 | 
			
		||||
                      [(constant x) 
 | 
			
		||||
                       (and (symbol? x) x)]
 | 
			
		||||
                      [(known x t) (f x)]
 | 
			
		||||
                      [else #f]))) =>
 | 
			
		||||
             (lambda (sym)
 | 
			
		||||
             (record-symbol-call! sym)
 | 
			
		||||
               (reset-symbol-proc! sym)
 | 
			
		||||
               (prm 'mref (T (K sym))
 | 
			
		||||
                    (K (- disp-symbol-record-proc symbol-ptag))))]
 | 
			
		||||
          [else (nonproc x)])]
 | 
			
		||||
            [else (nonproc x check?)])]
 | 
			
		||||
         [(primref op) (V x)]
 | 
			
		||||
       [else (nonproc x)]))
 | 
			
		||||
         [(known x t v)
 | 
			
		||||
          (cond
 | 
			
		||||
            [(eq? (T:procedure? t) 'yes)
 | 
			
		||||
             ;(record-optimization 'procedure x)
 | 
			
		||||
             (Function x #f)]
 | 
			
		||||
            [else (Function x check?)])]
 | 
			
		||||
         [else (nonproc x check?)]))
 | 
			
		||||
    (Function x #t))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  (define encountered-symbol-calls '())
 | 
			
		||||
  (define (record-symbol-call! x)
 | 
			
		||||
    
 | 
			
		||||
    (unless (memq x encountered-symbol-calls)
 | 
			
		||||
      (set! encountered-symbol-calls 
 | 
			
		||||
        (cons x encountered-symbol-calls))))
 | 
			
		||||
 | 
			
		||||
  (define record-optimization^
 | 
			
		||||
    (let ([h (make-eq-hashtable)])
 | 
			
		||||
      (lambda (what expr)
 | 
			
		||||
        (let ([n (hashtable-ref h what 0)])
 | 
			
		||||
          (hashtable-set! h what (+ n 1))
 | 
			
		||||
          (printf "optimize ~a[~s]: ~s\n" what n (unparse expr))))))
 | 
			
		||||
  (define-syntax record-optimization
 | 
			
		||||
    (syntax-rules ()
 | 
			
		||||
      [(_ what expr) (void)]))
 | 
			
		||||
 | 
			
		||||
  ;;;========================================================================
 | 
			
		||||
  ;;;
 | 
			
		||||
| 
						 | 
				
			
			@ -491,7 +520,8 @@
 | 
			
		|||
    (struct-case x
 | 
			
		||||
      [(var) x]
 | 
			
		||||
      [(constant i) (constant-rep x)]
 | 
			
		||||
      [(known expr type val) (T expr)]
 | 
			
		||||
      [(known expr type)
 | 
			
		||||
       (make-known (T expr) type)]
 | 
			
		||||
      [else (error 'cogen-T "invalid" (unparse x))]))
 | 
			
		||||
 | 
			
		||||
  (define (ClambdaCase x)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue