MAIN.LSP



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;						;;
;;	EDITOR VISUAL DEL LENGUAJE C		;;
;;	Modulo: main.lsp			;;
;;						;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;						;;
;;	Autor: J. Rafael R. Ochoa		;;
;;	e-mail: rochoa@zeus.umich.mx    	;;
;;	Universidad Michoacana de 		;;
;;	Morelia, Mich. MEXICO			;;
;;						;;
;;	Marzo 1998				;;
;;						;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Programa Principal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;
;; Variable GLOBAL donde se almacena el programa principal
;;;;
(setq *programa-principal* nil)

;;;;;;;;;;;;
;; Variable GLOBAL donde se almacenan las variables locales
;;;;
(setq *variables-locales* nil)

;;;;;;;;;;;;
;; Despliega el main
;;;;
(defun main (hotspot &rest ignore)
  (ghw:flush-hotspot hotspot)
  (aumenta-renglon 20)
  (ghw:draw-text *ventana-principal* 10 posicion-renglon
		"/* Comienza el programa principal */")
  (aumenta-renglon 30) 
  (tres-puntos-tipos-basicos 20)
  (ghw:draw-text *ventana-principal* 20 posicion-renglon "main () {")
  (aumenta-renglon 50)
  (opcion-variables-locales 60)
  (opcion-cuerpo-del-programa 60)
;  (aumenta-renglon 30)
;  (ghw:draw-text *ventana-principal* 20 posicion-renglon "}")
)

(defun sustituye (x y width height)
  (psetq s_x x s_y y s_width width s_height height))



;;--------------------------------------------
;; tres-puntos-basicos
;;--------------------------------------------
;; Muestra un rectangulo con tres puntos, que
;; basicos (int, float,...)
;;;;;;;;;;
(defun tres-puntos-tipos-basicos (posicion-x)
  (sustituye posicion-x posicion-renglon 45 30)
  (ghw:draw-rectangle *ventana-principal* posicion-x posicion-renglon
		45 30 :pen *lapiz-amarillo* :brush *relleno-azul*)
  (ghw:draw-text *ventana-principal* (+ 10 posicion-x) (+ posicion-renglon 10) 
		"...")
  (let ((hotspot
	 (ghw:make-hotspot *ventana-principal* :x posicion-x :y posicion-renglon
		:width 45 :height 30
		:status :active)))
  (ghw:add-to-object-method hotspot :mouse-left-down
		'(:after (tipos-basicos))))
  (aumenta-renglon 30))



;;--------------------------------------------
;; opcion-variables-locales
;;--------------------------------------------
;; Muestra un rectangulo con tres puntos, que
;; del programa (declaraciones , contenido)
;;;;;;;;;;
(defun opcion-variables-locales (posicion-x)
  (psetq cuadro-variable-local-x posicion-x 
	 cuadro-variable-local-y posicion-renglon)
  (ghw:draw-rectangle *ventana-principal* posicion-x posicion-renglon
		170 30 :pen *lapiz-amarillo* :brush *relleno-azul*)
  (ghw:draw-text *ventana-principal* (+ 10 posicion-x) (+ posicion-renglon 10) 
		"<Variables locales>")
  (let ((hotspot
	 (ghw:make-hotspot *ventana-principal* :x posicion-x :y posicion-renglon
		:width 170 :height 30
		:status :active)))
  (ghw:add-to-object-method hotspot :mouse-left-down
		'(:after (opcion-locales))))
  (aumenta-renglon 45)
)



;;--------------------------------------------------
;; opcion-locales
;;--------------------------------------------------
;; Declaracion de las variables locales
;;;;;;;;;;;;
(defun opcion-locales (hotspot &rest ignore)
  (elimina-todo-hotspot(obten-lista-de-hotspots *ventana-secundaria*))
  (limpia-ventana *ventana-secundaria*)
  (local-int)
  (local-float)
  (local-double)
  (local-char)
  (local-void))

;;--------------------------------------------------
;; local-int & pide-int-local
;;--------------------------------------------------
;;  Agregan una variable local de tipo entero
;;;;;;;;;;;;;;;;;;;;
(defun local-int ()
  (ghw:draw-rectangle *ventana-secundaria* 20 5 80 30
		        :pen *lapiz-azul* :brush *relleno-amarillo*)
	       (ghw:draw-text *ventana-secundaria* 25 10 
				"int")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 5
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))  
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (pide-int-local)))))

