Skip to content

Instantly share code, notes, and snippets.

@michaelballantyne
Created February 1, 2022 04:15
Show Gist options
  • Save michaelballantyne/f6bc234be515fb7b927b28c2ab750cc6 to your computer and use it in GitHub Desktop.
Save michaelballantyne/f6bc234be515fb7b927b28c2ab750cc6 to your computer and use it in GitHub Desktop.
Compute the set of primitives used in an s-expression linklet
#lang racket/base
(require racket/list racket/set racket/string racket/match)
(define (local? sym)
(define str (symbol->string sym))
(define trimmed (string-trim str #rx"_[0-9]+" #:left? #f))
(not (equal? str trimmed)))
(define (get-primitives l)
(define locally-defined (set))
(define (add-locally-defined! sym)
(set! locally-defined (set-add locally-defined sym)))
(define references (set))
(define (add-reference! sym)
(when (not (local? sym))
(set! references (set-add references sym))))
(define (traverse-body stmts)
(for ([stmt stmts])
(match stmt
[`(define-values ,bound-names ,rhs)
(for ([sym bound-names])
(add-locally-defined! sym))
(traverse-expr rhs)]
[_ (traverse-expr stmt)])))
(define (traverse-expr e)
(match e
[`(lambda ,formals ,body)
(traverse-expr body)]
[`(case-lambda . ,(list (list formals exprs) ...))
(map traverse-expr exprs)]
[`(,(or 'begin 'begin0) . ,exprs)
(map traverse-expr exprs)]
[`(if ,e1 ,e2 ,e3)
(traverse-expr e1)
(traverse-expr e2)
(traverse-expr e3)]
[`(,(or 'letrec-values 'let-values) ,(list (list _ rhs) ...) ,body)
(map traverse-expr rhs)
(traverse-expr body)]
[`(set! ,_ ,e)
(traverse-expr e)]
[`(with-continuation-mark ,e1 ,e2 ,e3)
(traverse-expr e1)
(traverse-expr e2)
(traverse-expr e3)]
[`(#%variable-reference . ,_)
(void)]
[`(quote ,_)
(void)]
[(? symbol?)
(add-reference! e)]
[(or (? number?) (? boolean?) (? string?) (? bytes?))
(void)]
[(list es ...)
(map traverse-expr es)]
[_ (error 'traverse-expr "not handled: ~v" e)]))
(match l
[`(,_ ,imports ,exports . ,body)
(traverse-body body)])
(set->list (set-subtract references locally-defined)))
#;(begin
(define path "/Users/michaelballantyne/racket/racket/src/expander/compiled/exp.zo")
(define l (read (open-input-file path)))
(define prims (get-primitives l)))
;> (length prims)
;503
;> prims
;'(list->string
; abort-current-continuation
; unsafe-end-atomic
; fx-
; port-read-handler
; string
; current-logger
; hash-eqv?
; unsafe-fx>=
; current-code-inspector
; system-library-subpath
; cadr
; -
; =
; build-path
; cdar
; exn:fail:filesystem?
; unsafe-fxvector-set!
; instance-variable-names
; explode-path
; system-type
; instance-describe-variable!
; vector
; srcloc-source
; unsafe-vector-ref
; call-with-escape-continuation
; instance?
; vector-set!
; imag-part
; fx<
; prop:impersonator-of
; path-element->bytes
; void
; memv
; make-hasheqv-placeholder
; path->directory-path
; numerator
; prop:evt
; exn-continuation-marks
; single-flonum-available?
; set-mcdr!
; complex?
; <
; make-continuation-prompt-tag
; inspector?
; raise
; not
; make-ephemeron
; unsafe-car
; write
; cadadr
; parameterization-key
; regexp-replace*
; procedure-arity
; string->path
; read-char-or-special
; cleanse-path
; srcloc
; resolve-path
; exact->inexact
; current-write-relative-directory
; symbol?
; hash-clear!
; list*
; linklet-export-variables
; cons
; instance-variable-value
; struct:exn:fail:filesystem
; byte?
; fixnum?
; read-case-sensitive
; sync/timeout
; unsafe-cdr
; max
; check-for-break
; unsafe-bytes-length
; /
; mcons
; make-struct-field-mutator
; eval-jit-enabled
; list->vector
; single-flonum?
; close-input-port
; variable-reference-from-unsafe?
; raise-result-arity-error
; hash-iterate-next
; fx>
; >=
; unsafe-flvector-set!
; make-struct-field-accessor
; make-string
; bytes->path
; fx+
; current-compile-target-machine
; car
; instance-name
; integer->integer-bytes
; path->complete-path
; split-path
; raise-mismatch-error
; regexp-match?
; string->bytes/utf-8
; raise-result-error
; zero?
; prop:checked-procedure
; byte-regexp?
; unsafe-vector*-ref
; vector*-ref
; plumber-add-flush!
; error-print-width
; make-inspector
; make-weak-box
; void?
; fx=
; caddr
; file-size
; make-hash-placeholder
; keyword->string
; output-port?
; keyword?
; >
; peek-char-or-special
; eof
; cadddr
; cdddr
; simplify-path
; eval-linklet
; unbox
; prop:sealed
; weak-box-value
; <=
; regexp-match-positions
; cddr
; semaphore-post
; string=?
; char->integer
; vector-immutable
; srcloc?
; list-ref
; eqv?
; unquoted-printing-string
; hash-for-each
; read-on-demand-source
; error-syntax->string-handler
; extflonum?
; hash?
; add1
; arithmetic-shift
; hash-count
; string->bytes/locale
; port-count-lines!
; vector-length
; unsafe-bytes-ref
; raise-argument-error
; unsafe-start-atomic
; current-inexact-milliseconds
; unsafe-fxrshift
; exn:fail:out-of-memory
; regexp
; char?
; inspector-superior?
; call-with-continuation-prompt
; variable-reference-constant?
; linklet-import-variables
; unsafe-vector-length
; path?
; fxand
; bytes->string/locale
; default-continuation-prompt-tag
; denominator
; eof-object?
; subbytes
; expand-user-path
; flonum?
; unsafe-fx<=
; path-convention-type
; write-string
; make-bytes
; immutable?
; set-box*!
; symbol->immutable-string
; datum-intern-literal
; sync
; compiled-position->primitive
; real->single-flonum
; exn:fail:unsupported
; placeholder-set!
; make-ephemeron-hasheq
; symbol-unreadable?
; file-position
; unsafe-immutable-hash-iterate-next
; box
; semaphore-peek-evt
; error
; +
; make-immutable-hash
; prop:procedure
; srcloc-line
; arity-at-least-value
; hasheq
; filesystem-change-evt
; log-level?
; srcloc-span
; fxrshift
; make-immutable-hasheqv
; write-bytes
; rational?
; instance-set-variable-value!
; flvector-set!
; boolean?
; string-locale-downcase
; primitive-in-category?
; syntax-span
; char-alphabetic?
; equal?
; make-polar
; values
; make-prefab-struct
; fprintf
; error-print-source-location
; unbox*
; string->bytes/latin-1
; string->immutable-string
; raise-arguments-error
; unsafe-make-place-local
; datum->syntax
; min
; bytes->string/utf-8
; raise-type-error
; bytes->path-element
; input-port?
; read-bytes
; struct->vector
; unsafe-string-length
; string-append-immutable
; *
; flush-output
; path->string
; srcloc-column
; prefab-key->struct-type
; make-hash
; impersonator?
; syntax-source
; hash-remove!
; exn:fail:read
; hash-iterate-first
; positive?
; append
; mcdr
; log-message
; andmap
; instantiate-linklet
; print-syntax-width
; make-hasheq
; display
; prop:authentic
; error-value->string-handler
; unsafe-immutable-hash-iterate-key+value
; hash-keys-subset?
; absolute-path?
; fx->fl
; primitive-table
; integer-bytes->integer
; bytes-open-converter
; unsafe-place-local-ref
; path-for-some-system?
; hash-iterate-key
; real-part
; unsafe-immutable-hash-iterate-key
; exact-positive-integer?
; current-plumber
; apply
; reparameterize
; read-byte
; primitive-lookup
; vector->immutable-vector
; object-name
; current-load-extension
; integer?
; primitive->compiled-position
; fx<=
; string-set!
; continuation-prompt-available?
; unsafe-vector-set!
; symbol-interned?
; eq-hash-code
; string-ref
; char<=?
; vector*-length
; exception-handler-key
; open-output-bytes
; make-vector
; unsafe-fx=
; get-output-bytes
; peek-byte
; current-load-relative-directory
; prefab-struct-key
; struct:exn:fail
; syntax-property
; bytes=?
; bytes<?
; char-whitespace?
; syntax-column
; current-inspector
; fxmin
; file-exists?
; unsafe-place-local-set!
; unsafe-fx-
; file-or-directory-modify-seconds
; relative-path?
; mcar
; syntax-line
; load-on-demand-enabled
; bytes-convert
; read-linklet-bundle-hash
; ephemeron-value
; vector->list
; regexp?
; make-hasheq-placeholder
; unsafe-end-breakable-atomic
; hash-set
; procedure-arity-includes?
; current-memory-use
; string->number
; make-weak-hash
; length
; bytes-length
; break-enabled-key
; fx>=
; fxvector-set!
; byte-pregexp?
; ceiling
; unsafe-vector*-length
; log
; eq?
; unsafe-fx<
; find-system-path
; inexact->exact
; memq
; read-accept-bar-quote
; current-environment-variables
; write-byte
; bitwise-ior
; extend-parameterization
; pregexp
; cache-configuration
; syntax?
; list-tail
; open-input-file
; call-with-continuation-barrier
; make-parameter
; pregexp?
; current-print
; exn-message
; set-box!
; unsafe-immutable-hash-iterate-first
; prop:custom-write
; hasheqv
; hash-iterate-key+value
; make-immutable-hasheq
; string->symbol
; equal-hash-code
; null?
; gensym
; floating-point-bytes->real
; filesystem-change-evt-cancel
; byte-regexp
; null
; prop:exn:srclocs
; box-immutable
; path->bytes
; hash
; char=?
; port-next-location
; make-semaphore
; string?
; hash-iterate-value
; current-error-port
; exact?
; make-weak-hasheq
; make-struct-type-property
; unsafe-fx+
; fxior
; never-evt
; hash-set!
; hash-eq?
; hash-remove
; integer-length
; current-thread
; logger-name
; modulo
; regexp-replace
; format
; current-output-port
; instance-data
; expt
; system-path-convention-type
; bytes-append
; vector-ref
; unsafe-start-breakable-atomic
; version
; exn:fail:contract:variable
; make-hasheqv
; hash-ref-key
; instance-unset-variable!
; exn:fail:contract?
; string-copy!
; exn:fail?
; extflonum-available?
; linklet-virtual-machine-bytes
; parameterization?
; arity-at-least?
; number->string
; vector?
; number?
; srcloc-position
; make-struct-type
; prop:equal+hash
; directory-list
; hash-copy
; recompile-linklet
; real?
; linklet?
; peek-bytes
; unsafe-vector*-set!
; with-input-from-file
; byte-pregexp
; cadar
; exn:fail:read:non-char
; real->extfl
; string-foldcase
; make-fxvector
; string->uninterned-symbol
; complete-path?
; negative?
; list?
; mpair?
; regexp-match
; string-append
; make-placeholder
; fx*
; open-input-bytes
; exact-integer?
; variable-reference?
; exact-nonnegative-integer?
; make-thread-cell
; caar
; continuation-mark-set-first
; quotient
; environment-variables-ref
; symbol->string
; string->list
; compile-linklet
; syntax-position
; vector-copy!
; prefab-key?
; substring
; make-instance
; for-each
; srcloc->string
; integer->char
; variable-reference->instance
; sub1
; bytes?
; current-continuation-marks
; make-flvector
; string-length
; caddar
; exn:fail:read:eof
; current-directory
; bytes->immutable-bytes
; string->keyword
; unsafe-undefined
; hash-ref
; read-char
; vector*-set!
; raise-range-error
; make-reader-graph
; cdr
; current-read-interaction
; write-linklet-bundle-hash
; box?
; bytes-ref
; make-rectangular
; real->floating-point-bytes
; string->unreadable-symbol
; char>=?
; symbol<?
; directory-exists?
; syntax-e
; fxlshift
; list
; unsafe-struct*-cas!
; unsafe-root-continuation-prompt-tag
; caadr
; char-numeric?
; procedure?
; call-with-values
; bytes
; box-cas!
; dynamic-wind
; current-input-port
; pair?)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment