Fin de la parti Evaluateur

This commit is contained in:
Bertrand BRUN 2010-11-21 18:47:29 +01:00
parent f9d7dded59
commit 218ab7a0f3

View File

@ -230,3 +230,127 @@
;; }}} Barriere-syntaxique
;; {{{ Evaluateur
;; meval-scheme: Expression -> Valeur
;; (meval-scheme e) rend la valeur de l'expression "e"
(define (meval-scheme e)
(evaluation e (env-initial)))
;; evaluation: Expression * Environnement -> Valeur
;; (evaluation expr env) rend la valeur de l'expression "expr" dans l'environnement "env"
(define (evaluation expr env)
;; (discrimine l'expression et invoque l'evaluateur specialise)
(cond
((variable? expr) (variable-val expr env))
((citation? expr) (citation-val expr env))
((alternative? expr) (alternative-eval
(alternative-condition expr)
(alternative-consequence expr)
(alternative-alternant expr) env))
((conditionnelle? expr) (conditionnelle-eval
(conditionnelle-clauses expr) env))
((sequence? expr) (sequence-eval (sequence-exprs expr) env))
((bloc? expr) (bloc-eval (bloc-liaisons expr)
(bloc-corps expr) env))
((application? expr) (application-eval
(application-fonction expr)
(application-arguments expr) env))
(else
(scheme-erreur 'evaluation "pas un programme" expr))))
;; alternative-eval: Expression3 * Environnement -> Valeur
;; (alternative-eval condition consequence alternant env) rend la valeur de
;; l'expression "(if condition consequence alternant)" dans l'environnement "env"
(define (alternative-eval condition consequence alternant)
(if (evaluation condition env)
(evaluation consequence env)
(evaluation alternant env)))
;; conditionnelle-eval: LISTE[Clause] -> Expression
;; (conditionnelle-eval clauses env) rend la valeur, dans l'environnement "env",
;; de l'expression "(cond c1 c2 ... cn)".
(define (conditionnelle-eval clauses env)
(evaluation (cond-expansion clauses) env))
;; cond-expansion: LISTE[Clause] -> Expression
;; (cond-expansion clauses) rend l'expression, ecrite avec des alternatives,
;; equivalente a l'expression "(cond c1 c2 .. cn)".
(define (cond-expansion clauses)
(if (pair? clauses)
(let ((first-clause (cadr clauses)))
(if (equal? (clause-condition first-clause) 'else)
(cons 'begin (clause-expressions first-clause))
(cons 'if
(cons
(clause-condition first-clause)
(cons
(cons 'begin (clause-expressions first-clause))
(let ((seq (cond-expansion (cdr clauses))))
(if (pair? seq)
(list seq)
seq)))))))
'()))
;; sequence-eval: LISTE[Expression] * Environnement -> Valeur
;; (sequence-eval exprs env) rend la valeur, dans l'environnement "env",
;; de l'expression "(begin e1 ... en)". (Il faut evaluer tour a tour les
;; expressions et rendre la valeur de la derniere expression.)
(define (sequence-eval exprs env)
;; sequence-eval+: LISTE[Expression]/non vide/ -> Valeur
;; meme fonction, sachant que la liste "exprs" n'est pas vide et en globalisant
;; la variable "env"
(define (sequence-eval+ exprs)
(if (pair? (cdr exprs))
(begin (evaluation (car exprs) env)
(sequence-eval+ (cdr exprs)))
(evaluation (car exprs) env)))
;; expression de (sequence-eval exprs env):
(if (pair? exprs)
(sequence-eval+ exprs)
#f))
;; application-eval: Expression * LISTE[Expression] * Environnement -> Valeur
;; (application-eval exp-fn args env) rend la valeur de l'invocation de
;; l'expression "exp-fn" aux arguments "args" dans l'environnement "env"
(define (application-eval exp-fn args env)
;; eval-env : Expression -> Valeur
;; (eval-env expr) rend la valeur de "expr" dans l'environnement "env"
(define (eval-env expr)
(evaluation expr env))
;;expression de (application-eval exp-fn args env) :
(let ((f (evaluation exp-fn env)))
(if (invocable? f)
(invocation f (meval-scheme-map eval-env args))
(scheme-erreur 'application-eval
"pas une fonction" f))))
;; bloc-eval: LISTE[Liaison] * Corps * Environnement -> Valeur
;; (bloc-eval liaisons corps env) rend la valeur, dans l'environnement "env"
;; de l'expression "(let liaisons corps)"
(define (bloc-eval liaisons corps env)
(corps-eval corps (env-add-liaisons liaisons env)))
;; corps-eval: Corps * Environnement -> Valeur
;; (corps-eval corps env) rend la valeur de "corps" dans l'environnement "env"
(define (corps-eval corps env)
(let ((def-exp (corps-separation-defs-exps corps)))
(let ((defs (car def-exp))
(exps (cadr def-exp)))
(sequence-eval exps (env-enrichissement env defs)))))
;; corps-separation-defs-exps: Corps -> COUPLE[LISTE[Definition] LISTE[Expression]]
;; (corps-separation-defs-exps corps) rend un couple dont le premier elements est
;; la liste des definitions du corps "corps" et le second element est la liste des
;; expressions de ce corps
(define (corps-separation-defs-exps corps)
(if (definition? (car corps))
(let ((def-exp-cdr
(corps-separation-defs-exps (cdr corps))))
(cons (cons (car corps)
(car def-exp-cdr))
(cdr def-exp-cdr)))
(list '() corps)))
;; }}} Evaluateur