mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-07-05 20:26:39 +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)
|
||||
(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
|
||||
|
||||
(define sc-macro-transformer
|
||||
|
@ -284,6 +290,9 @@
|
|||
(lambda (expr rename compare)
|
||||
`(,(rename 'make-promise) (,(rename 'lambda) () ,(cadr expr))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; promises
|
||||
|
||||
(define (make-promise thunk)
|
||||
(lambda ()
|
||||
(let ((computed? #f) (result #f))
|
||||
|
@ -295,6 +304,9 @@
|
|||
|
||||
(define (force x) (if (procedure? x) (x) x))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; exceptions
|
||||
|
||||
(define (error msg . args)
|
||||
(raise (make-exception 'user msg args #f #f)))
|
||||
|
||||
|
@ -305,6 +317,9 @@
|
|||
(current-exception-handler orig-handler)
|
||||
res)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; library functions
|
||||
|
||||
;; booleans
|
||||
|
||||
(define (not x) (if x #f #t))
|
||||
|
@ -552,6 +567,7 @@
|
|||
(current-output-port old-out)
|
||||
res)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; values
|
||||
|
||||
(define *values-tag* (list 'values))
|
||||
|
@ -567,6 +583,32 @@
|
|||
(apply consumer (cdr 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
|
||||
|
||||
|
@ -748,6 +790,9 @@
|
|||
(list (list _error "no expansion for"
|
||||
(list (rename 'strip-syntactic-closures) _expr)))))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; modules
|
||||
|
||||
(define *config-env* #f)
|
||||
|
||||
(define-syntax import
|
||||
|
@ -771,6 +816,7 @@
|
|||
res))
|
||||
(error "couldn't find module" (car ls))))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; SRFI-0
|
||||
|
||||
(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, "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_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_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),
|
||||
|
|
|
@ -436,6 +436,29 @@
|
|||
(test '(2 3)
|
||||
((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)
|
||||
|
|
Loading…
Add table
Reference in a new issue