diff --git a/scheme/ikarus.load.ss b/scheme/ikarus.load.ss index 3d24e36..ff5a642 100644 --- a/scheme/ikarus.load.ss +++ b/scheme/ikarus.load.ss @@ -48,12 +48,12 @@ (lambda (x) (define (read-file) (let ([p (open-input-file x)]) - (let ([x (read-initial p)]) + (let ([x (read-script-annotated p)]) (if (eof-object? x) (begin (close-input-port p) '()) (cons x (let f () - (let ([x (read p)]) + (let ([x (read-annotated p)]) (cond [(eof-object? x) (close-input-port p) diff --git a/scheme/ikarus.reader.ss b/scheme/ikarus.reader.ss index 93fb967..ba314b8 100644 --- a/scheme/ikarus.reader.ss +++ b/scheme/ikarus.reader.ss @@ -1315,6 +1315,12 @@ (define (read-as-comment p) (begin (read-expr p '() void) (void))) + (define (return-annotated x) + (cond + [(and (annotation? x) (eof-object? (annotation-expression x))) + (eof-object)] + [else x])) + (define my-read (lambda (p) (let-values ([(expr expr^ locs k) (read-expr p '() void)]) @@ -1340,28 +1346,32 @@ expr)])))) (define read-annotated - (lambda (p) - (let-values ([(expr expr^ locs k) (read-expr p '() void)]) - (cond - [(null? locs) expr^] - [else - (for-each reduce-loc! locs) - (k) - (if (loc? expr) - (loc-value^ expr) - expr^)])))) + (case-lambda + [(p) + (unless (input-port? p) + (error 'read-annotated "not an input port" p)) + (let-values ([(expr expr^ locs k) (read-expr p '() void)]) + (cond + [(null? locs) (return-annotated expr^)] + [else + (for-each reduce-loc! locs) + (k) + (if (loc? expr) + (loc-value^ expr) + (return-annotated expr^))]))] + [() (read-annotated (current-input-port))])) (define read-script-annotated (lambda (p) (let-values ([(expr expr^ locs k) (read-expr-script-initial p '() void)]) (cond - [(null? locs) expr^] + [(null? locs) (return-annotated expr^)] [else (for-each reduce-loc! locs) (k) (if (loc? expr) (loc-value^ expr) - expr^)])))) + (return-annotated expr^))])))) (define read-token (case-lambda diff --git a/scheme/last-revision b/scheme/last-revision index c686973..f038def 100644 --- a/scheme/last-revision +++ b/scheme/last-revision @@ -1 +1 @@ -1267 +1268 diff --git a/scheme/psyntax.compat.ss b/scheme/psyntax.compat.ss index 17979c2..31156d2 100644 --- a/scheme/psyntax.compat.ss +++ b/scheme/psyntax.compat.ss @@ -17,7 +17,9 @@ (library (psyntax compat) (export define-record make-parameter parameterize format gensym eval-core symbol-value set-symbol-value! - file-options-spec make-struct-type) + file-options-spec make-struct-type read-annotated + annotation? annotation-expression annotation-source + annotation-stripped) (import (only (ikarus compiler) eval-core) (ikarus)) diff --git a/scheme/psyntax.expander.ss b/scheme/psyntax.expander.ss index 349dc1d..e5b509c 100644 --- a/scheme/psyntax.expander.ss +++ b/scheme/psyntax.expander.ss @@ -200,7 +200,16 @@ ;;; Now to syntax objects which are records defined like: (define-record stx (expr mark* subst*) (lambda (x p) - (display "#datum x) p) (display ">" p))) @@ -336,9 +345,12 @@ ;;; now are some deconstructors and predicates for syntax objects. (define syntax-kind? (lambda (x p?) - (if (stx? x) - (syntax-kind? (stx-expr x) p?) - (p? x)))) + (cond + [(stx? x) (syntax-kind? (stx-expr x) p?)] + [(annotation? x) + (syntax-kind? (annotation-expression x) p?)] + [else (p? x)]))) + (define syntax-vector->list (lambda (x) (cond @@ -346,6 +358,8 @@ (let ((ls (syntax-vector->list (stx-expr x))) (m* (stx-mark* x)) (s* (stx-subst* x))) (map (lambda (x) (mkstx x m* s*)) ls))) + [(annotation? x) + (syntax-vector->list (annotation-expression x))] ((vector? x) (vector->list x)) (else (assertion-violation 'syntax-vector->list "not a syntax vector" x))))) (define syntax-pair? @@ -360,11 +374,22 @@ (and (syntax-pair? x) (syntax-list? (syntax-cdr x)))))) (define syntax-car (lambda (x) - (if (stx? x) - (mkstx (syntax-car (stx-expr x)) (stx-mark* x) (stx-subst* x)) - (if (pair? x) - (car x) - (assertion-violation 'syntax-car "not a pair" x))))) + (cond + [(stx? x) + (mkstx (syntax-car (stx-expr x)) (stx-mark* x) (stx-subst* x))] + [(annotation? x) + (syntax-car (annotation-expression x))] + [(pair? x) (car x)] + [else (assertion-violation 'syntax-car "not a pair" x)]))) + (define syntax-cdr + (lambda (x) + (cond + [(stx? x) + (mkstx (syntax-cdr (stx-expr x)) (stx-mark* x) (stx-subst* x))] + [(annotation? x) + (syntax-cdr (annotation-expression x))] + [(pair? x) (cdr x)] + [else (assertion-violation 'syntax-cdr "not a pair" x)]))) (define syntax->list (lambda (x) (if (syntax-pair? x) @@ -372,23 +397,16 @@ (if (syntax-null? x) '() (assertion-violation 'syntax->list "invalid argument" x))))) - (define syntax-cdr - (lambda (x) - (if (stx? x) - (mkstx (syntax-cdr (stx-expr x)) (stx-mark* x) (stx-subst* x)) - (if (pair? x) - (cdr x) - (assertion-violation 'syntax-cdr "not a pair" x))))) (define id? (lambda (x) (syntax-kind? x symbol?))) (define id->sym (lambda (x) - (if (stx? x) - (id->sym (stx-expr x)) - (if (symbol? x) - x - (assertion-violation 'id->sym "not an id" x))))) + (cond + [(stx? x) (id->sym (stx-expr x))] + [(annotation? x) (annotation-expression x)] + [(symbol? x) x] + [else (assertion-violation 'id->sym "not an id" x)]))) ;;; Two lists of marks are considered the same if they have the ;;; same length and the corresponding marks on each are eq?. @@ -445,10 +463,13 @@ (define strip (lambda (x m*) (if (top-marked? m*) - x + (if (annotation? x) + (annotation-stripped x) + x) (let f ((x x)) (cond ((stx? x) (strip (stx-expr x) (stx-mark* x))) + [(annotation? x) (annotation-stripped x)] ((pair? x) (let ((a (f (car x))) (d (f (cdr x)))) (if (and (eq? a (car x)) (eq? d (cdr x))) @@ -1963,6 +1984,8 @@ ((stx? e) (let-values (((m* s*) (join-wraps m* s* e))) (match-each (stx-expr e) p m* s*))) + [(annotation? e) + (match-each (annotation-expression e) p m* s*)] (else #f)))) (define match-each+ (lambda (e x-pat y-pat z-pat m* s* r) @@ -1984,6 +2007,8 @@ ((stx? e) (let-values (((m* s*) (join-wraps m* s* e))) (f (stx-expr e) m* s*))) + [(annotation? e) + (f (annotation-expression e) m* s*)] (else (values '() y-pat (match e z-pat m* s* r))))))) (define match-each-any (lambda (e m* s*) @@ -1995,6 +2020,8 @@ ((stx? e) (let-values (((m* s*) (join-wraps m* s* e))) (match-each-any (stx-expr e) m* s*))) + [(annotation? e) + (match-each-any (annotation-expression e) m* s*)] (else #f)))) (define match-empty (lambda (p r) @@ -2065,6 +2092,8 @@ ((stx? e) (let-values (((m* s*) (join-wraps m* s* e))) (match (stx-expr e) p m* s* r))) + [(annotation? e) + (match (annotation-expression e) p m* s* r)] (else (match* e p m* s* r))))) (match e p '() '() '()))) @@ -2168,13 +2197,14 @@ (syntax-match e () ((_ expr (keys ...) clauses ...) (begin - (unless (for-all (lambda (x) (and (id? x) (not (ellipsis? x)))) keys) + (unless (for-all (lambda (x) (and (id? x) (not (ellipsis? x)))) keys) (stx-error e "invalid literals")) (let ((x (gen-lexical 'tmp))) (let ((body (gen-syntax-case x keys clauses r mr))) (build-application no-source (build-lambda no-source (list x) body) (list (chi-expr expr r mr))))))))))) + (define syntax-transformer (let () (define gen-syntax @@ -2942,18 +2972,20 @@ (let ((id* (map (lambda (x) (mkstx x top-mark* '())) ext*))) (unless (valid-bound-ids? id*) (assertion-violation 'expander "invalid exports" (find-dups id*)))) - (values int* ext*)) + (values (map syntax->datum int*) (map syntax->datum ext*))) (else (syntax-match (car exp*) () ((rename (i* e*) ...) (begin - (unless (and (eq? rename 'rename) (for-all symbol? i*) - (for-all symbol? e*)) + (unless (and (eq? (syntax->datum rename) 'rename) + (for-all id? i*) + (for-all id? e*)) (assertion-violation 'expander "invalid export specifier" (car exp*))) (f (cdr exp*) (append i* int*) (append e* ext*)))) (ie (begin - (unless (symbol? ie) (assertion-violation 'expander "invalid export" ie)) + (unless (id? ie) + (assertion-violation 'expander "invalid export" ie)) (f (cdr exp*) (cons ie int*) (cons ie ext*))))))))) ;;; given a library name, like (foo bar (1 2 3)), @@ -2963,11 +2995,15 @@ (define (parse x) (syntax-match x () [((v* ...)) - (for-all (lambda (x) (and (integer? x) (exact? x))) v*) - (values '() v*)] - [(x . rest) (symbol? x) + (for-all + (lambda (x) + (let ([x (syntax->datum x)]) + (and (integer? x) (exact? x)))) + v*) + (values '() (map syntax->datum v*))] + [(x . rest) (id? x) (let-values ([(x* v*) (parse rest)]) - (values (cons x x*) v*))] + (values (cons (id->sym x) x*) v*))] [() (values '() '())] [_ (stx-error spec "invalid library name")])) (let-values (((name* ver*) (parse spec))) @@ -2983,7 +3019,9 @@ (export exp* ...) (import imp* ...) b* ...) - (and (eq? export 'export) (eq? import 'import) (eq? library 'library)) + (and (eq? (syntax->datum export) 'export) + (eq? (syntax->datum import) 'import) + (eq? (syntax->datum library) 'library)) (values name* exp* imp* b*)) (_ (stx-error e "malformed library"))))) @@ -3050,37 +3088,38 @@ (and (integer? x) (exact? x) (>= x 0))) (define (subversion-pred x*) (syntax-match x* () - [n (subversion? n) - (lambda (x) (= x n))] - [(p? sub* ...) (eq? p? 'and) + [n (subversion? (syntax->datum n)) + (lambda (x) (= x (syntax->datum n)))] + [(p? sub* ...) (eq? (syntax->datum p?) 'and) (let ([p* (map subversion-pred sub*)]) (lambda (x) (for-all (lambda (p) (p x)) p*)))] - [(p? sub* ...) (eq? p? 'or) + [(p? sub* ...) (eq? (syntax->datum p?) 'or) (let ([p* (map subversion-pred sub*)]) (lambda (x) (exists (lambda (p) (p x)) p*)))] - [(p? sub) (eq? p? 'not) + [(p? sub) (eq? (syntax->datum p?) 'not) (let ([p (subversion-pred sub)]) (lambda (x) (not (p x))))] - [(p? n) (and (eq? p? '<=) (subversion? n)) - (lambda (x) (<= x n))] - [(p? n) (and (eq? p? '>=) (subversion? n)) - (lambda (x) (>= x n))] + [(p? n) + (and (eq? (syntax->datum p?) '<=) (subversion? (syntax->datum n))) + (lambda (x) (<= x (syntax->datum n)))] + [(p? n) (and (eq? (syntax->datum p?) '>=) (subversion? n)) + (lambda (x) (>= x (syntax->datum n)))] [_ (assertion-violation 'import "invalid sub-version spec" x* spec)])) (define (version-pred x*) (syntax-match x* () [() (lambda (x) #t)] - [(c ver* ...) (eq? c 'and) + [(c ver* ...) (eq? (syntax->datum c) 'and) (let ([p* (map version-pred ver*)]) (lambda (x) (for-all (lambda (p) (p x)) p*)))] - [(c ver* ...) (eq? c 'or) + [(c ver* ...) (eq? (syntax->datum c) 'or) (let ([p* (map version-pred ver*)]) (lambda (x) (exists (lambda (p) (p x)) p*)))] - [(c ver) (eq? c 'not) + [(c ver) (eq? (syntax->datum c) 'not) (let ([p (version-pred ver)]) (lambda (x) (not (p x))))] [(sub* ...) @@ -3098,46 +3137,49 @@ (syntax-match x () [((version-spec* ...)) (values '() (version-pred version-spec*))] - [(x . x*) (symbol? x) + [(x . x*) (id? x) (let-values ([(name pred) (f x*)]) - (values (cons x name) pred))] + (values (cons (id->sym x) name) pred))] [() (values '() (lambda (x) #t))] [_ (stx-error spec "invalid import spec")]))) (define (get-import spec) (syntax-match spec () ((rename isp (old* new*) ...) - (and (eq? rename 'rename) - (for-all symbol? old*) - (for-all symbol? new*)) - (let ((subst (get-import isp))) + (and (eq? (syntax->datum rename) 'rename) + (for-all id? old*) + (for-all id? new*)) + (let ((subst (get-import isp)) + [old* (map id->sym old*)] + [new* (map id->sym new*)]) ;;; rewrite this to eliminate find* and rem* and merge (let ((old-label* (find* old* subst))) (let ((subst (rem* old* subst))) ;;; FIXME: make sure map is valid (merge-substs (map cons new* old-label*) subst))))) ((except isp sym* ...) - (and (eq? except 'except) (for-all symbol? sym*)) + (and (eq? (syntax->datum except) 'except) (for-all id? sym*)) (let ((subst (get-import isp))) - (rem* sym* subst))) + (rem* (map id->sym sym*) subst))) ((only isp sym* ...) - (and (eq? only 'only) (for-all symbol? sym*)) - (let ((subst (get-import isp))) + (and (eq? (syntax->datum only) 'only) (for-all id? sym*)) + (let ((subst (get-import isp)) + [sym* (map id->sym sym*)]) (let ((sym* (remove-dups sym*))) (let ((lab* (find* sym* subst))) (map cons sym* lab*))))) ((prefix isp p) - (and (eq? prefix 'prefix) (symbol? p)) - (let ((subst (get-import isp))) + (and (eq? (syntax->datum prefix) 'prefix) (id? p)) + (let ((subst (get-import isp)) + (prefix (symbol->string (id->sym p)))) (map (lambda (x) (cons (string->symbol - (string-append - (symbol->string p) + (string-append prefix (symbol->string (car x)))) (cdr x))) subst))) - ((library (spec* ...)) (eq? library 'library) + ((library (spec* ...)) (eq? (syntax->datum library) 'library) ;;; FIXME: versioning stuff (let-values ([(name pred) (parse-library-name spec*)]) (when (null? name) @@ -3155,7 +3197,7 @@ ((imp-collector) lib) (library-subst lib)))) ((x x* ...) - (not (memq x '(rename except only prefix library))) + (not (memq (syntax->datum x) '(rename except only prefix library))) (get-import `(library (,x . ,x*)))) (spec (assertion-violation 'import "invalid import spec" spec)))) (define (add-imports! imp h) @@ -3303,9 +3345,11 @@ (define (parse-top-level-program e*) (syntax-match e* () - (((import imp* ...) b* ...) (eq? import 'import) + (((import imp* ...) b* ...) + (eq? (syntax->datum import) 'import) (values imp* b*)) - (((import . x) . y) (eq? import 'import) + (((import . x) . y) + (eq? (syntax->datum import) 'import) (assertion-violation 'expander "invalid syntax of top-level program")) (_ @@ -3528,6 +3572,21 @@ (assertion-violation 'bound-identifier=? "not an identifier" y)) (assertion-violation 'bound-identifier=? "not an identifier" x)))) + (define (extract-position-condition x) + (define-condition-type &source-information &condition + make-source-condition source-condition? + (file-name source-filename) + (character source-character)) + (if (stx? x) + (let ([x (stx-expr x)]) + (if (annotation? x) + (let ([src (annotation-source x)]) + (if (pair? src) + (make-source-condition (car src) (cdr src)) + (condition))) + (condition))) + (condition))) + (define syntax-error (lambda (x . args) (unless (for-all string? args) @@ -3539,8 +3598,9 @@ "invalid syntax" (apply string-append args))) (make-syntax-violation - (stx->datum x) - 'none))))) + (syntax->datum x) + #f) + (extract-position-condition x))))) (define syntax-violation (case-lambda @@ -3568,7 +3628,8 @@ (make-message-condition msg) (make-syntax-violation (syntax->datum form) - (syntax->datum subform)))))])) + (syntax->datum subform)) + (extract-position-condition form))))])) (define identifier? (lambda (x) (id? x))) diff --git a/scheme/psyntax.library-manager.ss b/scheme/psyntax.library-manager.ss index 5bbd29f..894f620 100644 --- a/scheme/psyntax.library-manager.ss +++ b/scheme/psyntax.library-manager.ss @@ -148,7 +148,8 @@ (lambda (x) (let ((file-name ((file-locator) x))) (and (string? file-name) - (with-input-from-file file-name read)))) + (with-input-from-file file-name + read-annotated)))) (lambda (f) (if (procedure? f) f