~ chicken-core (chicken-5) 074fdfc6b5ccea0bbbacfac351a7a883997b24fc
commit 074fdfc6b5ccea0bbbacfac351a7a883997b24fc Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sat Apr 9 13:36:19 2011 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sat Apr 9 13:36:19 2011 +0200 implicit toplevel type defs; procedure-type adjustment from blist diff --git a/scrutinizer.scm b/scrutinizer.scm index 1cd8a513..ae4a4e27 100755 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -65,8 +65,10 @@ ; ##compiler#type -> TYPESPEC ; ##compiler#declared-type -> BOOL ; ##compiler#predicate -> TYPESPEC -; ##compiler#specializations -> (SPECIALIZATION ...) +; ##compiler#specializations -> (SPECIALIZATION ...) ; ##compiler#enforce-argument-types -> BOOL +; ##compiler#special-result-type -> PROCEDURE: NODE SYMBOL PROCEDURE-TYPE RESULT-TYPES -> +; RESULT-TYPES' ; ; specialization specifiers: ; @@ -264,7 +266,8 @@ (cond ((equal? ts2 (cdr t)) t) (else (dd " or-simplify: ~a" ts2) - (simplify `(or ,@(if (any (cut eq? <> '*) ts2) '(*) ts2)))))))) ) + (simplify + `(or ,@(if (any (cut eq? <> '*) ts2) '(*) ts2)))))))) ) ((procedure) (let* ((name (and (named? t) (cadr t))) (rtypes (if name (cdddr t) (cddr t)))) @@ -515,9 +518,12 @@ (let ((r (procedure-result-types ptype values-rest (cdr args)))) (d " result-types: ~a" r) ;;XXX we should check whether this is a standard- or extended binding - (let ((pn (procedure-name ptype)) - (op #f)) + (let* ((pn (procedure-name ptype)) + (op #f)) (when pn + (let ((hardcoded (variable-mark pn '##compiler#special-result-type))) + (when hardcoded + (set! r (hardcoded node pn ptype r)))) (cond ((and (fx= 1 nargs) (variable-mark pn '##compiler#predicate)) => (lambda (pt) @@ -575,49 +581,6 @@ (cond ((string? n) (string->symbol n)) ((symbol? n) n) (else #f))))) - (define (procedure-argument-types t n) - (cond ((or (memq t '(* procedure)) - (not-pair? t) - (eq? 'deprecated (car t))) - (values (make-list n '*) #f)) - ((eq? 'procedure (car t)) - (let* ((vf #f) - (llist - (let loop ((at (if (or (string? (second t)) (symbol? (second t))) - (third t) - (second t))) - (m n) - (opt #f)) - (cond ((null? at) '()) - ((eq? '#!optional (car at)) - (loop (cdr at) m #t) ) - ((eq? '#!rest (car at)) - (set! vf (and (pair? (cdr at)) (eq? 'values (cadr at)))) - (make-list m (rest-type (cdr at)))) - ((and opt (<= m 0)) '()) - (else (cons (car at) (loop (cdr at) (sub1 m) opt))))))) - (values llist vf))) - (else (bomb "not a procedure type" t)))) - (define (procedure-result-types t values-rest? args) - (cond (values-rest? args) - ((or (memq t '(* procedure)) - (not-pair? t) ) - '*) - ((eq? 'procedure (car t)) - (call/cc - (lambda (return) - (let loop ((rt (if (or (string? (second t)) (symbol? (second t))) - (cdddr t) - (cddr t)))) - (cond ((null? rt) '()) - ((eq? '* rt) (return '*)) - (else (cons (car rt) (loop (cdr rt))))))))) - (else (bomb "not a procedure type: ~a" t)))) - (define (noreturn-type? t) - (or (eq? 'noreturn t) - (and (pair? t) - (eq? 'or (car t)) - (any noreturn-type? (cdr t))))) (define (self-call? node loc) (case (node-class node) ((##core#call) @@ -693,15 +656,32 @@ (if rest (butlast vars) vars)) e))) (fluid-let ((blist '())) - (let ((r (walk (first subs) - (if rest (alist-cons rest 'list e2) e2) - (add-loc dest loc) - #f #t (list (tag)) #f))) + (let* ((initial-tag (tag)) + (r (walk (first subs) + (if rest (alist-cons rest 'list e2) e2) + (add-loc dest loc) + #f #t (list initial-tag) #f))) (list (append '(procedure) name - (list args) + (let loop ((argc argc) (vars vars) (args args)) + (cond ((zero? argc) args) + ((and (not (get db (car vars) 'assigned)) + (assoc (cons var initial-tag) blist)) + => + (lambda (a) + (unless (eq? (cdr a) '*) + (debugging + 'x "adjusting procedure argument type" + (car vars) (cdr a)) + (cons + (cdr a) + (loop (sub1 argc) (cdr vars) (cdr args)))))) + (else + (cons + (car args) + (loop (sub1 argc) (cdr vars) (cdr args)))))) r)))))))) ((set! ##core#set!) (let* ((var (first params)) @@ -720,8 +700,18 @@ "assignment of value of type `~a' to toplevel variable `~a' does not match declared type `~a'" rt var type) #t)) - ;;XXX we could set the ##compiler#type property here for hidden - ;; globals that are only assigned once + (when (and (not type) + (not b) + (not (eq? '* rt)) + (not (variable-visible? var)) + (not (get db var 'unknown))) + (and-let* ((val (or (get db var 'value) + (get db var 'local-value)))) + (when (eq? val (first subs)) + (debugging + 'x "implicitly declaring toplevel variable type" + var rt) + (mark-variable var '##compiler#type rt)))) (when b (cond ((eq? 'undefined (cdr b)) (set-cdr! b rt)) (strict-variable-types @@ -809,6 +799,52 @@ (debugging 'x "safe calls" safe-calls)) rn))) +(define (procedure-argument-types t n) + (cond ((or (memq t '(* procedure)) + (not-pair? t) + (eq? 'deprecated (car t))) + (values (make-list n '*) #f)) + ((eq? 'procedure (car t)) + (let* ((vf #f) + (llist + (let loop ((at (if (or (string? (second t)) (symbol? (second t))) + (third t) + (second t))) + (m n) + (opt #f)) + (cond ((null? at) '()) + ((eq? '#!optional (car at)) + (loop (cdr at) m #t) ) + ((eq? '#!rest (car at)) + (set! vf (and (pair? (cdr at)) (eq? 'values (cadr at)))) + (make-list m (rest-type (cdr at)))) + ((and opt (<= m 0)) '()) + (else (cons (car at) (loop (cdr at) (sub1 m) opt))))))) + (values llist vf))) + (else (bomb "not a procedure type" t)))) + +(define (procedure-result-types t values-rest? args) + (cond (values-rest? args) + ((or (memq t '(* procedure)) + (not-pair? t) ) + '*) + ((eq? 'procedure (car t)) + (call/cc + (lambda (return) + (let loop ((rt (if (or (string? (second t)) (symbol? (second t))) + (cdddr t) + (cddr t)))) + (cond ((null? rt) '()) + ((eq? '* rt) (return '*)) + (else (cons (car rt) (loop (cdr rt))))))))) + (else (bomb "not a procedure type: ~a" t)))) + +(define (noreturn-type? t) + (or (eq? 'noreturn t) + (and (pair? t) + (eq? 'or (car t)) + (any noreturn-type? (cdr t))))) + (define (load-type-database name #!optional (path (repository-path))) (and-let* ((dbfile (file-exists? (make-pathname path name)))) (when verbose-mode @@ -972,3 +1008,22 @@ `(procedure ,(upto t p) ,@(cdr p))))) (else #f))) (validate type)) + +(define-syntax define-special-case + (syntax-rules () + ((_ name handler) + (##sys#put! 'name '##compiler#special-result-type handler)))) + + +;;; hardcoded result types for certain primitives + +(define-special-case ##sys#make-structure + (lambda (node name ptype rtypes) + (or (let ((subs (node-subexpressions node))) + (and (pair? subs) + (let ((arg1 (first subs))) + (and (eq? 'quote (node-class arg1)) + (let ((val (first (node-parameters arg1)))) + (and (symbol? val) + `(struct ,val))))))) + rtypes)))Trap