~ chicken-core (chicken-5) 5a40360d93ede5d85f9db33ae72634b7c077e7fc
commit 5a40360d93ede5d85f9db33ae72634b7c077e7fc Author: felix <felix@call-with-current-continuation.org> AuthorDate: Wed Mar 9 04:33:10 2011 -0500 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Wed Mar 9 04:33:10 2011 -0500 -emit-type-file; types.db work; type-declaration syntax; stripping/globalizing in type-declarations; type-validation diff --git a/batch-driver.scm b/batch-driver.scm index 4c7de665..13d78814 100644 --- a/batch-driver.scm +++ b/batch-driver.scm @@ -75,6 +75,8 @@ (time0 #f) (time-breakdown #f) (forms '()) + (inline-output-file #f) + (type-output-file #f) (cleanup-forms '(((##sys#implicit-exit-handler)))) (profile (or (memq 'profile options) (memq 'accumulate-profile options) @@ -224,6 +226,8 @@ (set! inline-locally #t) ; otherwise this option makes no sense (set! local-definitions #t) (set! inline-output-file (option-arg ifile))) + (and-let* ((tfile (memq 'emit-type-file options))) + (set! type-outout-file (option-arg tfile))) (and-let* ([inlimit (memq 'inline-limit options)]) (set! inline-max-size (let ([arg (option-arg inlimit)]) @@ -484,6 +488,10 @@ (when (memq 'check-syntax options) (exit)) + (when type-output-file + (dribble "generating type file `~a' ..." type-output-file) + (emit-type-file type-output-file db)) + (let ([proc (user-pass)]) (when proc (dribble "User pass...") @@ -500,7 +508,6 @@ (print-node "initial node tree" '|T| node0) (initialize-analysis-database) -<<<<<<< HEAD (when (or do-scrutinize do-specialize) ;;;XXX hardcoded database file name (unless (memq 'ignore-repository options) diff --git a/c-platform.scm b/c-platform.scm index a65c386a..9250e4c7 100644 --- a/c-platform.scm +++ b/c-platform.scm @@ -101,6 +101,7 @@ parenthesis-synonyms prelude postlude prologue epilogue nursery extend feature no-feature types emit-import-library emit-inline-file static-extension consult-inline-file + emit-type-file heap-growth heap-shrinkage heap-initial-size ffi-define ffi-include-path) ) diff --git a/chicken-syntax.scm b/chicken-syntax.scm index 20c9e822..136b45bc 100644 --- a/chicken-syntax.scm +++ b/chicken-syntax.scm @@ -1110,6 +1110,25 @@ (##core#let-compiler-syntax (binding ...) body ...))))) +;;; type-declaration syntax + +(##sys#extend-macro-environment ;XXX not documented yet + ': '() + (##sys#er-transformer + (lambda (x r c) + (##sys#check-syntax ': x '(_ symbol _)) + (let ((name (##sys#globalize (cadr x))) + (type (##sys#strip-syntax (caddr x)))) + (validate-type type name) + (cond ((memq #:csi ##sys#features) '(##core#undefined)) + (else + (when (and (pair? type) + (eq? 'procedure (car type)) + (not (symbol? (cadr type)))) + (set! type `(procedure ,(##sys#strip-syntax name) ,@(cdr type)))) + `(##core#declare (type (,name ,type))))))))) + + (##sys#macro-subset me0 ##sys#default-macro-environment))) ;; register features diff --git a/compiler-namespace.scm b/compiler-namespace.scm index 679a62c8..b156ba30 100644 --- a/compiler-namespace.scm +++ b/compiler-namespace.scm @@ -108,6 +108,7 @@ emit-profile emit-syntax-trace-info emit-trace-info + emit-type-file enable-inline-files encode-literal eq-inline-operator @@ -165,6 +166,7 @@ get-line get-line-2 get-list + globalize hide-variable immediate? immutable-constants @@ -175,7 +177,6 @@ inline-lambda-bindings inline-locally inline-max-size - inline-output-file inline-substitutions-enabled inline-table inline-table-used @@ -199,6 +200,7 @@ make-variable-list mark-variable match-node + match-specialization membership-test-operators membership-unfold-limit no-argc-checks @@ -262,6 +264,7 @@ source-filename source-info->string source-info->line + specialize-node! standalone-executable string->c-identifier string->expr @@ -287,6 +290,7 @@ update-line-number-database update-line-number-database! used-units + validate-type valid-c-identifier? valid-compiler-options valid-compiler-options-with-argument diff --git a/compiler.scm b/compiler.scm index 3d637c6d..2beb740a 100644 --- a/compiler.scm +++ b/compiler.scm @@ -332,7 +332,6 @@ (define standalone-executable #t) (define local-definitions #f) (define inline-locally #f) -(define inline-output-file #f) (define enable-inline-files #f) (define compiler-syntax-enabled #t) (define unchecked-specialized-arithmetic #f) @@ -1262,24 +1261,17 @@ '() (##sys#current-environment) #f #f #f) ) ) -(define (process-declaration spec se) ; se unused in the moment +(define (process-declaration spec se) (define (check-decl spec minlen . maxlen) (let ([n (length (cdr spec))]) (if (or (< n minlen) (> n (optional maxlen 99999))) (syntax-error "invalid declaration" spec) ) ) ) (define (stripa x) ; global aliasing - (globalize x)) + (##sys#globalize x se)) (define (strip x) ; raw symbol (##sys#strip-syntax x)) (define stripu ##sys#strip-syntax) - (define (globalize sym) - (if (symbol? sym) - (let loop ((se se)) ; ignores syntax bindings - (cond ((null? se) (##sys#alias-global-hook sym #f #f)) ;XXX could hint at decl (3rd arg) - ((and (eq? sym (caar se)) (symbol? (cdar se))) (cdar se)) - (else (loop (cdr se))))) - sym)) - (define (globalize-all syms) (map globalize syms)) + (define (globalize-all syms) (map (cut ##sys#globalize <> se) syms)) (call-with-current-continuation (lambda (return) (unless (pair? spec) @@ -1474,14 +1466,20 @@ ((type) (for-each (lambda (spec) - (cond ((and (list? spec) (symbol? (car spec)) (>= (length spec) 2)) - (##sys#put! (car spec) '##core#type (cadr spec)) - (##sys#put! (car spec) '##core#declared-type #t) - (when (pair? (cddr spec)) - (##sys#put! (car spec) '##core#specializations (cddr spec)))) - (else - (warning "illegal type declaration item" spec)))) - (globalize-all (cdr spec)))) + (if (not (and (list? spec) (>= 2 (length spec)) (symbol? (car spec)))) + (warning "illegal type declaration" (##sys#strip-syntax spec)) + (let ((name (globalize (car spec))) + (type (##sys#strip-syntax (cadr spec)))) + (cond ((validate-type type name) + (##sys#put! name '##core#type type) + (##sys#put! name '##core#declared-type #t) + (when (pair? (cddr spec)) + (##sys#put! + name '##core#specializations + (##sys#strip-syntax (cddr spec))))) + (else + (warning "illegal type declaration" (##sys#strip-syntax spec))))))) + (cdr spec))) ((unsafe-specialized-arithmetic) (set! unchecked-specialized-arithmetic #t)) (else (warning "illegal declaration specifier" spec)) ) diff --git a/csc.scm b/csc.scm index bc840c79..626c46df 100644 --- a/csc.scm +++ b/csc.scm @@ -145,7 +145,7 @@ '(-debug -output-file -heap-size -nursery -stack-size -compiler -unit -uses -keyword-style -optimize-level -include-path -database-size -extend -prelude -postlude -prologue -epilogue -inline-limit -profile-name - -emit-inline-file -types + -emit-inline-file -types -emit-type-file -feature -debug-level -heap-growth -heap-shrinkage -heap-initial-size -consult-inline-file -emit-import-library -no-feature)) @@ -374,6 +374,7 @@ Usage: #{csc} FILENAME | OPTION ... -n -emit-inline-file FILENAME generate file with globally inlinable procedures (implies -inline -local) -consult-inline-file FILENAME explicitly load inline file + -emit-type-file FILENAME write type-declaration information into file -no-argc-checks disable argument count checks -no-bound-checks disable bound variable checks -no-procedure-checks disable procedure call checks diff --git a/expand.scm b/expand.scm index 4424e084..921a6d3c 100644 --- a/expand.scm +++ b/expand.scm @@ -123,6 +123,17 @@ (append (map (lambda (x y) (cons x y)) vars aliases) se)) ; inline cons +;;; resolve symbol to global name + +(define (##sys#globalize sym se) + (if (symbol? sym) + (let loop ((se se)) ; ignores syntax bindings + (cond ((null? se) (##sys#alias-global-hook sym #f #f)) ;XXX could hint at decl (3rd arg) + ((and (eq? sym (caar se)) (symbol? (cdar se))) (cdar se)) + (else (loop (cdr se))))) + sym)) + + ;;; Macro handling (define ##sys#macro-environment (make-parameter '())) diff --git a/scrutinizer.scm b/scrutinizer.scm index 1c1832e5..a785b4ed 100755 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -743,3 +743,28 @@ ((eq? 'quote (car x)) x) ; to handle numeric constants (else (cons (subst (car x)) (subst (cdr x)))))) (copy-node! (build-node-graph (subst template)) node))) + +(define (validate-type type name) + (define (validate t) + (cond ((memq t '(* string symbol char number boolean list pair + procedure vector null eof undefined port blob + pointer locative fixnum float pointer-vector deprecated))) + ((not (pair? t)) #f) + ((eq? 'or (car t)) + (and (list t) + (every validate (cdr t)))) + ((eq? 'struct (car t)) + (and (= 2 (length t)) (symbol? (cadr t)))) + ((eq? 'procedure (car t)) + (and (pair? (cdr t)) + (let ((t (if (symbol? (cadr t)) (cddr t) (cdr t)))) + (and (pair? t) + (list? (car t)) + (every + validate + (remove (cut memq <> '(#!optional #!rest values)) (car t))) + (or (eq? '* (cddr t)) + (and (list? (cddr t)) + (every validate (cddr t)))))))) + (else #f))) + (validate type)) diff --git a/support.scm b/support.scm index e8d07231..e79395a8 100644 --- a/support.scm +++ b/support.scm @@ -736,6 +736,23 @@ (loop))))))) +;;; write declared types to file + +(define (emit-type-file filename db) + (with-output-to-file filename + (lambda () + (print "; GENERATED BY CHICKEN " (chicken-version) " FROM " + source-filename "\n") + (##sys#hash-table-for-each + (lambda (sym plist) + (when (variable-visible? sym) + (and-let* ((type (variable-mark sym '##core#declared-type))) + (let ((specs (or (variable-mark sym '##core#specializations) '()))) + (pp (cons* sym type specs)))))) + db) + (print "; END OF FILE")))) + + ;;; Match node-structure with pattern: (define (match-node node pat vars) @@ -1504,6 +1521,7 @@ Usage: chicken FILENAME OPTION ... -no-lambda-info omit additional procedure-information -scrutinize perform local flow analysis for static checks -types FILENAME load additional type database + -emit-type-file FILENAME write type-declaration information into file Optimization options: diff --git a/types.db b/types.db index d8cb229c..45035e41 100644 --- a/types.db +++ b/types.db @@ -425,10 +425,7 @@ (arithmetic-shift (procedure arithmetic-shift (number number) number)) (bit-set? (procedure bit-set? (number fixnum) boolean) - ((fixnum fixnum) - (not (eq? 0 (##core#inline - "C_fixnum_and" #(1) - (##core#inline "C_fixnum_shift_left" 1 #(2))))))) + ((fixnum fixnum) (##core#inline "C_u_i_bit_setp" #(1) #(2)))) (bitwise-and (procedure bitwise-and (#!rest number) number) ((fixnum fixnum) (##core#inline "C_fixnum_and" #(1) #(2)))) @@ -1324,7 +1321,6 @@ ;; srfi-1 -;;XXX... (alist-cons (procedure alist-cons (* * *) list)) (alist-copy (procedure alist-copy (list) list)) (alist-delete (procedure alist-delete (* list #!optional (procedure (* *) *)) list)) @@ -1339,7 +1335,10 @@ (break! (procedure break! ((procedure (*) *) list) list list)) (car+cdr (procedure car+cdr (pair) * *)) (circular-list (procedure circular-list (#!rest) list)) -(circular-list? (procedure circular-list? (*) boolean)) + +(circular-list? (procedure circular-list? (*) boolean) + ((null) (let ((#:tmp #(1))) #f))) + (concatenate (procedure concatenate (list) list)) (concatenate! (procedure concatenate! (list) list)) (cons* (procedure cons* (* #!rest) pair)) @@ -1361,7 +1360,10 @@ (filter-map (procedure filter-map ((procedure (* #!rest) *) list #!rest list) list)) (find (procedure find ((procedure (*) *) list) *)) (find-tail (procedure find-tail ((procedure (*) *) list) *)) -(first (procedure first (pair) *)) + +(first (procedure first (pair) *) + ((pair) (##core#inline "C_u_i_car" #(1)))) + (fold (procedure fold ((procedure (* #!rest) *) * #!rest list) *)) (fold-right (procedure fold-right ((procedure (* #!rest) *) * #!rest list) *)) (fourth (procedure fourth (pair) *)) @@ -1390,14 +1392,25 @@ (map! (procedure map! ((procedure (*) *) list #!rest list) list)) (map-in-order (procedure map-in-order ((procedure (*) *) list #!rest list) list)) (ninth (procedure ninth (pair) *)) -(not-pair? (procedure not-pair? (*) boolean)) -(null-list? (procedure null-list? (list) boolean)) + +(not-pair? (procedure not-pair? (*) boolean) + ((pair) (let ((#:tmp #(1))) #f)) + (((not pair)) (let ((#:tmp #(1))) #t))) + +(null-list? (procedure null-list? (list) boolean) + ((pair) (let ((#:tmp #(1))) #f)) + ((list) (let ((#:tmp #(1))) #f)) + ((null) (let ((#:tmp #(1))) #t))) + (pair-fold (procedure pair-fold (procedure * list #!rest list) *)) (pair-fold-right (procedure pair-fold-right (procedure * list #!rest list) *)) (pair-for-each (procedure pair-for-each ((procedure (#!rest) . *) list #!rest list) undefined)) (partition (procedure partition ((procedure (*) *) list) list list)) (partition! (procedure partition! ((procedure (*) *) list) list list)) -(proper-list? (procedure proper-list? (*) boolean)) + +(proper-list? (procedure proper-list? (*) boolean) + ((null) (let ((#:tmp #(1))) #t))) + (reduce (procedure reduce ((procedure (* *) *) * list) *)) (reduce-right (procedure reduce-right ((procedure (* *) *) * list) *)) (remove (procedure remove ((procedure (*) *) list) list)) @@ -1424,11 +1437,12 @@ (unzip3 (procedure unzip3 (list) list list list)) (unzip4 (procedure unzip4 (list) list list list list)) (unzip5 (procedure unzip5 (list) list list list list list)) -(xcons (procedure xcons (* *) pair)) +(xcons (procedure xcons (* *) pair) (zip (procedure zip (list #!rest list) list)) ;; srfi-13 +;;XXX... (check-substring-spec (procedure check-substring-spec (* string fixnum fixnum) undefined)) (kmp-step (procedure kmp-step (string vector char fixnum (procedure (char char) *) fixnum) fixnum)) (make-kmp-restart-vector (procedure make-kmp-restart-vector (string #!optional (procedure (* *) *) fixnum fixnum) vector))Trap