marketplace-2014/lang/base.rkt

69 lines
2.3 KiB
Racket

#lang racket/base
(require (for-syntax racket/base))
(require (for-syntax racket/pretty))
(require "../sugar-untyped.rkt")
(require "../drivers/tcp-bare.rkt")
(require "../support/spy.rkt")
(provide (rename-out [module-begin #%module-begin])
(except-out (all-from-out racket/base) #%module-begin)
(all-from-out "../sugar-untyped.rkt")
(all-from-out "../drivers/tcp-bare.rkt")
(all-from-out "../support/spy.rkt")
stateless)
(define stateless (void))
(define-syntax (module-begin stx)
(unless (eq? (syntax-local-context) 'module-begin)
(raise-syntax-error #f "allowed only around a module body" stx))
(syntax-case stx ()
[(_ forms ...)
(let ()
(define (accumulate-actions action-ids final-forms forms)
(if (null? forms)
(let ((final-stx
#`(#%module-begin #,@(reverse final-forms)
(ground-vm tcp #,@(reverse action-ids)))))
;;(pretty-print (syntax->datum final-stx))
final-stx)
(syntax-case (local-expand (car forms)
'module
(syntax->list #'(quote
quote-syntax #%top
lambda case-lambda
let-values letrec-values
begin begin0 set!
with-continuation-mark
if #%app #%expression
define-values define-syntaxes
begin-for-syntax
module module*
#%module-begin
#%require #%provide
#%variable-reference))) ()
[(head rest ...)
(if (free-identifier=? #'head #'begin)
(accumulate-actions action-ids
final-forms
(append (syntax->list #'(rest ...)) forms))
(if (ormap (lambda (i) (free-identifier=? #'head i))
(syntax->list #'(define-values define-syntaxes begin-for-syntax
module module*
#%module-begin
#%require #%provide)))
(accumulate-actions action-ids
(cons (car forms) final-forms)
(cdr forms))
(accumulate-action (car forms) action-ids final-forms (cdr forms))))]
[non-pair-syntax
(accumulate-action (car forms) action-ids final-forms (cdr forms))])))
(define (accumulate-action action action-ids final-forms remaining-forms)
(define temp (car (generate-temporaries (list action))))
(accumulate-actions (cons temp action-ids)
(cons #`(define #,temp #,action) final-forms)
remaining-forms))
(accumulate-actions '() '() (syntax->list #'(forms ...))))]))