;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                ;;
;;  Étape 1 : les symboles et les types de bases  ;;
;;                                                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Pour lancer l’interpréteur vaλisp faites F8
;; Pour le relancer rapidement faites F9

;; Pour évaluer une sexpr ou une directive , placer le curseur après
;; le dernier caractère et faite C-x C-a

@env

;; Pour tester rapidement plusieurs sexpr, placer le curseur après le
;; dernier caractère de "Choucroute" et faites C-x a a a a a a

"Choucroute" ;; => "Choucroute"
655957       ;; => 655957
t            ;; => t
nil          ;; => nil
+            ;; => #p<add_valisp>
defvar       ;; => #s<defvar_valisp>
setq         ;; => #s<setq_valisp>



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                            ;;
;;  Étape 2 : les primitives  ;;
;;                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; On teste maintenant les primitives
(+ 100 20) ;; => 120

(+ (+ 1000 4)
   (+ 30 200)) ;; => 1234

(+ (+ (+ (+ 1 1) (+ 1 1))
      (+ (+ 1 1) (+ 1 1)))
   (+ 1 1)) ;; => 10



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                  ;;
;;  Étape 3 : les formes spéciales  ;;
;;                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar x 0)          ;; => 0
(defvar toto "salut") ;; => "salut"
toto                  ;; => "salut"
(setq x (+ x 1))      ;; => 1
(setq x (+ x 1))      ;; => 2
(setq x (+ x 1))      ;; => 3
(setq x (+ x 1))      ;; => 4
(setq x (+ x 6))      ;; => 10
x                     ;; => 10

(defvar a 100)
(defvar b 200)
(defvar c 300)

(if (setq a t) (setq b 'oui) (setq c 'non)) ;; => oui
a ;; t
b ;; oui
c ;; 300


(if (setq a nil) (setq b "non") (setq c "oui")) ;; "oui"
a ;; nil
b ;; oui
c ;; "oui"


;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                        ;;
;;  Étape 4 : les lambda  ;;
;;                        ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(lambda (x) (* 10 x))     ;; => (lambda (x) (* 10 x))
((lambda (x) (* 10 x)) 6) ;; => 600

(defvar suivant (lambda (nombre)
                  (+ 1 nombre)))

(suivant 10)                    ;; => 11
(suivant (suivant (suivant 0))) ;; => 3


(defvar list (lambda param param))

(list 1 2 3 4) ;; => (1 2 3 4)

(list 1
      (suivant 1)
      (+ 2 1)
      (+ (+ 1 1) (+ 1 1))) ;; => (1 2 3 4)

(defvar variable (lambda (a b . c)
                   (list a b c)))

(variable 1 2)         ;; => (1 2 nil)
(variable 1 2 3)       ;; => (1 2 (3))
(variable 1 2 3 4 5 6) ;; => (1 2 (3 4 5 6))

;; Pour cette fonction on suppose les primitives if_valisp,
;; car_valisp, cdr_valisp et cons_valisp écrites

(defvar map10 (lambda (liste)
                (if liste
                    (cons (* 10 (car liste))
                          (map10 (cdr liste)))
                  nil)))

(map10 (list 1 2 3 4 5))


(defvar list*-aux (lambda (liste)
                     (if (cdr liste) ;; si la liste contient au moins un élément
                         (cons (car liste)
                               (list*-aux (cdr liste)))
                       (car liste))))

(list*-aux (list 1 2 3 4)) ;; => (1 2 3 . 4)




(defvar list* (lambda liste
                (list*-aux liste)))

(list* 1 2 3 4) ;; => (1 2 3 . 4)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                        ;;
;;  Étape 5 : les macro   ;;
;;                        ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defvar defun (macro (nom variables . body)
                     (list 'defvar nom
                           (list* 'lambda variables body))))

(defun plus10 (n)
  (+ n 10))   ;; => (lambda (n) (+ n 10))


(defvar defmacro (macro (nom variables . body)
                        (list 'defvar nom
                              (list* 'macro variables body))))

(defmacro incr (variable . delta)
  (setq delta (if delta (car delta) 1))
  (list 'setq variable (list '+ delta variable)))



(defvar x 10) ;; => 10
(incr x)      ;; => 11
x             ;; => 11
(incr x 10)   ;; => 21
x             ;; => 21
