AtlatestRepositorysigil-markdown
1;;; Differential fuzz corpus for (sigil markdown).
2;;;
3;;; Usage: sigil bench/fuzz.sgl > out.txt
4;;;
5;;; Deterministically generates many small documents drawn from a
6;;; markup-dense alphabet and prints `~s` of (markdown->sxml doc) for each,
7;;; one record per line. Run this against the ORIGINAL parser and the
8;;; optimized parser and diff the two outputs: any divergence is a
9;;; correctness regression the fixed corpus missed. Deterministic (LCG with
10;;; 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 alphabet
18 (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)