#lang scheme/base
(provide
(all-defined-out)
(all-from-out syntax/stx))
(require
"grabbag.ss"
scheme/struct-info
syntax/stx)
(define (format-stx fmt . args)
(apply format fmt (->sexp args)))
(define (map-stx fn . stxs)
(apply map fn (map syntax->list stxs)))
(define (->sexp x)
(cond
((syntax? x) (syntax->datum x))
((list? x) (map ->sexp x))
((pair? x) (cons (->sexp (car x)) (->sexp (cdr x))))
((null? x) '())
(else x)))
(define (prefix-id . names)
(let ((orig-stx (car (reverse names)))) (datum->syntax orig-stx (string->symbol
(apply string-append
(map
(lambda (x)
(format "~a"
(if (syntax? x)
(syntax->datum x)
x)))
names)))
orig-stx orig-stx )))
(define (stx-reverse stx)
#`(#,@(reverse (syntax->list stx))))
(define (lexical-binding? stx)
(eq? 'lexical (identifier-binding stx)))
(define (stx-uncons stx)
(values (stx-car stx) (stx-cdr stx)))
(define (stx-length s)
(length (syntax->datum s)))
(define (lexical-context-from stx-lex)
(lambda (stx)
(let ((new-stx
(datum->syntax stx-lex
(syntax->datum stx)
stx)))
new-stx)))
(define-syntax-rule (syntax-case/r tree-stx literals clause ...)
(let down ((stx tree-stx))
(syntax-case stx literals
clause ...
((el (... ...))
(map down (syntax->list #'(el (... ...)))))
(el #'el))))
(define (struct->struct-info name [context name])
(let ([v (syntax-local-value name (lambda () #f))])
(unless (struct-info? v)
(raise-syntax-error #f "identifier is not bound to a structure type" context name))
(let ((v (extract-struct-info v)))
(printf "~a\n" v)
v)))
(define (struct->constructor . a) (cadr (apply struct->struct-info a)))
(define (struct->members . a) (cadddr (apply struct->struct-info a)))
(define (in-stx stx) (in-list (syntax->list stx)))
(define (datum->syntax-list stx lst)
(map (lambda (x) (datum->syntax stx x)) lst))
(define-syntax-rule (syntax-introduce-identifiers stx lst body)
(syntax-case (datum->syntax-list stx 'lst) ()
(lst body)))
(define-syntax-rule (define-hashes name ...)
(begin (define name (make-hash)) ...))
(define (datum id) (if (syntax? id) (syntax->datum id) id))
(define (id-reg! hash id [val #t]) (hash-set! hash (datum id) val))
(define (id-find hash id) (hash-ref hash (datum id) false))
(define (ids hash) (for/list (((k v) hash)) k))
(require (for-template scheme/base))
(define-syntax-rule (let-staged ((n v) ...) body ...)
#`(let-syntax
((m (lambda (stx)
(let ((n v) ...) body ...))))
(m)))