mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-07-06 04:36:38 +02:00
somewhat reluctantly adding dynamic-wind
This commit is contained in:
parent
4e5889a6f4
commit
a1941ff08a
3 changed files with 70 additions and 1 deletions
46
lib/init.scm
46
lib/init.scm
|
@ -89,6 +89,12 @@
|
||||||
(define (every pred ls)
|
(define (every pred ls)
|
||||||
(if (pair? ls) (if (pred (car ls)) (every pred (cdr ls)) #f) #t))
|
(if (pair? ls) (if (pred (car ls)) (every pred (cdr ls)) #f) #t))
|
||||||
|
|
||||||
|
(define (delq x ls)
|
||||||
|
(if (pair? ls)
|
||||||
|
(if (eq? x (car ls)) (delq x (cdr ls)) (cons (car ls) (delq x (cdr ls))))
|
||||||
|
'()))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; syntax
|
;; syntax
|
||||||
|
|
||||||
(define sc-macro-transformer
|
(define sc-macro-transformer
|
||||||
|
@ -284,6 +290,9 @@
|
||||||
(lambda (expr rename compare)
|
(lambda (expr rename compare)
|
||||||
`(,(rename 'make-promise) (,(rename 'lambda) () ,(cadr expr))))))
|
`(,(rename 'make-promise) (,(rename 'lambda) () ,(cadr expr))))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; promises
|
||||||
|
|
||||||
(define (make-promise thunk)
|
(define (make-promise thunk)
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(let ((computed? #f) (result #f))
|
(let ((computed? #f) (result #f))
|
||||||
|
@ -295,6 +304,9 @@
|
||||||
|
|
||||||
(define (force x) (if (procedure? x) (x) x))
|
(define (force x) (if (procedure? x) (x) x))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; exceptions
|
||||||
|
|
||||||
(define (error msg . args)
|
(define (error msg . args)
|
||||||
(raise (make-exception 'user msg args #f #f)))
|
(raise (make-exception 'user msg args #f #f)))
|
||||||
|
|
||||||
|
@ -305,6 +317,9 @@
|
||||||
(current-exception-handler orig-handler)
|
(current-exception-handler orig-handler)
|
||||||
res)))
|
res)))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; library functions
|
||||||
|
|
||||||
;; booleans
|
;; booleans
|
||||||
|
|
||||||
(define (not x) (if x #f #t))
|
(define (not x) (if x #f #t))
|
||||||
|
@ -552,6 +567,7 @@
|
||||||
(current-output-port old-out)
|
(current-output-port old-out)
|
||||||
res)))
|
res)))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; values
|
;; values
|
||||||
|
|
||||||
(define *values-tag* (list 'values))
|
(define *values-tag* (list 'values))
|
||||||
|
@ -567,6 +583,32 @@
|
||||||
(apply consumer (cdr res))
|
(apply consumer (cdr res))
|
||||||
(consumer res))))
|
(consumer res))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; dynamic-wind
|
||||||
|
|
||||||
|
(define *dk* (list #f))
|
||||||
|
|
||||||
|
(define (dynamic-wind before thunk after)
|
||||||
|
(let ((dk *dk*))
|
||||||
|
(set-dk! (cons (cons before after) dk))
|
||||||
|
(let ((res (thunk))) (set-dk! dk) res)))
|
||||||
|
|
||||||
|
(define (set-dk! dk)
|
||||||
|
(if (not (eq? dk *dk*))
|
||||||
|
(begin
|
||||||
|
(set-dk! (cdr dk))
|
||||||
|
(let ((before (car (car dk))) (dk dk))
|
||||||
|
(set-car! *dk* (cons (cdr (car dk)) before))
|
||||||
|
(set-cdr! *dk* dk)
|
||||||
|
(set-car! dk #f)
|
||||||
|
(set-cdr! dk '())
|
||||||
|
(set! *dk* dk)
|
||||||
|
(before)))))
|
||||||
|
|
||||||
|
(define (call-with-current-continuation proc)
|
||||||
|
(let ((dk *dk*))
|
||||||
|
(%call/cc (lambda (k) (proc (lambda (x) (set-dk! dk) (k x)))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; syntax-rules
|
;; syntax-rules
|
||||||
|
|
||||||
|
@ -748,6 +790,9 @@
|
||||||
(list (list _error "no expansion for"
|
(list (list _error "no expansion for"
|
||||||
(list (rename 'strip-syntactic-closures) _expr)))))))))))
|
(list (rename 'strip-syntactic-closures) _expr)))))))))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; modules
|
||||||
|
|
||||||
(define *config-env* #f)
|
(define *config-env* #f)
|
||||||
|
|
||||||
(define-syntax import
|
(define-syntax import
|
||||||
|
@ -771,6 +816,7 @@
|
||||||
res))
|
res))
|
||||||
(error "couldn't find module" (car ls))))))))))
|
(error "couldn't find module" (car ls))))))))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; SRFI-0
|
;; SRFI-0
|
||||||
|
|
||||||
(define-syntax cond-expand
|
(define-syntax cond-expand
|
||||||
|
|
|
@ -63,7 +63,7 @@ _OP(SEXP_OPC_TYPE_PREDICATE, SEXP_OP_TYPEP, 1, 0, 0, 0, 0, "opcode?", sexp_make
|
||||||
_OP(SEXP_OPC_TYPE_PREDICATE, SEXP_OP_TYPEP, 1, 0, 0, 0, 0, "input-port?", sexp_make_fixnum(SEXP_IPORT), 0),
|
_OP(SEXP_OPC_TYPE_PREDICATE, SEXP_OP_TYPEP, 1, 0, 0, 0, 0, "input-port?", sexp_make_fixnum(SEXP_IPORT), 0),
|
||||||
_OP(SEXP_OPC_TYPE_PREDICATE, SEXP_OP_TYPEP, 1, 0, 0, 0, 0, "output-port?", sexp_make_fixnum(SEXP_OPORT), 0),
|
_OP(SEXP_OPC_TYPE_PREDICATE, SEXP_OP_TYPEP, 1, 0, 0, 0, 0, "output-port?", sexp_make_fixnum(SEXP_OPORT), 0),
|
||||||
_OP(SEXP_OPC_GENERIC, SEXP_OP_APPLY1, 2, 0, SEXP_PROCEDURE, SEXP_PAIR, 0, "apply1", 0, NULL),
|
_OP(SEXP_OPC_GENERIC, SEXP_OP_APPLY1, 2, 0, SEXP_PROCEDURE, SEXP_PAIR, 0, "apply1", 0, NULL),
|
||||||
_OP(SEXP_OPC_GENERIC, SEXP_OP_CALLCC, 1, SEXP_PROCEDURE, 0, 0, 0, "call-with-current-continuation", 0, NULL),
|
_OP(SEXP_OPC_GENERIC, SEXP_OP_CALLCC, 1, SEXP_PROCEDURE, 0, 0, 0, "%call/cc", 0, NULL),
|
||||||
_OP(SEXP_OPC_GENERIC, SEXP_OP_RAISE, 1, SEXP_STRING, 0, 0, 0, "raise", 0, NULL),
|
_OP(SEXP_OPC_GENERIC, SEXP_OP_RAISE, 1, SEXP_STRING, 0, 0, 0, "raise", 0, NULL),
|
||||||
_OP(SEXP_OPC_IO, SEXP_OP_WRITE_CHAR, 1, 3, 0, SEXP_OPORT, 0, "write-char", (sexp)"*current-output-port*", NULL),
|
_OP(SEXP_OPC_IO, SEXP_OP_WRITE_CHAR, 1, 3, 0, SEXP_OPORT, 0, "write-char", (sexp)"*current-output-port*", NULL),
|
||||||
_OP(SEXP_OPC_IO, SEXP_OP_NEWLINE, 0, 3, 0, SEXP_OPORT, 0, "newline", (sexp)"*current-output-port*", NULL),
|
_OP(SEXP_OPC_IO, SEXP_OP_NEWLINE, 0, 3, 0, SEXP_OPORT, 0, "newline", (sexp)"*current-output-port*", NULL),
|
||||||
|
|
|
@ -436,6 +436,29 @@
|
||||||
(test '(2 3)
|
(test '(2 3)
|
||||||
((lambda () (let ((x 1)) (let ((y x)) (set! x 2) (set! y 3) (list x y))))))
|
((lambda () (let ((x 1)) (let ((y x)) (set! x 2) (set! y 3) (list x y))))))
|
||||||
|
|
||||||
|
(test '(a b c)
|
||||||
|
(let* ((path '())
|
||||||
|
(add (lambda (s) (set! path (cons s path)))))
|
||||||
|
(dynamic-wind (lambda () (add 'a)) (lambda () (add 'b)) (lambda () (add 'c)))
|
||||||
|
(reverse path)))
|
||||||
|
|
||||||
|
(test '(connect talk1 disconnect connect talk2 disconnect)
|
||||||
|
(let ((path '())
|
||||||
|
(c #f))
|
||||||
|
(let ((add (lambda (s)
|
||||||
|
(set! path (cons s path)))))
|
||||||
|
(dynamic-wind
|
||||||
|
(lambda () (add 'connect))
|
||||||
|
(lambda ()
|
||||||
|
(add (call-with-current-continuation
|
||||||
|
(lambda (c0)
|
||||||
|
(set! c c0)
|
||||||
|
'talk1))))
|
||||||
|
(lambda () (add 'disconnect)))
|
||||||
|
(if (< (length path) 4)
|
||||||
|
(c 'talk2)
|
||||||
|
(reverse path)))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(test-report)
|
(test-report)
|
||||||
|
|
Loading…
Add table
Reference in a new issue