Start tracking the listing module.
This commit is contained in:
parent
0d1b429e04
commit
b026949266
2 changed files with 99 additions and 1 deletions
76
listing.scm
Normal file
76
listing.scm
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
(module
|
||||||
|
listing (print-source-listing listing-tests!)
|
||||||
|
|
||||||
|
(import scheme
|
||||||
|
testing
|
||||||
|
(chicken base)
|
||||||
|
(chicken string)
|
||||||
|
(chicken format))
|
||||||
|
|
||||||
|
;; Returns the number of digits required to represent a given number
|
||||||
|
;; in decimal format.
|
||||||
|
(define (number-digits number)
|
||||||
|
(let loop ((number (abs number))
|
||||||
|
(digits 0))
|
||||||
|
(if (= number 0)
|
||||||
|
(if (= digits 0)
|
||||||
|
1
|
||||||
|
digits)
|
||||||
|
(loop (quotient number 10)
|
||||||
|
(+ digits 1)))))
|
||||||
|
|
||||||
|
;; Formats line number padding it with spaces from the left for
|
||||||
|
;; alignment with number of given maximum number of digits and
|
||||||
|
;; appends ordinal dot and space.
|
||||||
|
(define (format-line-number number digits)
|
||||||
|
(let loop ((args (list (sprintf "~A. " number)))
|
||||||
|
(spaces (- digits (number-digits number))))
|
||||||
|
(if (<= spaces 0)
|
||||||
|
(string-intersperse args "")
|
||||||
|
(loop (cons " " args)
|
||||||
|
(- spaces 1)))))
|
||||||
|
|
||||||
|
;; Returns true if given line is near the target line.
|
||||||
|
(define (line-near-target? line target context)
|
||||||
|
(or (< context 0)
|
||||||
|
(<= (abs (- line target)) context)))
|
||||||
|
|
||||||
|
(define (print-source-listing lines highlights context hl-pre hl-post ctx-pre ctx-pre ellipsis)
|
||||||
|
(let ((digits (number-digits (length lines))))
|
||||||
|
(let loop ((lines lines)
|
||||||
|
(number 1))
|
||||||
|
(when (not (null? lines))
|
||||||
|
(print (format-line-number number digits) (car lines))
|
||||||
|
(loop (cdr lines)
|
||||||
|
(+ number 1))))))
|
||||||
|
|
||||||
|
;; Performs self-tests of the listing module.
|
||||||
|
(define (listing-tests!)
|
||||||
|
(run-tests
|
||||||
|
listing
|
||||||
|
(test-eq? number-digits (number-digits 0) 1)
|
||||||
|
(test-eq? number-digits (number-digits 1) 1)
|
||||||
|
(test-eq? number-digits (number-digits 9) 1)
|
||||||
|
(test-eq? number-digits (number-digits 10) 2)
|
||||||
|
(test-eq? number-digits (number-digits 999) 3)
|
||||||
|
(test-equal? format-line-number (format-line-number 5 3) " 5. ")
|
||||||
|
(test-true line-near-target? (line-near-target? 4 5 -1))
|
||||||
|
(test-true line-near-target? (line-near-target? 4 5 1))
|
||||||
|
(test-true line-near-target? (line-near-target? 1 5 10))
|
||||||
|
(test-false line-near-target? (line-near-target? 4 5 0))
|
||||||
|
))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
(import listing)
|
||||||
|
|
||||||
|
(print-source-listing
|
||||||
|
'("asdf" "qwer")
|
||||||
|
'(1)
|
||||||
|
5
|
||||||
|
"\x1b[31;1m" "\x1b[0m"
|
||||||
|
"\x1b[33;1m" "\x1b[0m"
|
||||||
|
"\x1b[30;1m...\x1b[0m")
|
||||||
|
|
||||||
|
(listing-tests!)
|
24
testing.scm
24
testing.scm
|
@ -22,7 +22,7 @@
|
||||||
;;
|
;;
|
||||||
(module
|
(module
|
||||||
testing
|
testing
|
||||||
(test-eq? test-equal? test-exn run-tests)
|
(test-eq? test-equal? test-exn test-true test-false run-tests)
|
||||||
|
|
||||||
(import scheme
|
(import scheme
|
||||||
(chicken condition))
|
(chicken condition))
|
||||||
|
@ -59,6 +59,28 @@
|
||||||
(error 'test-equal? (sprintf "~A expression=~S expected-result=~S result=~S"
|
(error 'test-equal? (sprintf "~A expression=~S expected-result=~S result=~S"
|
||||||
'name 'expression expected-result result)))))))
|
'name 'expression expected-result result)))))))
|
||||||
|
|
||||||
|
;; Test passes if the expression evaluates to #t, raises exception
|
||||||
|
;; otherwise.
|
||||||
|
(define-syntax test-true
|
||||||
|
(syntax-rules ()
|
||||||
|
((_ name expression)
|
||||||
|
(let ((result expression))
|
||||||
|
(if (eq? result #t)
|
||||||
|
(display ".")
|
||||||
|
(error 'test-true (sprintf "~A expression=~S result=~S"
|
||||||
|
'name 'expression result)))))))
|
||||||
|
|
||||||
|
;; Test passes if the expression evaluates to #f, raises exception
|
||||||
|
;; otherwise.
|
||||||
|
(define-syntax test-false
|
||||||
|
(syntax-rules ()
|
||||||
|
((_ name expression)
|
||||||
|
(let ((result expression))
|
||||||
|
(if (eq? result #f)
|
||||||
|
(display ".")
|
||||||
|
(error 'test-true (sprintf "~A expression=~S result=~S"
|
||||||
|
'name 'expression result)))))))
|
||||||
|
|
||||||
;; Passes if the-test raises an exception
|
;; Passes if the-test raises an exception
|
||||||
(define-syntax test-exn
|
(define-syntax test-exn
|
||||||
(syntax-rules ()
|
(syntax-rules ()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue