;;; -*- Mode:Lisp; Package:DYPAR; Base:10; -*-

;;; ----------------------------------------------------------------
;;;
;;; 		(c) Copyright, 1989,
;;; 			by Mark Boggs and
;;;                     Jesus Gonzalez Boticario para
;;;                     Rank Xerox Espa¤a S.A.
;;; 			All rights reserved
;;;
;;; ----------------------------------------------------------------

;;; BABEL.LSP

;;; HISTORY
; 23-Feb-01 Moises Gil&Nuria Ripoll
;	Cambiamos de nombe la funcion "erase-gra" por "erasegra"
;
; 28-Jan-89  Mark Boggs (boggs) at Rank Xerox, Spain
;	Created.

;;; This file is a general repository for terminal output messages used by
;;; Dypar.  Those messages are named after the function which calls them.
;;; The purpose behind storing them here is to simplify the task of porting
;;; Dypar to other human languages.

;;; The files which are effected are:

;;; xload.lsp xref.lsp general.lsp flyxref.lsp xmatch6.lsp xpar.lsp

;;; Each of them needs this file to be loaded into the compile environment
;;; in order to function correctly.

(in-package "DYPAR"); :use '("LISP" "USER"))

;;; This has no real effect on the execution speed of hash retreival
;;(proclaim '(optimize (speed 3)))

;(proclaim '(inline gethash))

(eval-when (compile)
  (if (not (boundp '*macros-loaded*)) (load "macros")))

;;; Message management and access functions.

(defstruct (message (:conc-name nil))
  (name nil :type symbol)
  (english "" :type string)
  (spanish "" :type string)
  )

(defvar *message-hash* (make-hash-table :size 97))
(defvar *language* 'english)
(defvar *default-language* 'english)
(defvar *dypar-stream* *standard-output*)

;;; Variable to control if the function smformat must return a message 
;;; to the *dypar-stream*, this is optional to reduce the number of
;;; messages of DYPAR (useful in a run-time application).
(defvar *enable-output* t)

(defmacro add-message (name &rest args)
  `(setf (gethash ,name *message-hash*)
	 (make-message :name ,name ,@args)))

(defun clear-messages ()
  (clrhash *message-hash*))

(defmacro mformat (stream language message-name &rest args)
  `(format ,stream
	   (safe-language ,language ,message-name)
	   ,@args))

;;; Still needs work as the *language* goes away when this gets compiled.
;;; Macro-expansion in safe-language kills it.
(defun smformat (message-name &rest args)
 (and *enable-output*
      (apply (function format)
	 (cons *dypar-stream*
	       (cons (safe-language-fn *language* message-name)
		     args)))))

(defun safe-language-fn (language message-name)
  (if (string=
	(funcall language (gethash message-name *message-hash*))
	"")
      (funcall *default-language* (gethash message-name *message-hash*))
      (funcall language (gethash message-name *message-hash*))))

(defmacro mptrace (&rest form)
  `(and !ptrace
	(progn (mformat t ,@form)
	       t)))

(defmacro smptrace (&rest form)
  `(and !ptrace
	(progn (smformat ,@form)
	       t)))

;;; The else clause of the macro should be changed to reflect the
;;; different initial characters for yes and no in different languages.
(defmacro my-or-n-p (language message-name &rest args)
  `(if (eql language 'english)
       (y-or-n-p (english ,message-name) ,@args)
       (y-or-n-p (safe-language ,language ,message-name) ,@args)))

(defmacro safe-language (language message-name)
  `(or (null-string-test
	 (,(eval language) (gethash ,message-name *message-hash*)))
       (,*default-language* (gethash ,message-name *message-hash*))))

(defmacro null-string-test (string)
  `(if (string= ,string "")
       nil
       ,string))

;;; DYPAR-I  MESSAGES 
;;; The major comments introduce the different files in which the
;;; messages occur.  The secondary comments name the functions.
;;; Each message is named after the function in which it occurs.

;;; from XLOAD.LSP

;; loadgrammar

(add-message 'loadgrammar1
  :english "~&Semantic Grammar Loaded.~&"
  :spanish "~&Se ha cargado la gramatica semantica.~&"
  )
(add-message 'loadgrammar2
  :english "Bad rule syntax! A -> rule needs an atomic symbol, got: ~&~S~&"
  :spanish "Error en la sintaxis de la regla. Una regla del tipo -> ~&     ~
	    necesita un simbolo atomico.  He recibido: ~&  ~S~&"
  )
(add-message 'loadgrammar3
  :english
  "~&You are about to overwrite a previously defined non-terminal:  ~S~&"
  :spanish
  "~&Esta a punto de destruir la definicion anterior del no terminal:  ~S~&"
  )
(add-message 'loadgrammar4
  :english "The current expansion is:~&   ~S~&"
  :spanish "La expansion actual es:~&   ~S~&"
  )
(add-message 'loadgrammar5
  :english "The new expansion would be:~&    ~S~&"
  :spanish "La nueva expansion sera:~&    ~S~&"
  )
(add-message 'loadgrammar6 			; y-or-n-p **** Unconverted ****
  :english "Should I use the new definition?"
  :spanish "Debo utilizar la nueva definicion?"
  )
(add-message 'loadgrammar7
  :english "Ok. I will use the new definition~&~&"
  :spanish "Vale. Voy a usar la definicion nueva~&~&"
  )
(add-message 'loadgrammar8
  :english "Ok. I will use the old definition.~&~&"
  :spanish "Vale. Voy a usar la definicion anterior~&~&"
  )
(add-message 'loadgrammar9
  :english "Bad rule syntax!  Need 'X arrow Y', got: ~&    ~S   ~S    ~S~&"
  :spanish "Error en la sintaxis de la regla. Necesito 'X flecha Y', ~
            He recibido: ~&    ~S   ~S    ~S~&"
  )
(add-message 'loadgrammar10
  :english "Loadgrammar aborted.~&"
  :spanish "Se ha interrumpido la carga de la gramatica.~&"
  )

;; altprop

(add-message 'altprop1
  :english "Pattern must expand to a list:  ~S~&"
  :spanish "El patron debe expandirse en una lista:  ~S~&"
  )

;; read-meta-comment

(add-message 'read-meta-comment1
  :english "You have not specified a value for the meta-keyword: ~S~&"
  :spanish "No se ha especificado valor para la palabra clave: ~S~&"
  )
(add-message 'read-meta-comment2
  :english "Continuing without that metakey specified.~&"
  :spanish "Continuacion sin la palabra clave especificada.~&"
  )

;;; ***** There are three calls to pause at the end of read-meta-comment.


;;; from XREF.LSP

;; cross-reference

(add-message 'cross-reference1
  :english
    "~&Following non-terminals are not used in any rule or transformation:~&"
  :spanish
    "~&Los  no terminales siguientes no se utilizan en ninguna regla:~&"
  )
(add-message 'cross-reference2
  :english
    "~&Following non-terminals have been seen, but have no definitions:~&  ~S"
  :spanish "~&Los no terminales siguientes han sido utilizados pero no ~
  	    definidos:~&  ~S"
  )
(add-message 'cross-reference3 		; ptrace
  :english "~&Indexing => top-level rules:~&"
  :spanish "~&Indexando => reglas del alto nivel:~&"
  )
(add-message 'cross-reference4 		; ptrace
  :english "~&Cross-referencing Completed.~&"
  :spanish "~&Finalizada la creacion de las referencias cruzadas~&"
  )

;; x-reference

(add-message 'x-reference1 		; ptrace
  :english "~&~&X-referencing ~S~&"
  :spanish "~&~&Referencia cruzada de ~S~&"
  )

;; x-pat

(add-message 'x-pat1 			; ptrace
  :english "~&~S is not a legal pattern~&"
  :spanish "~&~S no es un patron permitido~&"
  )

;; x-ref

(add-message 'x-ref1
  :english "Potentially left recursive:~&   ~S~&"
  :spanish "Recursivo potencialmente por la izquierda:~&   ~S~&"
  )

;; loadgra

(add-message 'loadgra1 			; ptrace
  :english "~&Loading Grammar File: ~S~&"
  :spanish "~&Se esta cargando el fichero de la gramatica: ~S~&"
  )

;; erasegra

(add-message 'erasegra1 		; ptrace
  :english "~&The old grammar definitions have been erased.~&"
  :spanish "~&Se han borrado las definiciones anteriores de la gramatica.~&"
  )


;;; from GENERAL.LSP

;; pause

(add-message 'pause1
  :english "Pause from ~S~&"
  :spanish "Interrupcion en ~S~&"
  )
(add-message 'pause2
  :english "Reason: ~S~&"
  :spanish "Razon: ~S~&"
  )
(add-message 'pause3
  :english "~&Type CONTINUE to return with nil, ~
	    RESUME to return with the value given.~&"
  :spanish "~&Escriba CONTINUE para devolver nil, ~
            RESUME para devolver el valor dado.~&"
  )
(add-message 'pause4 			; used twice
  :english "~&Pause : "
  :spanish "~&Interrupcion: " 
  )
(add-message 'pause5
  :english "~&Continuing...~&"
  :spanish "~&Continuando...~&"
  )
(add-message 'pause6
  :english "~&Pause Return Value : "
  :spanish "~&Valor devuelto desde la interrupcion: "
  )
(add-message 'pause7
  :english "~&Resuming with ~S~&"
  :spanish "~&Resumiendo con ~S~&"
  )
(add-message 'pause8
  :english "~&Type CONTINUE to return with nil, ~
	    RESUME to return with the value given.~&"
  :spanish "~&Escriba CONTINUE para devolver nil, ~
            RESUME para devolver el valor dado.~&"
  )
(add-message 'pause9
  :english "~S~&Pause : "
  :spanish "~S~&Interrupcion: "
  )

;;; from FLYXREF.LSP

;;open-gra-file
;	   (format t "You have opened the ~S ~
;		   grammar file to update on the fly!~&" file))
;	  ((y-or-n-p "The " file " was not previously loaded. Should I "
;	       "use this file as a new grammar file for all the "
;	       "on fly updates? ")
;;close-gra-file
;	   (format t "Closed ~S~&" !!fly-file)
;	  (t (format t "This file is not an open file. ~
;		  The open file presently is ~S.~&"
;		  !!fly-file))))
;;modify-gra
;	 (format t
;		 "~&Enter the name of the rule you wish to add or change:  ")
;	 (format t "~&What type of rule is it? [N TL TR]  ")
;;def-nonterm
;		(format t "Nonterm Name: ")
;		(format t "Previously defined nonterminal:~&")
;		(format t "~S -> ~S~&" nonterm (get-pattern nonterm))
;		(cond ((y-or-n-p "Do you wish to redefine it?")
;		       (format t "The Rewrite pattern:  ")
;		  (format t "~&It's rewrite pattern:  ")
;;rem-nonterm
;	 (format t "Nonterm: ")
;	 (format t "Removing ~S that has ~&" nonterm)
;	 (format t "Rewrite:  ~S~&" (get nonterm ':rewrite))
;;def-rule
;	 (format t "Rule Pattern:  ")
;	 (format t "It's action:  ")
;;rem-rule
;	 (format t "Rule: ")
;	 (format t "Removing ~S that has ~&" rule)
;	 (format t "Pattern:  ~S~&" (get rule ':pattern))
;	 (format t "Action: ~S~&" (get rule ':action))
;	       (t (format t "~S does not exist." rule)))))
;;def-trans
;	 (format t "Trans Pattern:  ")
;	 (format t "It's Action:  ")
;;rem-trans
;	 (format t "Trans: ")
;	 (format t "Removing the ~S that has ~&")
;	 (format t "Pattern: ~S~&" (get trans ':pattern))
;	 (format t "Action: ~S~&" (get trans ':action))
;	       (t (format t "~S is not a transformation rule." trans)))))

;;; from XMATCH6.LSP

;; smatch1

(add-message 'smatch1-1
  :english "Error in Pattern Specification: ~S~&"
  :spanish "Error en la especificacion del patron: ~S~&"
  )

;;; from XPAR.LSP

;; printrule

(add-message 'printrule1
  :english "~&Rule ~S~&"
  :spanish "~&Regla ~S~&")

(add-message 'printrule2
  :english "Action will be: ~S~&With bindings: ~&"
  :spanish "La accion sera: ~S~&Con las asignaciones: ~&")

;; apply-top-level-rules

(add-message 'apply-top-level-rules1 	; ptrace
  :english "I will try rules:  ~S~&"
  :spanish "~&Comprobare las siguientas reglas:  ~S~&"
  )
(add-message 'apply-top-level-rules2 	; ptrace
  :english "More specific top-level rules failed.~&"
  :spanish "Han fallado las reglas del nivel superior mas especificas.~&"
  )
(add-message 'apply-top-level-rules3 	; ptrace
  :english "Now trying general rules:  ~S~&"
  :spanish "Comprobando las reglas mas generales:  ~S~&"
  )

;; applytrans

(add-message 'applytrans1 		; ptrace
  :english "~&Transforming  ~S~&"
  :spanish "~&Transformando  ~S~&"
  )
(add-message 'applytrans2 		; ptrace
  :english "Into ::>      ~S~&"
  :spanish "En ::>      ~S~&"
  )

;; ask-which-one
;; en los mensajes del tipo ask-which-one se ha cambiado "numero" por
;; "nombre" para que no haya equivocos a la hora de seleccionar la 
;; regla elegida por el usuario.

(add-message 'ask-which-one1
  :english "~&Multiple parses. Choose by typing the rule name.~&"
  :spanish "~&Varias posibilidades de equiparacion.~&~
	    Seleccione una regla tecleando su nombre.~&"
  )
(add-message 'ask-which-one2
  :english "~&Rule name: "
  :spanish "~&Nombre de la regla:  "
  )

(add-message 'confir-ask-which-one2
  :english "~&It isn't one of the names above"
  :spanish "~&Ese nombre de regla no esta entre las mostradas"
  )

;; resolve-internal-collision

(add-message 'resolve-internal-collision1
  :english
    "User defined resolution strategy failure~&Making arbitrary choice~&"
  :spanish "Fallo en las estrategia de resolucion definida por el usuario~&~
	    Se elejira una opcion arbitraria~&"
  )
(add-message 'resolve-internal-collision2
  :english "Unknown match resolution function: ~S Ignoring~&"
  :spanish
  "Funcion de resolucion de equiparacion desconocida: ~S Se ignorara.~&"
  )

;; resolve-collision

(add-message 'resolve-collision1
  :english "User defined resolution strategy failure ~&Asking the user to ~
            decide.~&"
  :spanish "Fallo en la estrategia de resolucion definida por el usuario.~&~
	    Se pide al usuario que decida.~&"
  )
(add-message 'resolve-collison2
  :english "Unknown match resolution function:  ~S Ignoring~&"
  :spanish
  "Funcion de resolucion de equiparacion desconocida: ~S Se ignorara.~&"
  )

;; applyrule

(add-message 'applyrule1 		; ptrace
  :english "Parse is:~&"
  :spanish "El analisis es:~&"
  )
(add-message 'applyrule2 		; used twice
  :english "No Parses found for:~&~S~&"
  :spanish "~&No se ha encontrado ningun analisis para:~&~S~&"
  )

;; parser

(add-message 'parser1
  :english "~&You are talking to the DYPAR English language Parser."
  :spanish
  "~&Esta Ud. hablando con el analizador de Castellano. Me llamo DYPAR."
  )
(add-message 'parser2
  :english "~&You may type in natural English sentences.~&"
  :spanish "~&Puede escribir frases en Castellano.~&"
  )
(add-message 'parser3
  :english "~&Leaving natural language interface.~&"
  :spanish "~&Abandonando el interface de lenguaje natural.~&"
  )
(add-message 'parser4
  :english "~&  Back to LISP.~&"
  :spanish "~&  Vuelta a LISP.~&"
  )

;(mformat t 'english 'parser1)
;(mformat t 'spanish 'parser1)
;(mformat t *language* 'parser1)
;(setq *language* 'spanish)
;(smformat 'parser1)

(defvar *babel-loaded* t)