(defun pide-int-local (hotspot &rest ignore)
	     (obten-valor-local 'int))	

;;--------------------------------------------------
;; local-float & pide-float-local
;;--------------------------------------------------
;;  Agregan una variable local de tipo flotante
;;;;;;;;;;;;;;;;;;;;
(defun local-float ()
  (ghw:draw-rectangle *ventana-secundaria* 20 45 80 30
		        :pen *lapiz-azul* :brush *relleno-amarillo*)
	       (ghw:draw-text *ventana-secundaria* 25 50 
				"float")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 45
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))  
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (pide-float-local)))))

(defun pide-float-local (hotspot &rest ignore)
	     (obten-valor-local 'float))	

;;--------------------------------------------------
;; local-double & pide-double-local
;;--------------------------------------------------
;;  Agregan una variable local de tipo double
;;;;;;;;;;;;;;;;;;;;
(defun local-double ()
  (ghw:draw-rectangle *ventana-secundaria* 20 85 80 30
		        :pen *lapiz-azul* :brush *relleno-amarillo*)
	       (ghw:draw-text *ventana-secundaria* 25 90 
				"double")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 85
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))  
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (pide-double-local)))))

(defun pide-double-local (hotspot &rest ignore)
	     (obten-valor-local 'double))	


;;--------------------------------------------------
;; local-char & pide-char-local
;;--------------------------------------------------
;;  Agregan una variable local de tipo char
;;;;;;;;;;;;;;;;;;;;
(defun local-char ()
  (ghw:draw-rectangle *ventana-secundaria* 20 125 80 30
		        :pen *lapiz-azul* :brush *relleno-amarillo*)
	       (ghw:draw-text *ventana-secundaria* 25 130 
				"char")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 125
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))  
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (pide-char-local)))))

(defun pide-char-local (hotspot &rest ignore)
	     (obten-valor-local 'char))	

;;--------------------------------------------------
;; local-void & pide-void-local
;;--------------------------------------------------
;;  Agregan una variable local de tipo void
;;;;;;;;;;;;;;;;;;;;
(defun local-void ()
  (ghw:draw-rectangle *ventana-secundaria* 20 165 80 30
		        :pen *lapiz-azul* :brush *relleno-amarillo*)
	       (ghw:draw-text *ventana-secundaria* 25 170 
				"void")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 165
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))  
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (pide-void-local)))))

