; param.ss -- a syntactic extension of Scheme for experimenting with ; parameter passing rules: call-by-value, call-by-reference ; call-by-value-result ; VAR datatype -- associates an identifier with a box (extend-syntax (VAR) [(VAR name initval) (define name (box initval))]) (extend-syntax (:=) [(:= var val) (set-box! var val)]) (extend-syntax (^) [(^ var) (unbox var)]) ; LOCALVAR: a let that makes the local variables VARs (extend-syntax (LOCALVAR) [(LOCALVAR ([name initval] ...) body ...) (let ([name (box initval)] ...) body ...)]) ; call-by-reference syntax: when using VAR, call-by-reference becomes ; the default ; proc-by-ref: another name for lambda (extend-syntax (proc-by-ref) [(proc-by-ref (id ...) body ...) (lambda (id ...) body ...)]) ; proc-by-value: formal parameters are VARS bound to the (unboxed) values ; of the actual parameters (extend-syntax (proc-by-value) [(proc-by-value (id ...) body ...) (with ([(newvar ...) (map (lambda (x) (gensym)) '(id ...))]) (lambda (newvar ...) (let ([id (box (^ newvar))] ...) body ...)))]) ; proc-by-value-result: (extend-syntax (proc-by-value-result) [(proc-by-value-result (id ...) body ...) (with ([(newvar ...) (map (lambda (x) (gensym)) '(id ...))]) (lambda (newvar ...) (let ([id (box (^ newvar))] ...) (let ([result (begin body ...)]) (:= newvar (^ id)) ... result))))]) ; while syntax: implements a while loop (for interesting examples) (extend-syntax (while) ((while condition body ...) (let ((while-body (lambda () body ...)) (while-cond (lambda () condition))) (letrec ((loop (lambda () (if (while-cond) (begin (while-body) (loop)) 'done)))) (loop)))))