Skip to content

Commit be8f3f2

Browse files
Merge branch 'main' into thesis
2 parents 4550625 + 2d4c458 commit be8f3f2

File tree

19 files changed

+1459
-130
lines changed

19 files changed

+1459
-130
lines changed

info.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
(define build-deps '("racket-doc" "scribble-lib" "drracket" "typed-racket-lib"))
1212
(define scribblings '(("scribblings/main.scrbl" (multi-page) (experimental) "syntax-spec-dev")))
1313
(define compile-omit-paths '("design" "demos"))
14-
(define test-omit-paths '("design" "demos"))
14+
(define test-omit-paths '("scribblings" "design" "demos"))

main.rkt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
...
88
...+
99

10+
#%host-expression
11+
1012
mutable-reference-compiler
1113
immutable-reference-compiler
1214

@@ -53,12 +55,14 @@
5355
free-identifiers
5456
binding-identifiers
5557
alpha-equivalent?
58+
subst
5659
get-racket-referenced-identifiers))
5760

5861
(require "private/syntax/interface.rkt"
5962
"private/runtime/compile.rkt"
6063
(for-syntax syntax/parse
6164
(except-in "private/ee-lib/main.rkt" racket-var)
65+
"private/runtime/compile.rkt"
6266
"private/ee-lib/persistent-id-table.rkt"
6367
"private/ee-lib/binding.rkt"
6468
"private/runtime/binding-operations.rkt"

private/ee-lib/flip-intro-scope.rkt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616

1717
(define/who (flip-intro-scope stx)
1818
(check who syntax? stx)
19-
((make-intro-scope-introducer) stx 'flip))
19+
(if (syntax-transforming?)
20+
((make-intro-scope-introducer) stx 'flip)
21+
stx))

private/ee-lib/persistent-id-table.rkt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
; so entries wouldn't be available during module visit until the end of the module
3333
; is reached.
3434

35-
(struct persistent-free-id-table [persisted transient id])
35+
(struct persistent-free-id-table [persisted [transient #:mutable] id])
3636

3737
(define (make-persistent-free-id-table id)
3838
(persistent-free-id-table
@@ -100,6 +100,9 @@
100100
#`(cons #'#,(flip-intro-scope k) #,(if (syntax? v)
101101
#`(deserialize-syntax-props #'#,(serialize-syntax-props (flip-intro-scope v)))
102102
#`'#,v))))
103+
104+
(set-persistent-free-id-table-transient! t (make-free-id-table))
105+
103106
#`(begin-for-syntax
104107
(do-extension! #,(persistent-free-id-table-id t)
105108
(list . #,alist))))

private/runtime/binding-operations.rkt

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
(provide free-identifiers
44
binding-identifiers
5+
identifier=?
56
alpha-equivalent?
7+
subst
68
get-racket-referenced-identifiers
79
(rename-out [identifier=? compiled-identifier=?]))
810

@@ -99,25 +101,22 @@
99101
; Syntax, Syntax [#:allow-host? Boolean] -> Boolean
100102
; Are the two expressions alpha-equivalent?
101103
(define (alpha-equivalent? stx-a stx-b #:allow-host? [allow-host? #f])
102-
(define bound-reference=? (alpha-equivalent?/bindings stx-a stx-b allow-host?))
104+
(define bound-reference=? (syntaxes->bound-reference=? stx-a stx-b allow-host?))
103105
(and bound-reference=?
104106
(alpha-equivalent?/references stx-a stx-b bound-reference=? allow-host?)))
105107

106108
; Syntax Syntax Boolean -> (or/c #f (Identifier Identifier -> Boolean))
107-
; check that the bindings of both expressions can be alpha-equivalent.
108-
; returns bound-reference=?, or #f if the binding check fails.
109-
(define (alpha-equivalent?/bindings stx-a stx-b allow-host?)
109+
; if the two terms have corresponding binders, build bound-reference=?
110+
; If they have different numbers of binders, return #f
111+
; bound-reference=? answers "do these two references refer to corresponding binders?"
112+
(define (syntaxes->bound-reference=? stx-a stx-b allow-host?)
110113
(define table-a (make-free-id-table))
111114
(define table-b (make-free-id-table))
115+
;; associate both binders with the same gensym
112116
(define (bind! identifier-a identifier-b)
113117
(define x (gensym))
114-
(free-id-table-set! table-a identifier-a x)
115-
(free-id-table-set! table-b identifier-b x))
116-
(define (bound-reference=? identifier-a identifier-b)
117-
(and (dict-has-key? table-a identifier-a)
118-
(dict-has-key? table-b identifier-b)
119-
(eq? (free-id-table-ref table-a identifier-a)
120-
(free-id-table-ref table-b identifier-b))))
118+
(free-id-table-set! table-a (compiled-from identifier-a) x)
119+
(free-id-table-set! table-b (compiled-from identifier-b) x))
121120
(define binders-a (binding-identifiers stx-a #:allow-host? allow-host?))
122121
(define binders-b (binding-identifiers stx-b #:allow-host? allow-host?))
123122
; must traverse binders before references
@@ -127,7 +126,16 @@
127126
[binder-b binders-b])
128127
(bind! binder-a binder-b))
129128
(and (= (length binders-a) (length binders-b))
130-
bound-reference=?))
129+
(substitutions->bound-reference=? table-a table-b)))
130+
131+
;; FreeIdTable FreeIdTable -> (Identifier Identifier -> Boolean)
132+
;; Do these two references refer to corresponding binders?
133+
;; table-a and table-b should map corresponding binders to the same, unique value
134+
(define ((substitutions->bound-reference=? table-a table-b) identifier-a identifier-b)
135+
(and (dict-has-key? table-a (compiled-from identifier-a))
136+
(dict-has-key? table-b (compiled-from identifier-b))
137+
(eq? (free-id-table-ref table-a (compiled-from identifier-a))
138+
(free-id-table-ref table-b (compiled-from identifier-b)))))
131139

132140
; Syntax Syntax (Identifier Identifier -> Boolean) Boolean -> Boolean
133141
; check that the references are alpha-equivalent.
@@ -159,6 +167,22 @@
159167
[(a b) (equal? (syntax->datum #'a)
160168
(syntax->datum #'b))])))
161169

170+
;; Syntax Syntax Syntax -> Syntax
171+
;; Replace all occurrences of target (by alpha equivalence) with replacement in stx.
172+
;; Leaves host expressions unchanged.
173+
(define (subst stx target replacement)
174+
(let loop ([stx stx])
175+
(if (if (compiled-binder? target)
176+
(and (compiled-reference? stx) (identifier=? stx target))
177+
(alpha-equivalent? stx target))
178+
replacement
179+
(syntax-parse stx
180+
;; ignore host expressions
181+
[((~literal #%host-expression) . _) this-syntax]
182+
[(a . b)
183+
(quasisyntax/loc this-syntax (#,(loop #'a) . #,(loop #'b)))]
184+
[_ stx]))))
185+
162186
(define current-referenced-vars (make-parameter #f))
163187

164188
; get the racket vars referenced in e of the provided binding classes
@@ -174,9 +198,7 @@
174198
'expression
175199
'())
176200

177-
(sequence->list (in-symbol-set (for/fold ([references (immutable-symbol-set)])
178-
([x (in-symbol-set (current-referenced-vars))])
179-
(symbol-set-add references x))))))
201+
(sequence->list (in-symbol-set (current-referenced-vars)))))
180202

181203
(define recording-reference-compiler
182204
(make-variable-like-reference-compiler

private/syntax/interface.rkt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@
359359
((~literal define-syntaxes) (x:racket-macro ...) e:expr)
360360
#:binding (export-syntaxes x ... e)
361361

362+
((~literal begin) b:racket-body ...)
363+
#:binding [(re-export b) ...]
364+
362365
e:racket-expr))
363366

364367
(define-syntax define-dsl-syntax

0 commit comments

Comments
 (0)