AtlatestRepositorysigil-markdown
sigil-markdown / tree / benchfuzz.sgl
1
;;; Differential fuzz corpus for (sigil markdown).2
;;;3
;;; Usage: sigil bench/fuzz.sgl > out.txt4
;;;5
;;; Deterministically generates many small documents drawn from a6
;;; markup-dense alphabet and prints `~s` of (markdown->sxml doc) for each,7
;;; one record per line. Run this against the ORIGINAL parser and the8
;;; optimized parser and diff the two outputs: any divergence is a9
;;; correctness regression the fixed corpus missed. Deterministic (LCG with10
;;; a fixed seed), so the two runs are directly comparable.12
(import (sigil markdown)13
(sigil io)14
(sigil string))16
;; Alphabet heavy in inline/block markers plus a little prose.17
(define alphabet18
(list #\a #\b #\space #\* #\_ #\` #\[ #\] #\( #\) #\! #\\ #\#19
#\- #\+ #\| #\: #\~ #\. #\1 #\newline #\space #\a #\space))21
(define alen (length alphabet))23
;; Simple LCG (Numerical Recipes constants); pure, seed threaded explicitly.24
(define (lcg-next state)25
(modulo (+ (* state 1664525) 1013904223) 4294967296))27
(define (nth-char idx)28
(list-ref alphabet (modulo idx alen)))30
;; Build one document of LEN chars starting from SEED; returns (doc . state).31
(define (make-doc seed len)32
(let loop ((k 0) (state seed) (chars '()))33
(if (>= k len)34
(cons (list->string (reverse chars)) state)35
(let ((s2 (lcg-next state)))36
(loop (+ k 1) s2 (cons (nth-char s2) chars))))))38
(define (run seed count max-len)39
(let loop ((i 0) (state seed))40
(when (< i count)41
(let* ((len (+ 1 (modulo state max-len)))42
(r (make-doc state len))43
(doc (car r))44
(state2 (cdr r)))45
(println "~s" (markdown->sxml doc))46
(loop (+ i 1) (lcg-next state2))))))48
;; Several regimes: short markup-dense docs and longer multi-line docs.49
(run 12345 5000 40)50
(run 987654321 4000 120)51
(run 55555 2000 300)