;;; Chickadee Game Toolkit ;;; Copyright (C) 2014 Ludovic Courtès ;;; Copyright © 2016 David Thompson ;;; ;;; Chickadee is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published ;;; by the Free Software Foundation, either version 3 of the License, ;;; or (at your option) any later version. ;;; ;;; Chickadee is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see ;;; . (define-module (chickadee utils) #:export (memoize for-range)) ;; Written by Ludovic Courtès. Taken from GNU Guix. (define (memoize proc) "Return a memoizing version of PROC." (let ((cache (make-hash-table))) (lambda args (let ((results (hash-ref cache args))) (if results (apply values results) (let ((results (call-with-values (lambda () (apply proc args)) list))) (hash-set! cache args results) (apply values results))))))) (define-syntax for-range (syntax-rules () ((_ ((var end start inc)) body ...) (let* ((s start) ; evaluate start/end only once (e end) (reverse? (< e s)) (start* (if reverse? e s)) (end* (if reverse? s e)) (inc* (abs inc))) (let loop ((var start*)) (when (< var end*) body ... (loop (+ var inc*)))))) ((_ ((var end start)) body ...) (for-range ((var end start 1)) body ...)) ((_ ((var end)) body ...) (for-range ((var end 0 1)) body ...)) ((_ ((var args ...) rest ...) body ...) (for-range ((var args ...)) (for-range (rest ...) body ...)))))