123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- (library (syntax-object)
- ;;(require "utilities.scm")
- ;;(require "sets.scm")
- (export syx syx? syx-type syx-data syx-metadata
- annotate annotate? annotate-syn annotate-set
-
- syx-atomic? syx-id? syx-id syx-special?
- syx-scope-set
- syn-force
- syn-car syn-cdr syn-map
- syn->datum)
- (import (chezscheme)
- (only (chezscheme csv7) record-field-accessor)
- (utils) (sets))
- ;; This implements a representation of syntax objects
- ;;
- ;; <syntax> ::= (syx atomic <atomic> ?)
- ;; | (syx id|special <symbol> ?)
- ;; | ()
- ;; | (<syntax> . <syntax>)
- ;; | (annotate <syntax> <set>)
- ;; (struct syx ((type) (data) (metadata)) #:transparent)
- ;; (define-record syx (type data metadata))
- (define %syx (make-record-type "syx" '(type data metadata)))
- (define syx (record-constructor %syx))
- (define syx? (record-predicate %syx))
- (define syx-type (record-field-accessor %syx 'type))
- (define syx-data (record-field-accessor %syx 'data))
- (define syx-metadata (record-field-accessor %syx 'metadata))
- ;; (struct annotate ((syn) (set)) #:transparent)
- ;; (define-record annotate (syn set))
- (define %annotate (make-record-type "annotate" '(syn set)))
- (define annotate (record-constructor %annotate))
- (define annotate? (record-predicate %annotate))
- (define annotate-syn (record-field-accessor %annotate 'syn))
- (define annotate-set (record-field-accessor %annotate 'set))
- ;;; Simple predicates and projections
- ;;
- (define (syx-atomic? syn)
- (and (syx? syn) (eq? 'atomic (syx-type syn))))
- (define (syx-id? syn)
- (and (syx? syn) (eq? 'id (syx-type syn))))
- (define (syx-id syn)
- (unless (syx-id? syn)
- (error 'syx-id "invalid input"))
- (syx-data syn))
- (define (syx-special? syn)
- (and (syx? syn) (eq? 'special (syx-type syn))))
- (define (syx-scope-set syn)
- (cond ((assoc 'set (syx-metadata syn)) => cdr)
- (else empty-set)))
- ;;; Pushing annotations down lazy syntax
- ;;
- (define (syx-apply e set)
- (case (syx-type e)
- ((atomic) e)
- ((id) (syx (syx-type e)
- (syx-data e)
- (assoc-replace (syx-metadata e)
- 'set
- (set-union set (syx-scope-set e)))))
- ((special) e)
- (else (error 'syx-apply "unknown type" (syx-type e)))))
- (define (syn-apply syn set)
- (cond ((syx? syn) (syx-apply syn set))
- ((null? syn) syn)
- ((pair? syn) (cons (syn-apply (car syn) set)
- (syn-apply (cdr syn) set)))
- ((annotate? syn)
- (syn-apply (annotate-syn syn)
- (set-union set (annotate-set syn))))
- (else (error 'syn-apply "unknown type" syn))))
- (define (syn-force s)
- (if (annotate? s)
- (let ((syn (annotate-syn s))
- (set (annotate-set s)))
- (syn-apply syn set))
- s))
- (define (syn-car e) (car (syn-force e)))
- (define (syn-cdr e) (cdr (syn-force e)))
- (define (syn-map f l)
- (let ((e (syn-force l)))
- (if (null? l)
- '()
- (cons (f (car l))
- (syn-map f (cdr l))))))
- ;;; Present it without lots of noise for debugging
- ;;
- (define (syn->datum syn)
- (cond ((syx? syn) (syx-data syn))
- ((null? syn) syn)
- ((pair? syn) (cons (syn->datum (car syn))
- (syn->datum (cdr syn))))
- ((annotate? syn) (syn->datum (annotate-syn syn)))
- ((symbol? syn) syn) ;; raw symbols are allowed inside quote
- (else (error 'syn->datum "unknown type" syn))))
- )
|