(module teachhelp mzscheme (require "firstorder.rkt" "rewrite-error-message.rkt" stepper/private/shared) (require-for-syntax stepper/private/shared) (provide make-undefined-check make-first-order-function) (define (make-undefined-check check-proc tmp-id) (let ([set!-stx (datum->syntax-object check-proc 'set!)]) (make-set!-transformer (lambda (stx) (syntax-case stx () [(set! id expr) (module-identifier=? (syntax set!) set!-stx) (with-syntax ([tmp-id tmp-id]) (syntax/loc stx (set! tmp-id expr)))] [(id . args) (datum->syntax-object check-proc (cons (stepper-syntax-property (datum->syntax-object check-proc (list check-proc (list 'quote (syntax id)) tmp-id)) 'stepper-skipto (append skipto/cdr skipto/third)) (syntax args)) stx)] [id (stepper-syntax-property (datum->syntax-object check-proc (list check-proc (list 'quote (syntax id)) tmp-id) stx) 'stepper-skipto (append skipto/cdr skipto/third))]))))) #; (define (appropriate-use what) (case what [(constructor) "called with values for the structure fields"] [(selector) "applied to a structure to get the field value"] [(predicate procedure) "applied to arguments"])) (define (make-first-order-function what arity orig-id app) (make-set!-transformer (make-first-order (lambda (stx) (syntax-case stx (set!) [(set! . _) (raise-syntax-error #f stx #f "internal error: assignment to first-order function")] [id (identifier? #'id) (raise-syntax-error #f (format "expected a function call, but there is no open parenthesis before this function") stx #f)] [(id . rest) (let ([found (length (syntax->list #'rest))]) (unless (= found arity) (raise-syntax-error #f (argcount-error-message arity found) stx #f)) (datum->syntax-object app (list* app (datum->syntax-object orig-id (syntax-e orig-id) #'id #'id) #'rest) stx stx))])) (syntax-local-introduce orig-id)))))