Work on new cal-period.

This commit is contained in:
Dominik Pantůček 2023-05-09 19:38:50 +02:00
parent b55c031481
commit 54712827bd
2 changed files with 46 additions and 36 deletions

View file

@ -364,3 +364,9 @@ UTIL-GIT-SOURCES=util-git.scm util-io.import.scm \
util-git.o: util-git.import.scm util-git.o: util-git.import.scm
util-git.import.scm: $(UTIL-GIT-SOURCES) util-git.import.scm: $(UTIL-GIT-SOURCES)
CAL-MONTH-SOURCES=cal-month.scm util-tag.import.scm \
testing.import.scm
cal-month.o: cal-month.import.scm
cal-month.import.scm: $(CAL-MONTH-SOURCES)

View file

@ -62,7 +62,11 @@
(chicken string) (chicken string)
cal-month cal-month
testing testing
configuration) configuration
util-tag)
;; Type tag
(define TAG-CAL-PERIOD (make-tag CAL-PERIOD))
;; Current month - if changed, we get the actual state for given month. ;; Current month - if changed, we get the actual state for given month.
(define *current-month* (define *current-month*
@ -73,19 +77,19 @@
;; Creates a new period value with optional since and before ;; Creates a new period value with optional since and before
;; comments. ;; comments.
(define (make-period since before . args) (define (make-cal-period since before . args)
(let ((scomment (if (not (null? args)) (car args) #f)) (let ((scomment (if (not (null? args)) (car args) #f))
(bcomment (if (and (not (null? args)) (bcomment (if (and (not (null? args))
(not (null? (cdr args)))) (not (null? (cdr args))))
(cadr args) (cadr args)
#f))) #f)))
(list since before scomment bcomment))) (list TAG-CAL-PERIOD since before scomment bcomment)))
;; Simple accessors ;; Simple accessors
(define period-since car) (define cal-period-since cadr)
(define period-before cadr) (define cal-period-before caddr)
(define period-scomment caddr) (define cal-period-scomment cadddr)
(define period-bcomment cadddr) (define cal-period-bcomment (compose cadddr cdr))
;; Sorts period markers (be it start or end) chronologically and ;; Sorts period markers (be it start or end) chronologically and
;; returns the sorted list. ;; returns the sorted list.
@ -95,15 +99,15 @@
(month<? (cadr a) (cadr b))))) (month<? (cadr a) (cadr b)))))
;; Converts list of start/stop markers to list of pairs of months - ;; Converts list of start/stop markers to list of pairs of months -
;; periods. ;; periods. The markers are lists in the form (start/stop cal-month).
(define (period-markers->periods l) (define (period-markers->cal-periods l)
(let loop ((l (sort-period-markers l)) (let loop ((l (sort-period-markers l))
(ps '()) (ps '())
(cb #f)) (cb #f))
(if (null? l) (if (null? l)
(list #t (list #t
(if cb (if cb
(reverse (cons (make-period (car cb) #f (cadr cb)) ps)) (reverse (cons (make-cal-period (car cb) #f (cadr cb)) ps))
(reverse ps)) (reverse ps))
"" ""
-1) -1)
@ -121,7 +125,7 @@
(if (eq? mtype rmt) (if (eq? mtype rmt)
(if cb (if cb
(loop (cdr l) (loop (cdr l)
(cons (make-period (car cb) month (cadr cb) comment) ps) (cons (make-cal-period (car cb) month (cadr cb) comment) ps)
#f) #f)
(loop (cdr l) (loop (cdr l)
ps ps
@ -133,91 +137,91 @@
;; Returns duration of period in months. Start is included, end is ;; Returns duration of period in months. Start is included, end is
;; not. The period contains the month just before the specified end. ;; not. The period contains the month just before the specified end.
(define (period->duration p) (define (cal-period->duration p)
(let* ((b (period-since p)) (let* ((b (cal-period-since p))
(e (period-before p)) (e (cal-period-before p))
(e- (if e e (*current-month*)))) (e- (if e e (*current-month*))))
(month-diff b e-))) (cal-month-diff b e-)))
;; Returns sum of periods lengths. ;; Returns sum of periods lengths.
(define (periods-duration l) (define (cal-periods-duration l)
(apply + (map period->duration l))) (apply + (map cal-period->duration l)))
;; True if month belongs to given month period - start inclusive, end ;; True if month belongs to given month period - start inclusive, end
;; exclusive. ;; exclusive.
(define (month-in-period? p . ml) (define (cal-month-in-period? p . ml)
(let ((m (if (null? ml) (let ((m (if (null? ml)
(*current-month*) (*current-month*)
(car ml)))) (car ml))))
(and (or (not (period-before p)) (and (or (not (cal-period-before p))
(month<? m (period-before p))) (cal-month<? m (cal-period-before p)))
(not (month<? m (period-since p)))))) (not (cal-month<? m (cal-period-since p))))))
;; Returns true if given month is in at least one of the periods ;; Returns true if given month is in at least one of the periods
;; given. Defaults to current month. ;; given. Defaults to current month.
(define (month-in-periods? ps . ml) (define (cal-month-in-periods? ps . ml)
(let ((m (if (null? ml) (let ((m (if (null? ml)
(*current-month*) (*current-month*)
(car ml)))) (car ml))))
(let loop ((ps ps)) (let loop ((ps ps))
(if (null? ps) (if (null? ps)
#f #f
(if (month-in-period? (car ps) m) (if (cal-month-in-period? (car ps) m)
#t #t
(loop (cdr ps))))))) (loop (cdr ps)))))))
;; Returns string representing a month period with possibly open end. ;; Returns string representing a month period with possibly open end.
(define (period->string p) (define (cal-period->string p)
(sprintf "~A..~A" (sprintf "~A..~A"
(month->string (period-since p)) (cal-month->string (cal-period-since p))
(month->string (period-before p)))) (cal-month->string (cal-period-before p))))
;; Returns a string representing a list of periods. ;; Returns a string representing a list of periods.
(define (periods->string ps) (define (cal-periods->string ps)
(string-intersperse (string-intersperse
(map period->string ps) (map cal-period->string ps)
", ")) ", "))
;; Finds a period the month matches and returns it. If no period ;; Finds a period the month matches and returns it. If no period
;; matches, it returns #f. ;; matches, it returns #f.
(define (periods-match ps . ml) (define (cal-periods-match ps . ml)
(let ((m (if (null? ml) (*current-month*) (car ml)))) (let ((m (if (null? ml) (*current-month*) (car ml))))
(let loop ((ps ps)) (let loop ((ps ps))
(if (null? ps) (if (null? ps)
#f #f
(if (month-in-period? (car ps) m) (if (cal-month-in-period? (car ps) m)
(car ps) (car ps)
(loop (cdr ps))))))) (loop (cdr ps)))))))
;; Creates lookup table from definition source ;; Creates lookup table from definition source
(define (make-period-lookup-table source) (define (make-cal-period-lookup-table source)
(let loop ((lst source) (let loop ((lst source)
(res '()) (res '())
(prev #f)) (prev #f))
(if (null? lst) (if (null? lst)
(reverse (reverse
(cons (cons (make-period (car prev) #f) (cons (cons (make-cal-period (car prev) #f)
(cdr prev)) (cdr prev))
res)) res))
(loop (cdr lst) (loop (cdr lst)
(if prev (if prev
(cons (cons (make-period (car prev) (caar lst)) (cons (cons (make-cal-period (car prev) (caar lst))
(cdr prev)) (cdr prev))
res) res)
res) res)
(car lst))))) (car lst)))))
;; Looks up current month and returns associated definitions ;; Looks up current month and returns associated definitions
(define (lookup-by-period table) (define (lookup-by-cal-period table)
(let loop ((lst table)) (let loop ((lst table))
(if (null? lst) (if (null? lst)
#f #f
(if (month-in-period? (caar lst)) (if (cal-month-in-period? (caar lst))
(cdar lst) (cdar lst)
(loop (cdr lst)))))) (loop (cdr lst))))))
;; Performs self-tests of the period module. ;; Performs self-tests of the period module.
(define (period-tests!) (define (cal-period-tests!)
(run-tests (run-tests
period period
(test-equal? sort-period-markers (test-equal? sort-period-markers