Lisp Notes 7


; The first thing you need to decide on is how to set up your initial data structure
; I would worry about reading from a file last but once you can read from the file
; it should not be to hard to set up a list like this.

(setf data
  '((NB MAIN)              
    (NS i integer)         
    (NS j real)            
    (NS size real)         
    (NS title char)        
    (NS find procedure)    
    (NS sort procedure)    
    (NS edit procedure)    
    (NS restore function)  
    (SD restore)           
    (SD j)                 
    (LS sort)              
    (SR find)              
    (NB find)              
    (LIST)                 
    (DUMP)                 
    (EB)                   
    (NB edit)              
    (EB)                   
    (NB restore)           
    (NB open_file)
    (NS restore function)
    (SD restore)
    (SD j)
    (LS sort)
    (SR find)
    (NB find)
    (LIST)
    (DUMP)
    (EB)
    (NB edit)
    (EB)
    (NB restore)
    (NB open_file)
    (NB access_file)
    (EB)
    (EB)
    (NB read_file)
    (EB)
    (NB write_file)
    (EB)
    (EB)
    (EB)))

(setf data1
  '((NB MAIN)              
    (NS i integer)         
    (NS j real)            
    (NS size real)         
    (NS title char)        
    (NS find procedure)    
    (NS sort procedure)    
    (NS edit procedure)    
    (NS restore function)                 
    (NB find)              
    (EB)                   
    (NB edit)              
    (EB)                   
    (NB restore)           
    (NB open_file)
    (NS restore function)
    (NB find)
    (EB)
    (NB edit)
    (EB)
    (NB restore)
    (NB open_file)
    (NB access_file)
    (EB)
    (EB)
    (NB read_file)
    (EB)
    (NB write_file)
    (EB)
    (EB)
    (EB)))

; You are going to need a main which will simply take a list as its input.
; In order to do anything with this you will want to define a helper function
; main* which will take extra parameters. Here is a simple example of how you
; would want to recurse through a list to count the elements.

(setf data_ex '(a b c))

(defun my_main_ex (my_list)
  (my_main_ex* my_list 0))

(defun my_main_ex* (my_list counter)
  (cond
   ((null my_list) counter)
   (t (my_main_ex* (cdr my_list) (+ 1 counter)))))


;   > (my_main_ex '(a b c))
;   3
;   vs.
;   > (my_main_ex data_ex)
;   3



; In this example counter is the variable that get incremented each time you 
; see an element. By calling cdr of my_list you take one element away each
; time the function is called. Since you do not have any way to store variables
; you set up the helper function with the extra parameter counter. You only want to 
; use setf for testing.

(defun my_main (my_list)
  (my_main* my_list nil))

(defun my_main* (my_list my_new_list)
  (cond
   ((null my_list) my_new_list)
   ((eq (car (car my_list)) 'nb)
    (my_main* (cdr my_list) (list (car my_list))))
   ((eq (car (car my_list)) 'ns)
    (my_main* (cdr my_list) (append my_new_list (list (car my_list)))))
   ((eq (car (car my_list)) 'eb) (append (list my_new_list)
                                         (my_main (cdr my_list))))
   (t (my_main* (cdr my_list) my_new_list))))

; There are three ways to put two lists together

;  > (cons '(a b c) '(1 2 3))
;  ((A B C) 1 2 3)

;  > (append '(a b c) '(1 2 3))
;  (A B C 1 2 3)

;  > (list '(a b c) '(1 2 3))
;  ((A B C) (1 2 3))

; What this example does it it takes a list like this
; ((nb main)(ns i int)(eb)(nb function)(ns x int)(ns z int)(eb)
; and turns it into this
; (((NB MAIN) (NS I INT)) ((NB FUNCTION) (NS X INT) (NS Z INT)))

;  > (my_main '((nb main)(ns i int)(eb)(nb function)(ns x int)(ns z int)(eb)))
;  (((NB MAIN) (NS I INT)) ((NB FUNCTION) (NS X INT) (NS Z INT)))

; Now you have a list of procedures. Each procedure is a list of variables.
; By setting up this data structure it will be easier to implement the other
; function. For example what variables are defined.

; Lets say you want to add the sd function to your program
; This is the same set of data just with SD inserted at random

(setf data2
  '((NB MAIN)              
    (NS i integer)         
    (NS j real)            
    (NS size real)         
    (NS title char)        
    (NS find procedure)    
    (NS sort procedure)    
    (NS edit procedure)    
    (NS restore function)  
    (SD restore)           
    (SD j)                 
    (NB find)              
    (EB)                   
    (NB edit)              
    (EB)                   
    (NB restore)           
    (NB open_file)
    (NS restore function)
    (SD restore)
    (SD j)
    (NB find)
    (EB)
    (NB edit)
    (EB)
    (NB restore)
    (NB open_file)
    (NB access_file)
    (EB)
    (EB)
    (NB read_file)
    (EB)
    (NB write_file)
    (EB)
    (EB)
    (EB)))


(defun my_main2 (my_list)
  (my_main2* my_list nil))

; For my_main2* you will need to add the condition to test for SD
; The sd function will want as its parameter the new list you have been
; building. Once SD is finished you will want to call my_main2* again 
; with the cdr of my_list and my_new_list. My_main2 gets the cdr of my_list
; because you want to get rid of the element you just read. It takes my_new_list
; unchanged because SD has nothing to do with building the procedure list.

(defun my_main2* (my_list my_new_list)
  (cond
   ((null my_list) my_new_list)
   ((eq (car (car my_list)) 'nb)
    (my_main2* (cdr my_list) (list (car my_list))))
   ((eq (car (car my_list)) 'ns)
    (my_main2* (cdr my_list) (append my_new_list (list (car my_list)))))
   ((eq (car (car my_list)) 'eb) (append (list my_new_list)
                                         (my_main2 (cdr my_list))))
   ((eq (car (car my_list)) 'sd) 
    (my_sd_function my_new_list (second (car my_list)))
    (my_main2* (cdr my_list) my_new_list))
   (t (my_main2* (cdr my_list) my_new_list))))

(defun my_sd_function (a_list var)
  (cond 
   ((null a_list) (format t "Finished SD~%"))
   ((eq var (second (car a_list))) 
    (format t "Looking for ~a List = ~a~%" var (car a_list))
    (format t "Found~%"))
   (t 
    (format t "Looking for ~a List = ~a~%" var (car a_list))
      (my_sd_function (cdr a_list) var))))