(define spec-compute-stats
  (fn
    (sections source)
    (let
      ((total 0)
        (pure 0)
        (mutation 0)
        (io 0)
        (render 0)
        (lines (len (split source "\n"))))
      (for-each
        (fn
          (section)
          (for-each
            (fn
              (d)
              (set! total (inc total))
              (if
                (empty? (get d "effects"))
                (set! pure (inc pure))
                (for-each
                  (fn
                    (eff)
                    (cond
                      (= eff "mutation")
                      (set! mutation (inc mutation))
                      (= eff "io")
                      (set! io (inc io))
                      (= eff "render")
                      (set! render (inc render))))
                  (get d "effects"))))
            (get section "defines")))
        sections)
      {:lines lines :io-count io :render-count render :pure-count pure :mutation-count mutation :test-total 0 :total-defines total})))
