www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

meval-scheme.scm (24702B)


      1 #lang scheme
      2 ;; {{{ Grammaire du langage
      3 ;; Le langage interprete est defini par la grammaire suivante :
      4 ;; meval-scheme := expression
      5 ;;   expression := variable
      6 ;;              |  constante  | (QUOTE donnee)                    ; citation
      7 ;;              |  (COND clause *)                                ; conditionnelle
      8 ;;              |  (IF condition consequence [alternant])         ; alternative
      9 ;;              |  (BEGIN expression*)                            ; sequence
     10 ;;              |  (LET (liaison*) corps)                         ; bloc
     11 ;;              |  (fonction argument*)                           ; application
     12 ;;    condition := expression
     13 ;;  consequence := expression
     14 ;;    alternant := expression
     15 ;;       clause := (condition expressin*)
     16 ;;              |  (ELSE expression*)
     17 ;;     fonction := expression
     18 ;;     argument := expression
     19 ;;    constante := nombre | chaine | booleen | caractere
     20 ;;       donnee := constante
     21 ;;              |  symbole
     22 ;;              |  (donnee*)
     23 ;;      liaison := (variable expression)
     24 ;;        corps := definition* expression expression*
     25 ;;   definition := (DEFINE (nom-fonction variable*) corps)
     26 ;; nom-fonction := variable
     27 ;;     variable := tous les symboles de Scheme autres que les mots-cles
     28 ;;      symbole := tous les symboles de Scheme
     29 ;;   }}} Grammaire du langage
     30 
     31 ;; {{{ Utilitaire generaux
     32 ;;
     33 ;; Necessaires pour l'auto-amorcage (on pourrait egalement les placer
     34 ;; dans l'environnement initial)
     35 
     36 ;; Signaler une erreur et abandonner l'evaluation
     37 (define (scheme-erreur fn message donnee)
     38   (error "meval-scheme" fn message donnee))
     39 
     40 ;; cadr: LISTE[alpha]/au moins 2 termes/ -> alpha
     41 ;; (cadr L) rend le second terme de la liste "L"
     42 (define (cadr L)
     43   (car (cdr L)))
     44 
     45 ;; cddr: LISTE[alpha]/au moins 2 termes/ ->LISTE[alpha]
     46 ;; (cddr L) rend la liste "L" privee de ses deux premiers termes
     47 (define (cddr L)
     48   (cdr (cdr L)))
     49 
     50 ;; caddr: LISTE[alpha]/au moins 3 termes/ -> alpha
     51 ;; (caddr L) rend le troisieme terme de la liste "L"
     52 (define (caddr L)
     53   (car (cdr (cdr L))))
     54 
     55 ;; cdddr: LISTE[alpha]/au moins 3 termes/ -> LISTE[alpha]
     56 ;; (cdddr L) rend la liste "L" privee de ses trois premiers termes
     57 (define (cdddr L)
     58   (cdr (cdr (cdr L))))
     59 
     60 ;; cadddr: LISTE[alpha]/au moins 4 termes/ -> alpha
     61 ;; (cadddr L) rend le quatrieme terme de la liste "L"
     62 (define (cadddr L)
     63   (car (cdr (cdr (cdr L)))))
     64 
     65 ;; length: LISTE[alpha] -> entier
     66 ;; (length L) rend la longueur de la liste "L"
     67 (define (length L)
     68   (if (pair? L)
     69 	  (+ 1 (length (cdr L)))
     70 	  0))
     71 
     72 ;; meval-scheme-map: (alpha -> beta) * LISTE[alpha] -> LISTE[beta]
     73 ;; (meval-scheme-map f L) rend la liste des valeurs de "f" appliquee
     74 ;; aux termes de la liste "L"
     75 (define (meval-scheme-map f L)
     76   (if (pair? L)
     77 	  (cons (f (car L)) (meval-scheme-map f (cdr L)))
     78 	  '()))
     79 
     80 ;; member: alpha * LISTE[alpha] -> LISTE[alpha] + #f
     81 ;; (member e L) rend le suffixe de "L" debutant par la premiere
     82 ;; occurence de "e" ou #f si "e" n'apparait pas dans "L"
     83 (define (member e L)
     84   (if (pair? L)
     85 	  (if (equal? e (car L))
     86 		  L
     87 		  (member e (cdr L)))
     88 	  #f))
     89 
     90 ;; rang: alpha * LISTE[alpha] -> entier
     91 ;; (rang e L) rend le rang de l'element donne dans la liste "L"
     92 ;; (ou on sait que l'element apparait). Le premier element a pour rang 1.
     93 (define (rang e L)
     94   (if (equal? e (car L))
     95 	  1
     96 	  (+ 1 (rang e (cdr L)))))
     97 
     98 ;; }}} Utilitaire generaux
     99 
    100 ;; {{{ Barriere-syntaxique
    101 ;;
    102 ;; Ces fonctions permettent de manipuler les differentes expression syntaxiques
    103 ;; dont Scheme est forme. Pour chacune de ces differentes formes syntaxiques, on
    104 ;; trouve le reconnaisseur et les accesseurs.
    105 
    106 ;; variable?: Expression -> bool
    107 (define (variable? expr)
    108   (if (symbol? expr)
    109 	  (cond ((equal? expr 'cond)   #f)
    110 			((equal? expr 'else)   #f)
    111 			((equal? expr 'if)     #f)
    112 			((equal? expr 'quote)  #f)
    113 			((equal? expr 'begin)  #f)
    114 			((equal? expr 'let)    #f)
    115 			((equal? expr 'let*)   #f)
    116 			((equal? expr 'define) #f)
    117 			((equal? expr 'or)     #f)
    118 			((equal? expr 'and)    #f)
    119 			(else                  #t))
    120 	  #f))
    121 
    122 ;; citation?: Expression -> bool
    123 (define (citation? expr)
    124   (cond ((number? expr)  #t)
    125 		((char? expr)    #t)
    126 		((string? expr)  #t)
    127 		((boolean? expr) #t)
    128 		((pair? expr)    (equal? (car expr) 'quote))
    129 		(else            #f)))
    130 
    131 ;; conditionnelle?: Expression -> bool
    132 (define (conditionnelle? expr)
    133   (if (pair? expr)
    134 	  (equal? (car expr) 'cond)
    135 	  #f))
    136 
    137 ;; conditionnelle-clauses: Conditionnelle -> LISTE[Clause]
    138 (define (conditionnelle-clauses cond)
    139   (cdr cond))
    140 
    141 ;; alternative?: Expression -> bool
    142 (define (alternative? expr)
    143   (if (pair? expr)
    144 	  (equal? (car expr) 'if)
    145 	  #f))
    146 
    147 ;; alternative-condition: Alternative -> Expression
    148 (define (alternative-condition alt)
    149   (cadr alt))
    150 
    151 ;; alternative-consequence: Alternative -> Expression
    152 (define (alternative-consequence alt)
    153   (caddr alt))
    154 
    155 ;; alternative-alternant: Alternative -> Expression
    156 (define (alternative-alternant alt)
    157   (if (pair? (cdddr alt))
    158 	  (cadddr alt)
    159 	  #f))
    160 
    161 ;; sequence?: Expression -> bool
    162 (define (sequence? expr)
    163   (if (pair? expr)
    164 	  (equal? (car expr) 'begin)
    165 	  #f))
    166 
    167 ;; sequence-exprs: Expression -> LISTE[Expression]
    168 (define (sequence-exprs expr)
    169   (cdr expr))
    170 
    171 ;; bloc?: Expression -> bool
    172 (define (bloc? expr)
    173   (if (pair? expr)
    174 	  (equal? (car expr) 'let)
    175 	  #f))
    176 
    177 ;; bloc-liaisons: Bloc -> LISTE[Liaison]
    178 (define (bloc-liaisons bloc)
    179   (cadr bloc))
    180 
    181 ;; bloc-corps: Bloc -> Corps
    182 (define (bloc-corps bloc)
    183   (cddr bloc))
    184 
    185 ;; application?: Expression -> bool
    186 (define (application? expr)
    187   (pair? expr))
    188 
    189 ;; application-fonction: Application -> Expression
    190 (define (application-fonction app)
    191   (car app))
    192 
    193 ;; application-arguments: Application -> LISTE[Expression]
    194 (define (application-arguments app)
    195   (cdr app))
    196 
    197 ;; clause-condition: Clause -> Expression
    198 (define (clause-condition clause)
    199   (car clause))
    200 
    201 ;; clause-expressions: Clause -> LISTE[Expression]
    202 (define (clause-expressions clause)
    203   (cdr clause))
    204 
    205 ;; liaison-variable: Liaison -> Variable
    206 (define (liaison-variable liaison)
    207   (car liaison))
    208 
    209 ;; liaison-expr: Liaison -> Expression
    210 (define (liaison-expr liaison)
    211   (cadr liaison))
    212 
    213 ;; definition?: Corps -> bool
    214 ;; (definition? corps) rend #t ssi le premier elements de "corps" est une definition
    215 (define (definition? corps)
    216   (if (pair? corps)
    217 	  (equal? (car corps) 'define)
    218 	  #f))
    219 
    220 ;; definition-nom-fonction: Definition -> Variable
    221 (define (definition-nom-fonction def)
    222   (car (cadr def)))
    223 
    224 ;; definition-variables: Definition -> LISTE[Variable]
    225 (define (definition-variables def)
    226   (cdr (cadr def)))
    227 
    228 ;; definition-corps: Definition -> Corps
    229 (define (definition-corps def)
    230   (cddr def))
    231 
    232 ;; }}} Barriere-syntaxique
    233 
    234 ;; {{{ Evaluateur
    235 
    236 ;; meval-scheme: Expression -> Valeur
    237 ;; (meval-scheme e) rend la valeur de l'expression "e"
    238 (define (meval-scheme e)
    239   (evaluation e (env-initial)))
    240 
    241 ;; evaluation: Expression * Environnement -> Valeur
    242 ;; (evaluation expr env) rend la valeur de l'expression "expr" dans l'environnement "env"
    243 (define (evaluation expr env)
    244   ;; (discrimine l'expression et invoque l'evaluateur specialise)
    245   (cond
    246    ((variable? expr) (variable-val expr env))
    247    ((citation? expr) (citation-val expr))
    248    ((alternative? expr) (alternative-eval
    249 						 (alternative-condition expr)
    250 						 (alternative-consequence expr)
    251 						 (alternative-alternant expr) env))
    252    ((conditionnelle? expr) (conditionnelle-eval
    253 							(conditionnelle-clauses expr) env))
    254    ((sequence? expr) (sequence-eval (sequence-exprs expr) env))
    255    ((bloc? expr) (bloc-eval (bloc-liaisons expr)
    256 							(bloc-corps expr) env))
    257    ((application? expr) (application-eval
    258 						 (application-fonction expr)
    259 						 (application-arguments expr) env))
    260    (else
    261 	(scheme-erreur 'evaluation "pas un programme" expr))))
    262 
    263 ;; alternative-eval: Expression3 * Environnement -> Valeur
    264 ;; (alternative-eval condition consequence alternant env) rend la valeur de
    265 ;; l'expression "(if condition consequence alternant)" dans l'environnement "env"
    266 (define (alternative-eval condition consequence alternant env)
    267   (if (evaluation condition env)
    268 	  (evaluation consequence env)
    269 	  (evaluation alternant env)))
    270 
    271 ;; conditionnelle-eval: LISTE[Clause] -> Expression
    272 ;; (conditionnelle-eval clauses env) rend la valeur, dans l'environnement "env",
    273 ;; de l'expression "(cond c1 c2 ... cn)".
    274 (define (conditionnelle-eval clauses env)
    275   (evaluation (cond-expansion clauses) env))
    276 
    277 ;; cond-expansion: LISTE[Clause] -> Expression
    278 ;; (cond-expansion clauses) rend l'expression, ecrite avec des alternatives,
    279 ;; equivalente a l'expression "(cond c1 c2 .. cn)".
    280 (define (cond-expansion clauses)
    281   (if (pair? clauses)
    282 	  (let ((first-clause (cadr clauses)))
    283 		(if (equal? (clause-condition first-clause) 'else)
    284 			(cons 'begin (clause-expressions first-clause))
    285 			(cons 'if
    286 				  (cons
    287 				   (clause-condition first-clause)
    288 				   (cons
    289 					(cons 'begin (clause-expressions first-clause))
    290 					(let ((seq (cond-expansion (cdr clauses))))
    291 					  (if (pair? seq)
    292 						  (list seq)
    293 						  seq)))))))
    294 	  '()))
    295 
    296 ;; sequence-eval: LISTE[Expression] * Environnement -> Valeur
    297 ;; (sequence-eval exprs env) rend la valeur, dans l'environnement "env",
    298 ;; de l'expression "(begin e1 ... en)". (Il faut evaluer tour a tour les
    299 ;; expressions et rendre la valeur de la derniere expression.)
    300 (define (sequence-eval exprs env)
    301   ;; sequence-eval+: LISTE[Expression]/non vide/ -> Valeur
    302   ;; meme fonction, sachant que la liste "exprs" n'est pas vide et en globalisant
    303   ;; la variable "env"
    304   (define (sequence-eval+ exprs)
    305 	(if (pair? (cdr exprs))
    306 		(begin (evaluation (car exprs) env)
    307 			   (sequence-eval+ (cdr exprs)))
    308 		(evaluation (car exprs) env)))
    309   ;; expression de (sequence-eval exprs env):
    310   (if (pair? exprs)
    311 	  (sequence-eval+ exprs)
    312 	  #f))
    313 
    314 ;; application-eval: Expression * LISTE[Expression] * Environnement -> Valeur
    315 ;; (application-eval exp-fn args env) rend la valeur de l'invocation de
    316 ;; l'expression "exp-fn" aux arguments "args" dans l'environnement "env"
    317 (define (application-eval exp-fn args env)
    318   ;; eval-env : Expression -> Valeur
    319   ;; (eval-env expr) rend la valeur de "expr" dans l'environnement "env"
    320   (define (eval-env expr)
    321 	(evaluation expr env))
    322   ;;expression de (application-eval exp-fn args env) :
    323   (let ((f (evaluation exp-fn env)))
    324 	(if (invocable? f)
    325 		(invocation f (meval-scheme-map eval-env args))
    326 		(scheme-erreur 'application-eval
    327 					   "pas une fonction" f))))
    328 
    329 ;; bloc-eval: LISTE[Liaison] * Corps * Environnement -> Valeur
    330 ;; (bloc-eval liaisons corps env) rend la valeur, dans l'environnement "env"
    331 ;; de l'expression "(let liaisons corps)"
    332 (define (bloc-eval liaisons corps env)
    333   (corps-eval corps (env-add-liaisons liaisons env)))
    334 
    335 ;; corps-eval: Corps * Environnement -> Valeur
    336 ;; (corps-eval corps env) rend la valeur de "corps" dans l'environnement "env"
    337 (define (corps-eval corps env)
    338   (let ((def-exp (corps-separation-defs-exps corps)))
    339 	(let ((defs (car def-exp))
    340 		  (exps (cadr def-exp)))
    341 	  (sequence-eval exps (env-enrichissement env defs)))))
    342 
    343 ;; corps-separation-defs-exps: Corps -> COUPLE[LISTE[Definition] LISTE[Expression]]
    344 ;; (corps-separation-defs-exps corps) rend un couple dont le premier elements est
    345 ;; la liste des definitions du corps "corps" et le second element est la liste des
    346 ;; expressions de ce corps
    347 (define (corps-separation-defs-exps corps)
    348   (if (definition? (car corps))
    349 	  (let ((def-exp-cdr
    350 			  (corps-separation-defs-exps (cdr corps))))
    351 		(cons (cons (car corps)
    352 					(car def-exp-cdr))
    353 			  (cdr def-exp-cdr)))
    354 	  (list '() corps)))
    355 
    356 ;; }}} Evaluateur
    357 
    358 ;; {{{ Barriere-interpretation
    359 
    360 ;; Un programme Scheme comme LISP decrit deux sortes d'objets: les valeurs non fonctionnelles
    361 ;; (entier, bool, liste...) et les valeurs fonctionnelles
    362 
    363 ;;   {{{ Valeurs-non-fonctionnelles
    364 
    365 ;; citation-val: Citation -> Valeur/non fonctionnelle/
    366 ;; (citation-val cit) rend la valeur de la citation "cit"
    367 (define (citation-val cit)
    368   (if (pair? cit)
    369 	  (cadr cit)
    370 	  cit))
    371 
    372 ;;   }}} Valeur-non-fonctionnelles
    373 
    374 ;;   {{{ Valeur-fonctionnelles
    375 
    376 ;; Il y a deux type de fonctions, les fonctions predefinies (reconnues par primitive? en Scheme
    377 ;; et special-form-p en LISP) et les fonctions du programme en cours d'evaluation (creer par
    378 ;; fonction-creation)
    379 
    380 ;; invocable?: Valeur -> bool
    381 ;; (invocable? val) rend vrai ssi "val" est un fonction (primitive ou definie)
    382 (define (invocable? val)
    383   (if (primitive? val)
    384 	  #t
    385 	  (fonction? val)))
    386 
    387 ;; invocation: Invocable * LISTE[Valeur] -> Valeur
    388 ;; (invocation f args) rend la valeur de l'application de "f" aux elements de "vals"
    389 (define (invocation f args)
    390   (if (primitive? f)
    391 	  (primitive-invocation f args)
    392 	  (fonction-invocation f args)))
    393 
    394 ;;     {{{ Primitives
    395 
    396 ;; Une primitive est implantee par un 4-uplet :
    397 ;; - le premier element est le symbole *primitive* (pour les reconnaitre)
    398 ;; - le second element est la fonction du Scheme sous-jacent qui implante la primitive,
    399 ;; - le troisieme element est un comparateur (= ou >=)
    400 ;; - le quatrieme element est un entier naturel, ces deux derniers elements permettant
    401 ;;   de specifier l'arite de la primitive.
    402 
    403 ;; primitive?: Valeur -> bool
    404 ;; (primitive? val) rend vrai ssi "val" est une fonction primitive
    405 (define (primitive? val)
    406   (if (pair? val)
    407 	  (equal? (car val) '*primitive*)
    408 	  #f))
    409 
    410 ;; primitive-creation: N-UPLET[(Valeur... -> Valeur)(num * num -> bool) num] -> Primitive
    411 ;; (primitive-creation f-c-n) rend la primitive implantee par la fonction (du Scheme sous-jacent)
    412 ;; "f", le premier element de "f-c-n", et dont l'arite est specifier par le
    413 ;; comparateur "c", deuxieme element de "f-c-n" et l'entier "n", le troisieme element
    414 (define (primitive-creation f-c-n)
    415   (cons '*primitive* f-c-n))
    416 
    417 ;; primitive-invocation: Primitive * LISTE[Valeur] -> Valeur
    418 ;; (primitive-invocation p args) rend la valeur de l'application de la primitive "p" aux element
    419 ;; de args
    420 (define (primitive-invocation p args)
    421   (let ((n       (length args))
    422 		(f       (cadr p))
    423 		(compare (caddr p))
    424 		(arite   (cadddr p)))
    425 	(if (compare n arite)
    426 		(cond
    427 		 ((= n 0) (f))
    428 		 ((= n 1) (f (car args)))
    429 		 ((= n 2) (f (car args) (cadr args)))
    430 		 ((= n 3) (f (car args) (cadr args) (caddr args)))
    431 		 ((= n 4) (f (car args) (cadr args) (caddr args) (cadddr args)))
    432 		 (else
    433 		  (scheme-erreur 'primitive-invocation
    434 						 "limite implantation (arite quelconque < 5)" args)))
    435 		(scheme-erreur 'primitive-invocation
    436 					   "arite incorrecte" args))))
    437 
    438 ;;     }}} Primitives
    439 
    440 ;;     {{{ Fonction-meta-definies
    441 
    442 ;; Une fonction definie est implantee par un 4-uplet:
    443 ;; - le premier element est le symbole *fonction* (pour les reconnaitre)
    444 ;; - le second element est la liste des variables de la definition de la fonction
    445 ;; - le troisieme element est le corps de la definition de la fonction
    446 ;; - le dernier element est l'environnement ou est definie la fonction
    447 
    448 ;; fonction?: Valeur -> bool
    449 ;; (fonction? val) rend vrai ssi "val" est une fonction meta-definie
    450 (define (fonction? val)
    451   (if (pair? val)
    452 	  (equal? (car val) '*fonction*)
    453 	  #f))
    454 
    455 ;; fonction-invocation: Fonction * LISTE[Valeur] -> Valeur
    456 ;; (fonction-invocation f args) rend la valeur de l'application de la fonction
    457 ;; meta-definie "f" aux element de "args"
    458 (define (fonction-invocation f args)
    459   (let ((variables (cadr f))
    460 		(corps     (caddr f))
    461 		(env       (cadddr f)))
    462 	(corps-eval corps (env-extension env variables args))))
    463 
    464 ;; fonction-creation: Definition * Environnement -> Fonction
    465 ;; (fonction-creation definition env) rend la fonction definie par "definition" dans
    466 ;; l'environnement "env"
    467 (define (fonction-creation definition env)
    468   (list '*fonction*
    469 		(definition-variables definition)
    470 		(definition-corps definition)
    471 		env))
    472 
    473 ;;     }}} Fonctions-meta-definies
    474 ;;  }}} Valeurs-fonctionnelles
    475 ;; }}} Barriere-interpretation
    476 
    477 ;; {{{ Environnement-H (barriere de haut niveau)
    478 
    479 ;; variable-val: Variable * Environnement -> Valeur
    480 ;; (variable-val var env) rend la valeur de la variable "var" dans l'environnement "env"
    481 (define (variable-val var env)
    482   (if (env-non-vide? env)
    483 	  (let ((bloc (env-1er-bloc env)))
    484 		(let ((variables (blocActivation-variables bloc)))
    485 		  (if (member var variables)
    486 			  (blocActivation-val bloc var)
    487 			  (variable-val var (env-reste env)))))
    488 	  (scheme-erreur 'variable-val "variable inconnue" var)))
    489 
    490 ;; env-extension: Environnement * LISTE[Variable] * LISTE[Valeur] -> Environnement
    491 ;; (env-extension env vars vals) rend l'environnement "env" etendu avec un bloc
    492 ;; d'activation liant les variables "vars" aux valeurs "vals"
    493 (define (env-extension env vars vals)
    494   (if (= (length vars) (length vals))
    495 	  (let ((bloc (blocActivation-creation vars)))
    496 		(begin
    497 		  (blocActivation-mettre-valeurs! bloc vals)
    498 		  (env-add bloc env)))
    499 	  (scheme-erreur 'env-extension
    500 					 "arite incorrecte" (list vars vals))))
    501 
    502 ;; env-add-liaisons: LISTE[Liaison] * Environnement -> Environnement
    503 ;; (env-add-liaisons liaisons env) rend l'environnement obtenu en ajoutant a l'environnement
    504 ;; "env", les liaisons "liaisons"
    505 (define (env-add-liaisons liaisons env)
    506   ;; eval-env: Expression -> Valeur
    507   ;; (eval-env exp) rend la valeur de "exp" dans l'environnement "env"
    508   (define (eval-env exp)
    509 	(evaluation exp env))
    510   ;; expression de (env-add-liaisons env) :
    511   (env-extension
    512    env
    513    (meval-scheme-map liaison-variable liaisons)
    514    (meval-scheme-map eval-env
    515 					 (meval-scheme-map liaison-expr liaisons))))
    516 
    517 ;; env-enrichissement: Environnement * LISTE[Definition] -> Environnement
    518 ;; (env-enrichissement env defs) rend l'environnement "env" etendu avec un bloc
    519 ;; d'activation pour les definitions fonctionnelles "defs"
    520 (define (env-enrichissement env defs)
    521   (let ((noms (meval-scheme-map definition-nom-fonction defs)))
    522 	(let ((bloc (blocActivation-creation noms)))
    523 	  (let ((env-plus (env-add bloc env)))
    524 		(define (fonction-creation-env-plus definition)
    525 		  (fonction-creation definition env-plus))
    526 		(begin
    527 		  (blocActivation-mettre-valeurs!
    528 		   bloc
    529 		   (meval-scheme-map fonction-creation-env-plus defs))
    530 		  env-plus)))))
    531 
    532 ;;   {{ Environnement-B (barriere de bas niveau)
    533 
    534 ;; Les environnement sont representes par la structure de donnees
    535 ;; LISTE[BlocActivation]
    536 
    537 ;; env-vide: -> Environnement
    538 ;; (env-vide) rend l'environnement vide
    539 (define (env-vide) '())
    540 
    541 ;; env-non-vide?: Environnement -> bool
    542 ;; (env-non-vide? env) rend #t ssi l'environnement "env" n'est pas vide
    543 (define (env-non-vide? env)
    544   (pair? env))
    545 
    546 ;; env-add: Environnement * BlocActivation -> Environnement
    547 ;; (env-add bloc env) rend l'environnement obtenu en ajoutant devant
    548 ;; l'environnement "env" le bloc d'activation "bloc"
    549 (define (env-add bloc env)
    550   (cons bloc env))
    551 
    552 ;; env-1er-bloc: Environnement -> BlocActivation
    553 ;; (env-1er-bloc env) rend le premier bloc (le dernier dans la liste) d'activation
    554 ;; de l'environnement "env"
    555 ;; ERREUR lorsque l'environnement donnee est vide
    556 (define (env-1er-bloc env)
    557   (car env))
    558 
    559 ;; env-reste: Environnement -> Environnement
    560 ;; (env-reste env) rend l'environnement obtenu en supprimant le premier bloc d'activation
    561 ;; de l'environnement "env"
    562 ;; ERREUR lorsque l'environnement donnee est vide
    563 (define (env-reste env)
    564   (cdr env))
    565 
    566 ;;     {{{ Bloc d'activation
    567 
    568 ;; Les blocs d'activation sont representes par la structure de donnees:
    569 ;; VECTEUR[LISTE[Variables] Valeur ...]
    570 
    571 ;; blocActivation-variables: BlocActivation -> LISTE[Variable]
    572 ;; (blocActivation-variables bloc) rend la liste des variables definies
    573 ;; dans le bloc d'activation "bloc"
    574 (define (blocActivation-variables bloc)
    575   (vector-ref bloc 0))
    576 
    577 ;; blocActivation-val: BlocActivation * Variable -> Valeur
    578 ;; (blocActivation-val bloc var) rend la valeur de la variable "var" dans le bloc
    579 ;; d'activation "bloc"
    580 ;; HYPOTHESE: "var" est une variable definie dans le "bloc"
    581 (define (blocActivation-val bloc var)
    582   (let ((i (rang var (blocActivation-variables bloc))))
    583 	(vector-ref bloc i)))
    584 
    585 ;; blocActivation-creation: LISTE[Variable] -> BlocActivation
    586 ;; (blocActivation-creation vars) rend un bloc d'activation contenant la liste des variables
    587 ;; "vars" avec la place qu'il faut pour les valeurs de ces variables, cette place n'etant pas
    588 ;; remplie
    589 (define (blocActivation-creation vars)
    590   (let ((bloc (make-vector (+ 1 (length vars)))))
    591 	(begin
    592 	  (vector-set! bloc 0 vars)
    593 	  bloc)))
    594 
    595 ;; blocActivation-mettre-valeurs!: BlocActivation * LISTE[Valeur] -> Rien
    596 ;; (blocActivation-mettre-valeurs! bloc vals) affecte les valeurs "vals" (donnees sous forme de
    597 ;; liste) dans le bloc d'activation "bloc".
    598 (define (blocActivation-mettre-valeurs! bloc vals)
    599   ;; remplir!: entier * LISTE[Valeur] -> Rien
    600   ;; (remplir! i vals) remplit les cases du vecteur "bloc" a partir de l'indice "i", avec les valeurs
    601   ;; de la liste "vals" (et dans le meme ordre)
    602   (define (remplir! i vals)
    603 	(if (pair? vals)
    604 		(begin
    605 		  (vector-set! bloc i (car vals))
    606 		  (remplir! (+ i 1) (cdr vals)))
    607                 null))
    608   (remplir! 1 vals))
    609 
    610 ;;     }}} Bloc d'activation
    611 ;;   }}} Environnement-B (barriere de bas niveau
    612 
    613 ;;   {{{ Environnement-initial
    614 
    615 ;; L'environnement initial est compose des primitives.
    616 ;; Pour faciliter la description des differentes primitives (et par manque de temps :D)
    617 ;; on les ecrira sous forme d'une liste de description de primitive.
    618 ;; Une element du type DescriptionPrimitive est une description d'une primitive. C'est
    619 ;; une liste dont :
    620 ;; - le premier element est la variable representant la primitive consideree
    621 ;; - les trois autres elements sont les trois elements qui decrivent
    622 ;; l'implantation de la primitive (la fonction Scheme, le comparateur, et l'arite)
    623 
    624 ;; env-initial -> Environnement
    625 ;; (env-initial) rend l'environnement initial (l'environnement qui contient toutes les primitives.
    626 (define (env-initial)
    627   (env-extension
    628    (env-vide)
    629    (meval-scheme-map car (descriptions-primitives))
    630    (meval-scheme-map primitive-creation
    631 					 (meval-scheme-map cdr
    632 									   (descriptions-primitives)))))
    633 
    634 ;; description-primitive: Variable * (Valeur ... -> Valeur) * (num * num -> bool) * num -> DescriptionPrimitive
    635 ;; (description-primitive var f comparator arite) rend la description de la primitive designee par "var" implantee
    636 ;; dans Scheme par "f" et dont l'arite est definie par "comparator" et "arite"
    637 (define (description-primitive var f comparator arite)
    638   (list var f comparator arite))
    639 
    640 ;; descriptions-primitives: -> LISTE[DescriptionPrimitive]
    641 ;; (descriptions-primitives) rend la liste des descriptions de toutes les primitives
    642 (define (descriptions-primitives)
    643   (cons (description-primitive 'car             car              =   1)
    644   (cons (description-primitive 'cdr             cdr              =   1)
    645   (cons (description-primitive 'cons            cons             =   2)
    646   (cons (description-primitive 'list            list             >=  0)
    647   (cons (description-primitive 'vector-length   vector-length    =   1)
    648   (cons (description-primitive 'vector-ref      vector-ref       =   2)
    649   (cons (description-primitive 'vector-set!     vector-set!      =   3)
    650   (cons (description-primitive 'make-vector     make-vector      =   1)
    651   (cons (description-primitive 'pair?           pair?            =   1)
    652   (cons (description-primitive 'symbol?         symbol?          =   1)
    653   (cons (description-primitive 'number?         number?          =   1)
    654   (cons (description-primitive 'string?         string?          =   1)
    655   (cons (description-primitive 'boolean?        boolean?         =   1)
    656   (cons (description-primitive 'vector?         vector?          =   1)
    657   (cons (description-primitive 'char?           char?            =   1)
    658   (cons (description-primitive 'equal?          equal?           =   2)
    659   (cons (description-primitive '+               +                >=  0)
    660   (cons (description-primitive '-               -                =   2)
    661   (cons (description-primitive '*               *                >=  0)
    662   (cons (description-primitive '/               /                =   2)
    663   (cons (description-primitive '=               =                =   2)
    664   (cons (description-primitive '<               <                =   2)
    665   (cons (description-primitive '>               >                =   2)
    666   (cons (description-primitive '<=              <=               =   2)
    667   (cons (description-primitive '>=              >=               =   2)
    668   (cons (description-primitive 'remainder      remainder         =   2)
    669   (cons (description-primitive 'display        display           =   1)
    670   (cons (description-primitive 'newline        newline           =   0)
    671   (cons (description-primitive 'read           read              =   0)
    672   (cons (description-primitive 'error          error             >=  2)
    673 		(list))))))))))))))))))))))))))))))))
    674 
    675 ;;   }}} Environnement-initial
    676 ;; }}} Environnement-H (barriere de haut niveau)