From 8f68f03408b04fbd5f21efaa375b9c7f732ac607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sat, 30 Oct 2010 22:25:46 +0200 Subject: [PATCH 1/3] Correction (?) sur le defun dans lisp2li. --- lisp2li.lisp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lisp2li.lisp b/lisp2li.lisp index e27fe1b..340212f 100644 --- a/lisp2li.lisp +++ b/lisp2li.lisp @@ -28,10 +28,13 @@ par le compilateur et par l’interpréteur" ((eq 'quote (car expr)) ;; quotes (cons :lit (second expr))) ((eq 'defun (car expr)) ;; TODO : a verifier que le cas de defun est bien gerer comme on le veux - (cons :call (list 'add-top-level-binding (cons :lclosure (list (length (third expr)) - (lisp2li (fourth expr) - (make-stat-env (push-new-env env "DEFUN") - (third expr)))))))) + (add-top-level-binding env + (second expr) + (cons :lclosure (list (length (third expr)) + (lisp2li (fourth expr) + (make-stat-env (push-new-env env "DEFUN") + (third expr)))))) + (cons :lit (second expr))) ((eq 'setq (car expr)) (cons :call (cons 'set-binding (list `(:lit . ,env) (cons :lit (second expr)) From c2fe50a031f64836a7c28108de4600d06c5e5a9f Mon Sep 17 00:00:00 2001 From: Bertrand BRUN Date: Sun, 31 Oct 2010 00:09:39 +0200 Subject: [PATCH 2/3] Correction d'un mauvais test sur les fonctions definie. Ainsi que l'ajout d'un test pour eviter les erreurs d'environnement vide a l'execution de lisp2li --- environnement.lisp | 4 ++-- lisp2li.lisp | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/environnement.lisp b/environnement.lisp index 69974f7..a1ed85a 100644 --- a/environnement.lisp +++ b/environnement.lisp @@ -52,8 +52,8 @@ Le paramètre ENV-STACK est toute la pile d'environnements." (defun add-binding (env-stack name value) "Ajoute une liaison au dernier environnement (le plus bas)." (setf (cdar env-stack) - (cons (cons name value) - (cdar env-stack))) + (cons (cons name value) + (cdar env-stack))) env-stack) (defun get-binding (env-stack name) diff --git a/lisp2li.lisp b/lisp2li.lisp index 340212f..bb2e130 100644 --- a/lisp2li.lisp +++ b/lisp2li.lisp @@ -2,13 +2,14 @@ (defun lisp2li (expr env) "Convertit le code LISP en un code intermédiaire reconnu par le compilateur et par l’interpréteur" - (cond ((and (atom expr) (constantp expr)) ; literaux + (cond ((null env) (lisp2li expr (empty-env-stack))) + ((and (atom expr) (constantp expr)) ; literaux (cons :lit expr)) ((symbolp expr) ; symboles (let ((cell (get-binding env expr))) (if cell (cons :var (car cell)) - (warn "Variable ~S unknown" (car expr))))) + (warn "Variable ~S unknown" expr)))) ((and (consp (car expr)) (eq 'lambda (caar expr))) ;; λ-expressions @@ -18,7 +19,7 @@ par le compilateur et par l’interpréteur" (error "Lambda expression NYI")) ((not (symbolp (car expr))) (warn "~S isn't a symbol" (car expr))) - ((not (fboundp (car expr))) + ((get-binding env (car expr)) (list :unknown expr env)) ((eq 'if (car expr)) ; if (list :if @@ -131,6 +132,6 @@ par le compilateur et par l’interpréteur" (deftestvar lisp2li env (add-binding (empty-env-stack) 'x 1)) (deftest lisp2li (lisp2li '(setq x 2) env) - '(:call set-binding (:lit (("TOP-LEVEL" (x . 1)))) (:lit . x) (:lit . 2))) + '(:call set-binding (:lit . (("TOP-LEVEL" (x . 1)))) (:lit . x) (:lit . 2))) ;(run-tests t) \ No newline at end of file From b154264f1ad40063fb9fb557d77484b2c719f042 Mon Sep 17 00:00:00 2001 From: Bertrand BRUN Date: Sun, 31 Oct 2010 02:45:19 +0200 Subject: [PATCH 3/3] Correction de la fonction print-env-stack pour quel puisse afficher correctement l'environnement, lisp2li gere maintenant correctement les lambda-expressions et les defuns --- environnement.lisp | 21 +++++++++++++++------ lisp2li.lisp | 32 +++++++++++++++++++------------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/environnement.lisp b/environnement.lisp index a1ed85a..4ea2e9d 100644 --- a/environnement.lisp +++ b/environnement.lisp @@ -93,12 +93,21 @@ l'environnement top-level." env-stack) (defun print-env-stack (env-stack) - (if (atom env-stack) - nil - (progn (format t "~&~a: " (caar env-stack)) - (mapcar (lambda (b) (format t "~& ~w = ~w" (car b) (cdr b))) - (cdar env-stack)) - (print-env-stack (cdr env-stack))))) + (let ((*print-circle* t)) + (if (atom env-stack) + nil + (progn (format t "~&~a: " (caar env-stack)) + (mapcar (lambda (b) (format t "~& ~w = ~w" (car b) (cdr b))) + (cdar env-stack)) + (print-env-stack (cdr env-stack)))))) + +;(defun print-env-stack (env-stack) +; (if (atom env-stack) +; nil +; (progn (format t "~&~a: " (caar env-stack)) +; (mapcar (lambda (b) (format t "~& ~w = ~w" (car b) (cdr b))) +; (cdar env-stack)) +; (print-env-stack (cdr env-stack))))) ;;Test Unitaire (deftest environnement diff --git a/lisp2li.lisp b/lisp2li.lisp index bb2e130..1f3ab09 100644 --- a/lisp2li.lisp +++ b/lisp2li.lisp @@ -1,4 +1,4 @@ -;; TODO : reste a gerer les defuns, les let, les lambda expression, les setf, les progn, ... +(load "environnement") (defun lisp2li (expr env) "Convertit le code LISP en un code intermédiaire reconnu par le compilateur et par l’interpréteur" @@ -10,16 +10,20 @@ par le compilateur et par l’interpréteur" (if cell (cons :var (car cell)) (warn "Variable ~S unknown" expr)))) + ((eq 'lambda (car expr)) + (let ((env-bis (make-stat-env (push-new-env env "LAMBDA") (second expr)))) + `(:lclosure ,env-bis + ,(lisp2li (third expr) + env-bis)))) ((and (consp (car expr)) (eq 'lambda (caar expr))) - ;; λ-expressions - ;; => recursion sur arguments - ;; => construction environnement - ;; => recursion sur corps de la λ-fonction - (error "Lambda expression NYI")) + `(:call ,(lisp2li (car expr) env) + ,@(mapcar (lambda (param) + (lisp2li param env)) + (cdr expr)))) ((not (symbolp (car expr))) (warn "~S isn't a symbol" (car expr))) - ((get-binding env (car expr)) + ((and (not (fboundp (car expr))) (not (get-binding env (car expr)))) (list :unknown expr env)) ((eq 'if (car expr)) ; if (list :if @@ -29,12 +33,12 @@ par le compilateur et par l’interpréteur" ((eq 'quote (car expr)) ;; quotes (cons :lit (second expr))) ((eq 'defun (car expr)) ;; TODO : a verifier que le cas de defun est bien gerer comme on le veux - (add-top-level-binding env - (second expr) - (cons :lclosure (list (length (third expr)) - (lisp2li (fourth expr) - (make-stat-env (push-new-env env "DEFUN") - (third expr)))))) + (let ((env-bis (make-stat-env (push-new-env env "DEFUN") (third expr)))) + (add-top-level-binding env + (second expr) + (cons :lclosure (cons env-bis + (lisp2li (fourth expr) + env-bis))))) (cons :lit (second expr))) ((eq 'setq (car expr)) (cons :call (cons 'set-binding (list `(:lit . ,env) @@ -134,4 +138,6 @@ par le compilateur et par l’interpréteur" (lisp2li '(setq x 2) env) '(:call set-binding (:lit . (("TOP-LEVEL" (x . 1)))) (:lit . x) (:lit . 2))) +;; Test sur le defun + ;(run-tests t) \ No newline at end of file