;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;                                                          ;;;;;;;;
;;;;;;  All files in this directory and its subdirectories are  ;;;;;;;;
;;;;;;  copyright 1997, 1998, 1999, 2000, 2002, 2003.           ;;;;;;;;
;;;;;;  by Rafael D. Sorkin.  All rights reserved.              ;;;;;;;;
;;;;;;                                                          ;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; bibliotek.elisp.el           Time-stamp:<2002-Dec-16 22:11:34 15870.38374>
;
; BEWARE  We load this file BEFORE bibliotek.macros, 
; so don't use herein anything from there (such as `deff')!  
;
; This file exists as a separate entity for the sake of compatibility with TCL
; (True Common Lisp).  A function or constant defined here might be useful in
; elisp but cause grief to TCL compilers such as the cmucl or gcl compilers.
; We define here constants like 1/2, which have no elisp meaning as such, since
; it lacks rationals.  Here also are aliases needed to reconcile differences in
; function names between elisp and TCL, as well as other things that just are
; not needed by TCL and can conveniently be kept separately.
; 
; All macros peculiar to elisp should be kept here (or alternatively in
; bibliotek.elisp.coda), since some lisps define them anyway, even if
; they're not part of the Common Lisp standard.
;
; Much of what remains here could go to bibliotek.elisp.coda.el 


;: Roster of macros, functions, aliases, and constants defined 
;|======================================================================
;| 
;|  A whole slew of simple aliases:
;|  	Assoc 		Get 		Member		Delete
;|	Sort 		Defun 		Compile 	Let
;| 	find-symbol 	defconstant 	gc
;|     
;|  Float
;|
;|  realp
;|
;|  Read-from-string (needed since elisp lacks multiple return values)
;|
;|  Some small fractions for elisp (which lacks rationals)
;|
;|  load-safe
;|  stop-loading / stop
;|     :loaded (global vble)
;|
;|  retrieve-error-messages-from
;|
;|  elisp-if (an alias for `if')
;|
;|==========================================================================

;: Check we are really in elisp 

 (unless *elisp* (error " Use { bibliotek.elisp } only with elisp"))


;: A slew of simple aliases 

; The following aliases are meant to allow elisp code to be compatible with
; TCL (true common lisp) conventions.

(defalias 'Defmacro 'defmacro*)
(defalias 'Defun  'defun*)
(defalias 'Defsubst 'defsubst*)
(defalias 'Let    'lexical-let)
(defalias 'macro-function 'symbol-function)

(defalias 'Assoc  'assoc*)
(defalias 'Get    'get*)
(defalias 'Member 'member*)
(defalias 'Delete 'delete*)  
(defalias 'Sort   'sort*)
(defalias 'Compile 'byte-compile)
(defalias 'find-symbol 'intern-soft)
(defalias 'gc 'garbage-collect)

(defmacro defconstant (&rest H)
  " A macro for TCL compatibility."
  `(defconst ,@H))
 ;
 ; (defalias 'defconstant 'defconst)	
 ;
 ; This alias has problems when being loaded after compilation.  In fact, the
 ; elisp compiler can't handle it.  Probably the reason is that in elisp
 ; `defconst' is a special form, not a macro (like in tcl), and the compiler
 ; doesn't know how to handle aliases which are special forms.  (The
 ; interpreter has no trouble, though.)
 ; This is why I made it a macro.

;: Some small fractions for elisp (which lacks rationals) 

(setq  
       1/2 (/  1  2.0)                 
       3/2 (/  3  2.0)
       5/2 (/  5  2.0)
      -1/2 (/ -1  2.0)
      -3/2 (/ -3  2.0)

       1/3 (/  1  3.0)
       2/3 (/  2  3.0)
       4/3 (/  4  3.0)
       5/3 (/  5  3.0) 
      -1/3 (/ -1  3.0)
      -2/3 (/ -2  3.0)

       1/4 (/  1  4.0)
       3/4 (/  3  4.0)
       5/4 (/  5  4.0)

       1/5 (/  1  5.0)
       1/6 (/  1  6.0)       
       1/7 (/  1  7.0)
       1/8 (/  1  8.0)
       1/9 (/  1  9.0)
      1/10 (/  1 10.0)
      1/11 (/  1 11.0)
      1/12 (/  1 12.0)
      1/16 (/  1 16.0)
    -1/360 (/ -1 360.0)
    1/1260 (/  1 1260.0)
   -1/1680 (/ -1 1680.0)
   )

;; These are here because some TCL compilers can't tolerate their presence,
;; even if the form is not evaluated, in particular:
;
;  sun-lisp trouble: the use of fractions like 2/3 as variable names
;  discombobulates the sun-lisp compiler, because it "sees thru"
;  the `(when *elisp* ..)' wrapping. 