(defun pide-void-local (hotspot &rest ignore)
	     (obten-valor-local 'void))	



;;--------------------------------------------------
;; agrega-variable-local
;;--------------------------------------------------
;; Funcion que forma la lista de variables globales
;;;;;;;;;
(defun agrega-variable-local (variable tipo)
        (if (null (encuentra-variable variable *variables-locales*))
(progn
    	(push (variable-con-tipo variable tipo) *variables-locales*)
(imprime-variable-local tipo variable)))
)



;;---------------------------------------------
;; obten-valor-local
;;---------------------------------------------
;; Peticion del nombre de la variable local
;;;;;;;;;
(defun obten-valor-local (tipo)
  (let ((nombre-local
	(ghw:make-window :title "Variable local"
  			         :x-scrollbar-p nil
				 :y-scrollbar-p nil
				 :height 70 :width 250
				 :system-menu-p nil
				 :reshapeable-p nil
				 :status :active)))
	(let ((stream (ws::make-window-stream nombre-local)))
	(let ((input (read-line stream)))
	(agrega-variable-local input tipo)
	(setf (ghw:window-caret-p nombre-local) t)
	(ghw:flush-window nombre-local)))))


;;----------------------------------------------
;; imprime-variable-local
;;----------------------------------------------
;; Impresion de la variable local
;;;;;;;;;;;
(defun imprime-variable-local (tipo variable)
  (borra-hacia-abajo cuadro-variable-local-y *ventana-principal*)
  (let ((tipo-en-minusculas
       (nstring-downcase (string tipo))))
   (let ((tipo-y-variable
       (concatenate 'string tipo-en-minusculas " " variable "\;")))
(if (null *variables-locales*)
     (ghw:draw-text *ventana-principal* 60 cuadro-variable-local-y tipo-y-variable)
     (ghw:draw-text *ventana-principal* 60 
	(- cuadro-variable-local-y 20) tipo-y-variable))
	(setq posicion-renglon (+ cuadro-variable-local-y 20))))
  	(opcion-variables-locales 60)
	(opcion-cuerpo-del-programa 60))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;--------------------------------------------
;; opcion-cuerpo-del-programa
;;--------------------------------------------
;; Muestra un rectangulo con tres puntos, que
;; del programa (declaraciones , contenido)
;;;;;;;;;;
(defun opcion-cuerpo-del-programa (posicion-x)
  (setq cuerpo-y posicion-renglon)
  (ghw:draw-rectangle *ventana-principal* posicion-x posicion-renglon
		115 30 :pen *lapiz-amarillo* :brush *relleno-azul*)
  (ghw:draw-text *ventana-principal* (+ 10 posicion-x) (+ posicion-renglon 10) 
		"<Enunciado>")
  (let ((hotspot
	 (ghw:make-hotspot *ventana-principal* :x posicion-x :y posicion-renglon
		:width 115 :height 30
		:status :active)))
  (ghw:add-to-object-method hotspot :mouse-left-down
		'(:after (enunciado))))
;(aumenta-renglon 45)
  (ghw:draw-text *ventana-principal* 20 (+ 45 posicion-renglon) "}")
  )



;;----------------------------------------
;; opcion-programa
;;----------------------------------------
;; enunciado 	:	enunciado-de-expresion
;;		|	enunciado-de-seleccion
;;		|	enunciado-de-iteracion
;;		;
;;;;;;;;
(defun enunciado (hotspot &rest ignore)
  (elimina-todo-hotspot(obten-lista-de-hotspots *ventana-secundaria*))
  (limpia-ventana *ventana-secundaria*)
  (opcion-expresion)
  (opcion-enunciado-de-seleccion)
  (opcion-enunciado-de-iteracion))



(defun opcion-expresion ()
  (ghw:draw-rectangle *ventana-secundaria* 20 5 190 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 10 
			"Enunciado de expresion")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 5
               			:width 190 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (enunciado-expresion)))))


(defun enunciado-expresion (hotspot &rest ignore)
  (elimina-todo-hotspot(obten-lista-de-hotspots *ventana-secundaria*))
  (limpia-ventana *ventana-secundaria*)
  (punto-y-coma)
  (opcion-expresion))

(defun punto-y-coma ()
   (ghw:draw-rectangle *ventana-secundaria* 20 45 30 20 
		:pen *lapiz-amarillo* :brush *relleno-azul*)
   (ghw:draw-text *ventana-secundaria* 25 50 "\;"))

;;------------------------------------------------------
;; enunciado-de-seleccion
;;------------------------------------------------------
;; enunciado_de_seleccion :
;;				IF '(' expresion ')' enunciado
;;			|	IF '(' expresion ')' enunciado
;;				ELSE '(' expresion ')' enunciado
;;			;
;;;;;;;;;;;;;
(defun opcion-enunciado-de-seleccion ()
  (ghw:draw-rectangle *ventana-secundaria* 20 45 190 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 50 
			"Enunciado de seleccion")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 45
               			:width 190 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (selection)))))


;;--------------------------------------------
;; selection
;;--------------------------------------------
;; Creacion de las funciones que representen
;; las producciones de enunciado-de-seleccion
;;;;;;;;;;;;;
(defun selection (hotspot &rest ignore)
  (elimina-todo-hotspot(obten-lista-de-hotspots *ventana-secundaria*))
  (limpia-ventana *ventana-secundaria*)
  (ifx)
;  (if_else)
)

;;--------------------------------------------
;; ifx
;;--------------------------------------------
;; IF '(' expresion ')' enunciado
;;;;;;;;;;;
(defun ifx ()
  (ghw:draw-rectangle *ventana-secundaria* 20 5 190 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 10 
			"if ( expresion )")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 5
               			:width 190 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-if)))))

;;---------------------------------------
;; imprime-if
;;---------------------------------------
(defun imprime-if (hotspot &rest ignore)
   (borra-hacia-abajo cuerpo-y *ventana-principal*)
   (ghw:draw-text *ventana-principal* 60 cuerpo-y "if (" )
(ghw:draw-rectangle *ventana-principal* 80 (+ cuerpo-y 20) 100 30
		:pen *lapiz-amarillo* :brush *relleno-azul*)
(ghw:draw-text *ventana-principal* 85 (+ cuerpo-y 25) "<Expresion>")
(ghw:draw-text *ventana-principal* 85 (+ cuerpo-y 55) ") {")


   (aumenta-renglon 80)
  (opcion-cuerpo-del-programa 90)
(aumenta-renglon 80)
(opcion-cuerpo-del-programa 60)

)

;;--------------------------------------------
;; opcion-expresion
;;--------------------------------------------
(defun opcion-expresion (hotspot &rest ignore)
  (elimina-todo-hotspot(obten-lista-de-hotspots *ventana-secundaria*))
  (limpia-ventana *ventana-secundaria*))



;;--------------------------------------------
;; enunciado-de-iteracion
;;--------------------------------------------
(defun opcion-enunciado-de-iteracion ()
  (ghw:draw-rectangle *ventana-secundaria* 20 85 190 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 90 
			"Enunciado de iteracion")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 85
               			:width 190 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-double)))))

