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)