|
|
|
#lang racket/base
|
|
|
|
|
|
|
|
|
|
|
|
(require racket/contract/base)
|
|
|
|
|
|
|
|
|
|
|
|
(provide
|
|
|
|
(contract-out
|
|
|
|
[semantic-action? predicate/c]
|
|
|
|
[semantic-action-build-datum-splice (-> semantic-action? list? list?)]
|
|
|
|
[semantic-action-build-syntax-splice
|
|
|
|
(-> semantic-action? (listof syntax?) #:first-token syntax-token? #:last-token syntax-token?
|
|
|
|
(listof syntax?))]
|
|
|
|
[cut-action cut-action?]
|
|
|
|
[cut-action? predicate/c]
|
|
|
|
[splice-action splice-action?]
|
|
|
|
[splice-action? predicate/c]
|
|
|
|
[label-action? predicate/c]
|
|
|
|
[label-action (->* (any/c) (#:properties hash? #:expression-properties hash?) label-action?)]
|
|
|
|
[label-action-value (-> label-action? any/c)]
|
|
|
|
[label-action-properties (-> label-action? hash?)]
|
|
|
|
[label-action-expression-properties (-> label-action? hash?)]
|
|
|
|
[build-pair-action (->* () (#:properties hash?) build-pair-action?)]
|
|
|
|
[build-pair-action? predicate/c]
|
|
|
|
[build-list-action (->* () (#:properties hash?) build-list-action?)]
|
|
|
|
[build-list-action? predicate/c]
|
|
|
|
[build-improper-list-action (->* () (#:properties hash?) build-improper-list-action?)]
|
|
|
|
[build-improper-list-action? predicate/c]
|
|
|
|
[build-vector-action (->* () (#:properties hash?) build-vector-action?)]
|
|
|
|
[build-vector-action? predicate/c]
|
|
|
|
[build-hash-action (->* () (#:kind (or/c 'equal 'eqv 'eq) #:properties hash?) build-hash-action?)]
|
|
|
|
[build-hash-action? predicate/c]
|
|
|
|
[build-box-action (->* () (#:properties hash?) build-box-action?)]
|
|
|
|
[build-box-action? predicate/c]
|
|
|
|
[build-prefab-struct-action (->* (prefab-key?) (#:properties hash?) build-prefab-struct-action?)]
|
|
|
|
[build-prefab-struct-action? predicate/c]))
|
|
|
|
|
|
|
|
|
|
|
|
(require racket/list
|
|
|
|
racket/match
|
|
|
|
racket/sequence
|
|
|
|
rebellion/private/static-name
|
|
|
|
yaragg/base/token)
|
|
|
|
|
|
|
|
|
|
|
|
;@----------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
(define (semantic-action? v)
|
|
|
|
(or (cut-action? v)
|
|
|
|
(splice-action? v)
|
|
|
|
(label-action? v)
|
|
|
|
(build-pair-action? v)
|
|
|
|
(build-list-action? v)
|
|
|
|
(build-improper-list-action? v)
|
|
|
|
(build-vector-action? v)
|
|
|
|
(build-hash-action? v)
|
|
|
|
(build-box-action? v)
|
|
|
|
(build-prefab-struct-action? v)))
|
|
|
|
|
|
|
|
|
|
|
|
(struct cut-action () #:transparent #:constructor-name constructor:cut-action #:omit-define-syntaxes)
|
|
|
|
(define cut-action (constructor:cut-action))
|
|
|
|
|
|
|
|
|
|
|
|
(struct splice-action ()
|
|
|
|
#:transparent #:constructor-name constructor:splice-action #:omit-define-syntaxes)
|
|
|
|
(define splice-action (constructor:splice-action))
|
|
|
|
|
|
|
|
|
|
|
|
(struct label-action (value expression-properties properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:label-action
|
|
|
|
#:omit-define-syntaxes
|
|
|
|
#:guard
|
|
|
|
(struct-guard/c any/c
|
|
|
|
(hash/c any/c any/c #:immutable #true #:flat? #true)
|
|
|
|
(hash/c any/c any/c #:immutable #true #:flat? #true)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (label-action value
|
|
|
|
#:properties [properties (hash)]
|
|
|
|
#:expression-properties [expression-properties (hash)])
|
|
|
|
(constructor:label-action value properties expression-properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-pair-action (properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-pair-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-pair-action #:properties [properties (hash)])
|
|
|
|
(constructor:build-pair-action properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-list-action (properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-list-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-list-action #:properties [properties (hash)])
|
|
|
|
(constructor:build-list-action properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-improper-list-action (properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-improper-list-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-improper-list-action #:properties [properties (hash)])
|
|
|
|
(constructor:build-improper-list-action properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-vector-action (properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-vector-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-vector-action #:properties [properties (hash)])
|
|
|
|
(constructor:build-vector-action properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-hash-action (kind properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-hash-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-hash-action #:kind [kind 'equal] #:properties [properties (hash)])
|
|
|
|
(constructor:build-hash-action kind properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-box-action (properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-box-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-box-action #:properties [properties (hash)])
|
|
|
|
(constructor:build-box-action properties))
|
|
|
|
|
|
|
|
|
|
|
|
(struct build-prefab-struct-action (key properties)
|
|
|
|
#:transparent
|
|
|
|
#:constructor-name constructor:build-prefab-struct-action
|
|
|
|
#:omit-define-syntaxes)
|
|
|
|
|
|
|
|
|
|
|
|
(define (build-prefab-struct-action key #:properties [properties (hash)])
|
|
|
|
(constructor:build-prefab-struct-action key properties))
|
|
|
|
|
|
|
|
|
|
|
|
(define (semantic-action-build-datum-splice action children)
|
|
|
|
(match action
|
|
|
|
[(== cut-action) '()]
|
|
|
|
[(== splice-action) children]
|
|
|
|
[(? label-action?) (list (cons (label-action-value action) children))]
|
|
|
|
[(? build-pair-action?) (list (cons (first children) (second children)))]
|
|
|
|
[(? build-list-action?) (list children)]
|
|
|
|
[(? build-improper-list-action?) (list (list->improper-list children))]
|
|
|
|
[(? build-vector-action?) (list (list->vector children))]
|
|
|
|
[(? build-hash-action?)
|
|
|
|
(define hash-maker
|
|
|
|
(case (build-hash-action-kind action)
|
|
|
|
[(equal) make-immutable-hash]
|
|
|
|
[(eqv) make-immutable-hasheqv]
|
|
|
|
[(eq) make-immutable-hasheq]))
|
|
|
|
(define pairs
|
|
|
|
(for/list ([key+value (in-slice 2 children)])
|
|
|
|
(cons (first key+value) (second key+value))))
|
|
|
|
(define hash (hash-maker pairs))
|
|
|
|
(unless (equal? (hash-count hash) (length pairs))
|
|
|
|
(raise-arguments-error (name build-hash-action)
|
|
|
|
"duplicate keys detected when building hash datum"
|
|
|
|
"pairs" pairs))
|
|
|
|
(list hash)]
|
|
|
|
[(? build-box-action?) (list (box-immutable (first children)))]
|
|
|
|
[(? build-prefab-struct-action?)
|
|
|
|
(define key (build-prefab-struct-action-key action))
|
|
|
|
(list (apply make-prefab-struct key children))]))
|
|
|
|
|
|
|
|
|
|
|
|
(define (semantic-action-build-syntax-splice action children
|
|
|
|
#:first-token first-token
|
|
|
|
#:last-token last-token)
|
|
|
|
(match action
|
|
|
|
[(== cut-action) '()]
|
|
|
|
[(== splice-action) children]
|
|
|
|
|
|
|
|
[(? label-action?)
|
|
|
|
(define label-location
|
|
|
|
(srcloc (syntax-token-source first-token)
|
|
|
|
(syntax-token-line first-token)
|
|
|
|
(syntax-token-column first-token)
|
|
|
|
(syntax-token-position first-token)
|
|
|
|
0))
|
|
|
|
(define label-stx
|
|
|
|
(syntax-add-properties
|
|
|
|
(datum->syntax #false (label-action-value action) label-location #false)
|
|
|
|
(label-action-properties action)))
|
|
|
|
(define expression-location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define expression-stx
|
|
|
|
(datum->syntax #false (cons label-stx children) expression-location #false))
|
|
|
|
(list (syntax-add-properties expression-stx (label-action-expression-properties action)))]
|
|
|
|
|
|
|
|
[(? build-pair-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define properties (build-pair-action-properties action))
|
|
|
|
(define stx (datum->syntax #false (cons (first children) (second children)) location #false))
|
|
|
|
(list (syntax-add-properties stx properties))]
|
|
|
|
|
|
|
|
[(? build-list-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define properties (build-list-action-properties action))
|
|
|
|
(list (syntax-add-properties (datum->syntax #false children location #false) properties))]
|
|
|
|
|
|
|
|
[(? build-improper-list-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define properties (build-improper-list-action-properties action))
|
|
|
|
(define stx (datum->syntax #false (list->improper-list children) location #false))
|
|
|
|
(list (syntax-add-properties stx properties))]
|
|
|
|
|
|
|
|
[(? build-vector-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define properties (build-vector-action-properties action))
|
|
|
|
(define stx (datum->syntax #false (list->vector children) location #false))
|
|
|
|
(list (syntax-add-properties stx properties))]
|
|
|
|
|
|
|
|
[(? build-hash-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define hash-maker
|
|
|
|
(case (build-hash-action-kind action)
|
|
|
|
[(equal) make-immutable-hash]
|
|
|
|
[(eqv) make-immutable-hasheqv]
|
|
|
|
[(eq) make-immutable-hasheq]))
|
|
|
|
(define pairs
|
|
|
|
(for/list ([key+value (in-slice 2 children)])
|
|
|
|
(cons (syntax->datum (first key+value)) (second key+value))))
|
|
|
|
(define hash (hash-maker pairs))
|
|
|
|
(unless (equal? (hash-count hash) (length pairs))
|
|
|
|
(raise-arguments-error (name build-hash-action)
|
|
|
|
"duplicate keys detected when building hash syntax"
|
|
|
|
"pairs" pairs))
|
|
|
|
(define stx (datum->syntax #false (hash-maker pairs) location #false))
|
|
|
|
(list (syntax-add-properties stx (build-hash-action-properties action)))]
|
|
|
|
|
|
|
|
[(? build-box-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define properties (build-box-action-properties action))
|
|
|
|
(define stx (datum->syntax #false (box-immutable (first children)) location #false))
|
|
|
|
(list (syntax-add-properties stx properties))]
|
|
|
|
|
|
|
|
[(? build-prefab-struct-action?)
|
|
|
|
(define location (srcloc-spanning-tokens first-token last-token))
|
|
|
|
(define key (build-prefab-struct-action-key action))
|
|
|
|
(define properties (build-prefab-struct-action-properties action))
|
|
|
|
(define stx (datum->syntax #false (apply make-prefab-struct key children) location #false))
|
|
|
|
(list (syntax-add-properties stx properties))]))
|
|
|
|
|
|
|
|
|
|
|
|
(define (list->improper-list list)
|
|
|
|
(apply list* list))
|
|
|
|
|
|
|
|
|
|
|
|
(define (srcloc-spanning-tokens first-token last-token)
|
|
|
|
(srcloc (syntax-token-source first-token)
|
|
|
|
(syntax-token-line first-token)
|
|
|
|
(syntax-token-column first-token)
|
|
|
|
(syntax-token-position first-token)
|
|
|
|
(- (syntax-token-end-position last-token) (syntax-token-position first-token))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (syntax-add-properties stx properties)
|
|
|
|
(for/fold ([stx stx]) ([(key value) (in-hash properties)])
|
|
|
|
(syntax-property stx key value)))
|