;: Some further aliases functions and macros 

(defun Read-from-string (string) 
  " Invokes the corresponding elisp fcn and discards the second return value."
  (car (read-from-string string)))


(defmacro retrieve-error-messages-from (&rest body)
  "\
 Will return the error information if an error occurs.
 Once upon a time, this was useful to see error messages which  
 which overran the echo area, but as of emacs 19.30, it is no
 longer needed for this purpose, because all messages are saved in the
 buffer *Messages*.  However, it's still useful to trap errors (similar 
 to `ignore-errors' in TCL.    \ 
  " 
  `(condition-case error-info
       (progn ,@ body)
        ((error) error-info)))
  ;  
  ; It doesn't retrieve the error message as such, but the symbol naming the
  ; error, together with the other data which would appear in the message.

(defalias 'ignore-errors 'retrieve-error-messages-from)


;; For loading files safely

; Here we define a new "error" condition `loaded'  (belonging to the
; error-symbol `:loaded') and we make `stop-loading' signal this condition.
; Then we make `load-safe' trap this condition and return normally.  If some
; other error condition occurs then `load-safe' signals error.

(put :loaded 'error-conditions '(loaded))
(put :loaded 'error-message "Encountered a call to `stop-loading'")
 
(defun stop-loading (&rest H) 
  "\
 If a file loaded with `load-safe' encounters `(stop-loading)' then loading
 will terminate without an error.  Any args (eg a message) will be displayed.
  "
  (signal :loaded H))

(defalias 'stop 'stop-loading)
 
(defun load-safe (file) 
  "\
 Same as `load' except that it stops loading and returns without error when it
 encounters the form `(stop-loading)'
  "
  (condition-case 
    err-data
      (load file)
    (loaded 
     (assert (eq (car err-data) :loaded))
     (cond
       ((cddr err-data) (format "%s %s" (cadr err-data) (cddr err-data)))
       ((cdr err-data) (format "%s"  (cadr err-data)))
       (t 
	(format "Loaded up to the stop instruction: %s" file))))
    (error (error (format "Error while loading %s: %s" file err-data))))) 


(defalias 'elisp-if 'if)

(defsubst Float(x y) 
  "\
 Same as elisp's `float' but ignores second argument.  Defined only
 for the sake of TCL compatibility.  (defined by `defsubst').
  "  
  (float x))

(defun realp (x) "self explanatory" (typep x 'real))

;: Some dummy functions and macros needed for elisp compatibility 

 ; These are here just to stop compiler warnings, when the compiler sees
 ; code that it doesn't recognize in some bibliotek.

(defun make-string-output-stream (&rest X) "dummy function")
(defun make-string-input-stream  (&rest X) "dummy function")
(defun get-output-stream-string  (&rest X) "dummy function")
(defun read-line                 (&rest X) "dummy function")


;: Other stuff

(defconst :initial-element  ':initial-element
  " a keyword used by TCL that the elisp compiler doesn't know about")
 ;
 ; COMMENTS Without the above, the elisp compiler issues warnings about
 ; :initial-element because it doesn't know about that keyword.
 ; (We say `defconst' here because the alias `defconstant' upsets the compiler,
 ; though not the interpreter) 

;; Let emacs know about some symbols so it will complete them

(defvar *print-length* nil)
(defvar array-element-type nil)

;: End