;;----------------------------------------
;; tipos-basicos
;;----------------------------------------
;; Despliega en la *ventana-secundaria*
;; los tipos basicos
;;;;;;;;;;;;;
(defun tipos-basicos (hotspot &rest ignore)
  (ghw:flush-hotspot hotspot)
  (limpia-ventana *ventana-secundaria*)
  (tipo-int)
  (tipo-float)
  (tipo-double)
  (tipo-char)
  (tipo-void))


;;;;;;;;;;;;;;;;;;;;;
;; Selecciona el tipo al que 
;; pertenece la variable
;;
;; especificador-de-tipo:
;;			VOID
;;		|	CHAR
;;		|	INT
;;		|	FLOAT
;;		|	DOUBLE
;;		;
;;;;;;;
(defun especificador-de-tipo ()
	(let ((tipo-valido (identificador)))
	(cond ((equal tipo-valido '1) 'int)
		((equal tipo-valido '2) 'float)
		((equal tipo-valido '3) 'double)
		((equal tipo-valido '4) 'char)
		((equal tipo-valido '5) 'void))))


(defun tipo-int ()
  (ghw:draw-rectangle *ventana-secundaria* 20 5 80 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 10 "int")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 5
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-out
                                        '(:after (borra-hotspot)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-int)))))

(defun imprime-int (hotspot &rest ignore)
  (ghw:draw-rectangle *ventana-principal* s_x s_y s_width s_height 
	:pen *lapiz-blanco* :brush *relleno-blanco*)
  (ghw:draw-text *ventana-principal* s_x (+ 10 s_y) "int"))
					


(defun tipo-float ()
  (ghw:draw-rectangle *ventana-secundaria* 20 45 80 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 50 "float")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 45
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-float)))))

(defun imprime-float (hotspot &rest ignore)
  (ghw:draw-rectangle *ventana-principal* s_x s_y s_width s_height 
	:pen *lapiz-blanco* :brush *relleno-blanco*)
  (ghw:draw-text *ventana-principal* s_x (+ 10 s_y) "float"))


(defun tipo-double ()
  (ghw:draw-rectangle *ventana-secundaria* 20 85 80 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 90 "double")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 85
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-double)))))

(defun imprime-double (hotspot &rest ignore)
  (ghw:draw-rectangle *ventana-principal* s_x s_y s_width s_height 
	:pen *lapiz-blanco* :brush *relleno-blanco*)
  (ghw:draw-text *ventana-principal* s_x (+ 10 s_y) "double"))



(defun tipo-char ()
  (ghw:draw-rectangle *ventana-secundaria* 20 125 80 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 130 "char")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 125
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-char)))))

(defun imprime-char (hotspot &rest ignore)
  (ghw:draw-rectangle *ventana-principal* s_x s_y s_width s_height 
	:pen *lapiz-blanco* :brush *relleno-blanco*)
  (ghw:draw-text *ventana-principal* s_x (+ 10 s_y) "char"))


(defun tipo-void ()
  (ghw:draw-rectangle *ventana-secundaria* 20 165 80 30
		        :pen *lapiz-amarillo* :brush *relleno-azul*)
	       (ghw:draw-text *ventana-secundaria* 25 170 "void")
	       (let ((hotspot
       			(ghw:make-hotspot *ventana-secundaria* :x 20 :y 165
               			:width 80 :height 30
               			:status :active)))
       			(ghw:add-to-object-method hotspot :mouse-left-down
                                        '(:after (imprime-void)))))

(defun imprime-void (hotspot &rest ignore)
  (ghw:draw-rectangle *ventana-principal* s_x s_y s_width s_height 
	:pen *lapiz-blanco* :brush *relleno-blanco*)
  (ghw:draw-text *ventana-principal* s_x (+ 10 s_y) "void"))



;;;;;;;;;;
;; Funcion para el printf
;;;;
(defun printf ()
  (ghw:draw-text *ventana-principal* 20 
	posicion-renglon "printf(" )
  (setq posicion-renglon (+ posicion-renglon 30))
  (ghw:draw-rectangle *ventana-principal* 
		      50 posicion-renglon 
		     45 30 :pen *lapiz-amarillo*
		      :brush *relleno-rojo*)
  (ghw:draw-text *ventana-principal* 60 (+ posicion-renglon 15) "...")
  (setq posicion-renglon (+ posicion-renglon 30))
 (ghw:draw-text *ventana-principal* 20 270 ")\;")
  (setq posicion-renglon (+ posicion-renglon 30)))