3 (define-macro (cond . a)
4 (if (null? a) '(if #f #f)
5 (cond ((eq? (caar a) 'else) `(begin . ,(cdar a)))
6 ((and (not (null? (cdar a))) (eq? (cadar a) '=>))
9 (if ,x (,(caddar a) ,x) (cond . ,(cdr a))))))
10 (else `(if ,(caar a) (begin . ,(cdar a)) (cond . ,(cdr a)))))))
12 (define-macro (case a . cs)
15 (cond . ,(map (lambda (c)
16 (if (eq? (car c) 'else) c
17 `((memv ,x ',(car c)) . ,(cdr c))))
27 (#%+-aux (#%+ x (#%car rest)) (#%cdr rest))
33 (#%+-aux (#%+ x (#%car rest)) (#%cdr rest))
39 (#%--aux (#%- x (#%car rest)) (#%cdr rest))
45 (#%--aux (#%- x (#%car rest)) (#%cdr rest))
51 (#%*-aux (#%* x (#%car rest)) (#%cdr rest))
57 (#%*-aux (#%* x (#%car rest)) (#%cdr rest))
78 (or (#%< x y) (#%= x y))))
86 (or (#%> x y) (#%= x y))))
129 (#%length-aux lst 0)))
134 (#%length-aux (cdr lst) (#%+ n 1))
140 (#%cons (#%car lst1) (append (#%cdr lst1) lst2))
145 (reverse-aux lst '())))
150 (reverse-aux (#%cdr lst) (#%cons (#%car lst) rev))
157 (list-ref (#%cdr lst) (#%- i 1)))))
163 (list-set! (#%cdr lst) (#%- i 1) x))))
175 (if (#%< x 0) (#%neg x) x)))
181 (define #%box (lambda (a) (#%cons a '())))
183 (define #%unbox (lambda (a) (#%car a)))
185 (define #%box-set! (lambda (a b) (#%set-car! a b)))
189 (#%list->string chars)))
193 (#%string->list str)))
197 (#%list->string chars)))
199 (define string-length ;; TODO are all these string operations efficient ? they all convert to lists. use true vectors when we have them ?
201 (length (#%string->list str))))
203 (define string-append
205 (#%list->string (append (#%string->list str1) (#%string->list str2)))))
208 (lambda (str start end)
211 (#%substring-aux1 (#%string->list str) start)
214 (define #%substring-aux1
217 (#%substring-aux1 (#%cdr lst) (#%- n 1))
220 (define #%substring-aux2
223 (#%cons (#%car lst) (#%substring-aux2 (#%cdr lst) (#%- n 1)))
229 (#%cons (f (#%car lst))
238 (for-each f (#%cdr lst)))
243 (let ((k (#%get-cont)))
246 (#%return-to-cont k r))))))
251 (define start-first-process
253 (set! root-k (#%get-cont))
254 (set! readyq (#%cons #f #f))
255 (#%set-cdr! readyq readyq)
260 (let* ((k (#%get-cont))
261 (next (#%cons k (#%cdr readyq))))
262 (#%set-cdr! readyq next)
263 (#%graft-to-cont root-k thunk))))
267 (let ((next (#%cdr readyq)))
268 (if (#%eq? next readyq)
271 (#%set-cdr! readyq (#%cdr next))
272 (#%return-to-cont (#%car next) #f))))))
276 (let ((k (#%get-cont)))
277 (#%set-car! readyq k)
278 (set! readyq (#%cdr readyq))
279 (let ((next-k (#%car readyq)))
280 (#%set-car! readyq #f)
281 (#%return-to-cont next-k #f)))))
288 (lambda (freq-div duration)
289 (#%beep freq-div duration)))
309 (or (#%getchar-wait 0 3)
314 (#%getchar-wait duration 3)))
318 (#%sleep-aux (#%+ (#%clock) duration))))
322 (if (#%< (#%clock) wake-up)
323 (#%sleep-aux wake-up)
332 (lambda (id duty period)
333 (#%led id duty period)))
337 (if (#%eq? state 'red)
344 (for-each putchar (#%string->list x))
350 (begin (#%putchar #\" 3)
354 (display (number->string x)))
356 (begin (#%putchar #\( 3)
358 (#%write-list (#%cdr x))))
360 (display "#<symbol>"))
362 (display "#<object>")))))
363 ;; TODO have vectors and co ?
370 (begin (#%putchar #\space 3)
372 (#%write-list (#%cdr lst))))
374 (begin (display " . ")
376 (#%putchar #\) 3))))))
378 (define number->string
382 (#%cons #\- (#%number->string-aux (#%neg n) '()))
383 (#%number->string-aux n '())))))
385 (define #%number->string-aux
387 (let ((rest (#%cons (#%+ #\0 (#%remainder n 10)) lst)))
390 (#%number->string-aux (#%quotient n 10) rest)))))
395 (#%putchar #\newline 3)))
411 (#%car (#%car (#%car p)))))
414 (#%car (#%car (#%cdr p)))))
417 (#%car (#%cdr (#%car p)))))
420 (#%car (#%cdr (#%cdr p)))))
423 (#%cdr (#%car (#%car p)))))
426 (#%cdr (#%car (#%cdr p)))))
429 (#%cdr (#%cdr (#%car p)))))
432 (#%cdr (#%cdr (#%cdr p)))))
438 ((and (#%pair? x) (#%pair? y))
439 (and (equal? (#%car x) (#%car y))
440 (equal? (#%cdr x) (#%cdr y))))
441 ((and (#%u8vector? x) (#%u8vector? y))
442 (u8vector-equal? x y))
446 (define u8vector-equal?
448 (let ((lx (#%u8vector-length x)))
449 (if (#%= lx (#%u8vector-length y))
450 (u8vector-equal?-loop x y lx)
452 (define u8vector-equal?-loop
456 (and (#%= (#%u8vector-ref x l) (#%u8vector-ref y l))
457 (u8vector-equal?-loop x y (#%- l 1)))))) ;; TODO test this
466 (assoc t (#%cdr l))))))
468 ;; TODO ordinary vectors are never more that 6 elements long in the stack, so implementing them as lists is acceptable
470 (define vector-ref list-ref)
471 (define vector-set! list-set!)
473 (define bitwise-ior (lambda (x y) (#%ior x y)))
474 (define bitwise-xor (lambda (x y) (#%xor x y)))
475 ;; TODO add bitwise-and ? bitwise-not ?
477 (define current-time (lambda () (#%clock)))
478 (define time->seconds (lambda (t) (#%quotient t 100))) ;; TODO no floats, is that a problem ?
483 (define list->u8vector ;; TODO not used except for server
485 (let* ((n (length x))
486 (v (#%make-u8vector n 0)))
487 (list->u8vector-loop v 0 x)
489 (define list->u8vector-loop
491 (#%u8vector-set! v n (#%car x))
492 (if (#%not (#%null? (#%cdr x)))
493 (list->u8vector-loop v (#%+ n 1) (#%cdr x)))))
494 (define u8vector-length (lambda (x) (#%u8vector-length x)))
495 (define u8vector-ref (lambda (x y) (#%u8vector-ref x y)))
496 (define u8vector-set! (lambda (x y z) (#%u8vector-set! x y z)))
497 ;; (define make-u8vector
499 ;; (let ((v (#%make-u8vector n)))
500 ;; (make-u8vector-loop v (#%- n 1) x)
502 (define make-u8vector
504 (#%make-u8vector n x)))
505 ;; (define make-u8vector-loop
507 ;; ;;; (display "ok:")
509 ;; ;;; (display "\n")
510 ;; (if (>= n 0) (#%u8vector-set! v n x)) ;; TODO safety, should not be needed
512 ;; (begin ;; (display "loop\n")
513 ;; (make-u8vector-loop v (#%- n 1) x)))))
514 ;; ;; TODO with named lets ?