settings.scm
#lang scheme/base

;; support for global settings

(require (file "util.scm"))

(provide declare-setting
         setting
         setting-set!)
         
(define SETTING_STORAGE (hash))

(define-syntax declare-setting
  (syntax-rules ()
    ((_ setting-name default-val)
     (setting-set-aux! 'setting-name default-val #t))))

(define-syntax setting
  (syntax-rules ()
    ((_ setting-name)
     (hash-table-get SETTING_STORAGE 'setting-name
                     (lambda () (no-setting-error 'setting-name))))))

(define-syntax setting-set!
  (syntax-rules ()
    ((_ setting-name new-val)
     (setting-set-aux! 'setting-name new-val #f))))

(define (setting-set-aux! key val is-default)
  (let ((does-exist (hash-table-exists? SETTING_STORAGE key)))
    (if (or (and is-default does-exist)
            (and (not is-default) (not does-exist)))
        (no-setting-error key)
        (hash-table-put! SETTING_STORAGE key val))))

(define (no-setting-error setting-name)
  (e "No setting named '~A' exists." setting-name))