Welcome to the CHICKEN Scheme pasting service
crunch byte ring buffer added by db7 on Sat Sep 27 09:59:13 2025
#|
chicken-crunch rbuf-example.scm
gcc $(chicken-crunch -cflags) -DCRUNCH_NO_UTF rbuf-example.c
./a.out
|#
(module rbuf
(make-rbuf
rbuf-clear!
rbuf-empty?
rbuf-push!
rbuf-pop!)
(import (scheme base)
(crunch c)
(chicken base)
(crunch memory)
(crunch declarations)
(crunch aggregate-types)
(chicken bitwise))
(: (byte=? byte byte) boolean)
(define byte=? (c-lambda ((byte x) (byte y)) boolean "return x == y;"))
(: (byte+ byte byte) byte)
(define byte+ (c-lambda ((byte x) (byte y)) byte "return (x + y);"))
(: (byte- byte byte) byte)
(define byte- (c-lambda ((byte x) (byte y)) byte "return (x - y);"))
(: (byte->integer byte) integer)
(define byte->integer (c-lambda ((byte x)) integer "return (long) x;"))
(: (integer->byte integer) byte)
(define integer->byte (c-lambda ((integer x)) byte "return (uint8_t) x;"))
(define-struct rbuf
(cap byte)
(head byte)
(tail byte)
(buf bytevector))
(define-compound-accessors (pointer (struct rbuf))
(mk-rbuf cap head tail buf)
(cap rbuf-cap)
(head rbuf-head rbuf-head!)
(tail rbuf-tail rbuf-tail!)
(buf rbuf-buf))
(: (make-rbuf integer) (pointer (struct rbuf)))
(define (make-rbuf cap)
; cap must be power of 2!
(mk-rbuf (integer->byte cap)
(integer->byte 0)
(integer->byte 0)
(make-bytevector cap)))
(: (rbuf-clear! (pointer (struct rbuf))) void)
(define (rbuf-clear! rb)
(rbuf-head! rb 0)
(rbuf-tail! rb 0))
(: (rbuf-push! (pointer (struct rbuf))) boolean)
(define (rbuf-empty? rb)
(= (rbuf-head rb) (rbuf-tail rb)))
(: (next-index byte byte) byte)
(define (next-index idx cap)
(let ((idx (byte+ idx (integer->byte 1)))
(cap (byte- cap (integer->byte 1))))
(integer->byte
(bitwise-and (byte->integer idx)
(byte->integer cap)))))
(: (next-head (pointer (struct rbuf))) byte)
(define (next-head rb)
(next-index (rbuf-head rb) (rbuf-cap rb)))
(: (rbuf-push! (pointer (struct rbuf)) byte) boolean)
(define (rbuf-push! rb value)
(let* ((nhead (next-head rb))
(full (byte=? (rbuf-tail rb) nhead)))
(unless full
(bytevector-u8-set! (rbuf-buf rb)
(byte->integer (rbuf-head rb))
(byte->integer value))
(rbuf-head! rb nhead))
(not full)))
(: (next-tail (pointer (struct rbuf))) byte)
(define (next-tail rb)
(next-index (rbuf-tail rb) (rbuf-cap rb)))
(: (rbuf-pop! (pointer (struct rbuf))) byte)
(define (rbuf-pop! rb)
(if (rbuf-empty? rb)
(integer->byte 0)
(let ((ntail (next-tail rb))
(value (bytevector-u8-ref (rbuf-buf rb)
(byte->integer (rbuf-tail rb)))))
(rbuf-tail! rb ntail)
value)))
)
(import (scheme base)
(scheme write)
(chicken syntax)
(crunch c)
(crunch declarations)
rbuf)
(define-syntax print
(syntax-rules ()
((_ VAL ...)
(begin
(begin (display VAL) (display " "))
...
(newline)))))
(define (main)
(let ((rb (make-rbuf 8)))
(print "(empty? rb) =>" (rbuf-empty? rb))
(print "(push! rb 123) =>" (rbuf-push! rb 123))
(print "(empty? rb) =>" (rbuf-empty? rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(empty? rb) =>" (rbuf-empty? rb))
(print "(push! rb 1) =>" (rbuf-push! rb 1))
(print "(push! rb 2) =>" (rbuf-push! rb 2))
(print "(push! rb 3) =>" (rbuf-push! rb 3))
(print "(push! rb 4) =>" (rbuf-push! rb 4))
(print "(push! rb 5) =>" (rbuf-push! rb 5))
(print "(push! rb 6) =>" (rbuf-push! rb 6))
(print "(push! rb 7) =>" (rbuf-push! rb 7))
(print "(push! rb 8) =>" (rbuf-push! rb 8))
(print "(push! rb 1) =>" (rbuf-push! rb 9))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(pop! rb) =>" (rbuf-pop! rb))
(print "(empty? rb) =>" (rbuf-empty? rb))))