;; data/init.scm - Sizzle initialization file.
;;
;; Copyright (C) 2000 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
;;
;; This 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 2, or (at your option)
;; any later version.
;; 
;; This software 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 package; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.  


(define 1+
  (lambda (n) (+ n 1)))
(define 1-
  (lambda (n) (- n 1)))

(define add1 1+)
(define sub1 1-)

;; Configuration parameters ==========================================

(define %sizzle-major-version% #f)
(define %sizzle-minor-version% #f)
(define %sizzle-patchlevel% #f)
(let ((version-list (map string->number (string-split #\. %sizzle-version%))))
  (set! %sizzle-major-version% (car version-list))
  (set! %sizzle-minor-version% (cadr version-list))
  (set! %sizzle-patchlevel% (caddr version-list)))

;; Read-line procedure taken from Guile's boot-9.scm =================

(define (read-line . args)
  (let* ((port		(if (null? args)
			    (current-input-port)
			    (car args)))
	 (handle-delim	(if (> (length args) 1)
			    (cadr args)
			    'trim))
	 (line/delim	(%read-line port))
	 (line		(car line/delim))
	 (delim		(cdr line/delim)))
    (case handle-delim
      ((trim) line)
      ((split) line/delim)
      ((concat) (if (and (string? line) (char? delim))
		    (string-append line (string delim))
		    line))
      ((peek) (if (char? delim)
		  (unread-char delim port))
	      line)
      (else
       (error "unexpected handle-delim value: " handle-delim)))))

;; Some useful macro definitions =====================================

":doc
when
(when test stmt ...)
If @var{test} evaluates to a true value, all @var{stmt}s are executed in
order.  The returned value is undefined if the @var{stmt}s are not evaluated,
otherwise the value of the last statement is returned.
doc:"
(define-macro (when test . stmts)
  `(if ,test (begin (if #f #f) ,@stmts)))

":doc
unless
(unless test stmt ...) => *anything*
If @var{test} evaluates to the false value, all @var{stmt}s are executed in
order.  The returned value is undefined if the @var{stmt}s are not evaluated,
otherwise the value of the last statement is returned.
doc:"
(define-macro (unless test . stmts)
  `(if (not ,test) (begin (if #f #f) ,@stmts)))

":doc
false-if-exception
(false-if-exception expr) => *anything*
Evaluate the expression @var{expr} and return its value.  When @var{expr}
raises an exception, return the false value @code{#f}.
order.
doc:"
(define-macro (false-if-exception expr)
  `(catch #t (lambda () ,expr) (lambda x #f)))

":doc
while
(while test stmt...) => *anything*
Evaluate @var{test} and if it evaluates to a true value, evaluate the
@var{stmt}s in order.  Repeat this until @var{test} returns @code{#f}.
Inside the @var{stmt}s, the procedures @code{break} and @code{continue} are
defined, which exit the innermost enclosing while statement and restart
the loop.  Normally, the result of the last statement is returned.
doc:"
":doc
break
(break value) => *noreturn*
Return from the enclosing while statement and make it return the value
@var{value}.
doc:"
":doc
continue
(continue) => *noreturn*
Restart the enclosing while loop with the condition.
doc:"
(define-macro (while cond . stmts)
  `(letrec ((continue (lambda ()
                        (or (not ,cond)
                            (begin ,@stmts (continue)))))
            (break (lambda val (apply throw 'break val))))
     (catch 'break
            (lambda () (continue))
            (lambda v (cadr v)))))

;; Binding from SRFI-8 ===============================================

;(define-syntax receive
;  (syntax-rules ()
;    ((receive formals expression body ...)
;     (call-with-values (lambda () expression)
;       (lambda formals body ...)))))

":doc
receive
(receive (var0 ...) expr body ...)
Evaluate @var{expr} and bind all values returned to the variables @var{var0}
...@var{varn}. Then execute the @var{body} expressions.
doc:"
(define-macro (receive formals expression . body)
  `(call-with-values (lambda () ,expression) (lambda ,formals ,@body)))
