Advertisement
Guest User

Untitled

a guest
Jan 25th, 2018
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. La leçon de programmation la plus importante
  2. ============================================
  3.  
  4. Normalement, comme c'est la leçon de programmation la plus importante,
  5. elle aurait du déjà être enseignée avec les autres langages de
  6. programmation!
  7.  
  8.  
  9. Le principal problème dans le code que tu as écris, c'est le manque
  10. d'abstration.
  11.  
  12. Par exemple, le fait d'utiliser GET partout. Cela implique un choix
  13. d'implantation trés spécifique pour la VM, à savoir qu'un VM est
  14. représentée par un symbole (pourquoi?) et ses attributs par des
  15. entrées dans la p-list du symbole (avec un accès linéaire O(n) sur les
  16. attributs, ce qui est coûteux, mais c'est accessoire).
  17.  
  18. La conséquence, c'est que si on voulait changer l'implantation de la
  19. VM, il faudrait changer tout le code, remplacer tous ces appels à GET.
  20.  
  21. Un autre inconvénient, ça n'aide pas à la compréhension de la
  22. signification du code. C'est particulièrement intriguant, dans
  23. l'utilisation de fonctions comme CADADR. On voit bien que on va
  24. naviguer dans un arbre de paires, mais quel rapport est-ce que ça a
  25. avec une machine virtuelle? (Avec GET, on voit bien qu'on va chercher
  26. une propriété dans une p-list, mais quel rapport est-ce que ça a avec
  27. une machine virtuelle? (C'est plus facile à deviner, mais c'est le
  28. même principe)).
  29.  
  30.  
  31. Pour résoudre ce problème, on peut utiliser une abstraction fonctionnelle.
  32.  
  33. Il s'agit d'une fonction ou d'un groupe de fonction ayant un nom (et
  34. donc, une fonction) significative pour le domaine du problème.
  35.  
  36. Ainsi, si on défini des fonctions comme:
  37.  
  38. vm-memory
  39. vm-r0
  40. vm-r1
  41. vm-r2
  42. vm-r3
  43. vm-pc
  44. vm-fp
  45. vm-dpp
  46.  
  47. etc, on voit bien que l'on a affaire à des composant d'une machine virtuelle.
  48.  
  49. Même si tu choisis d'implanter la machine virtuelle avec un symbole et
  50. sa p-list, le fait d'introduire ces abstractions fonctionnelle vont
  51. rendre ton code bien plus limpide, et maintenable:
  52.  
  53.  
  54. (defun vm-memory (vm) (get vm :memtab))
  55. (defun vm-r0 (vm) (get vm :r0))
  56. (defun vm-pc (vm) (get vm :pc))
  57.  
  58.  
  59. Ainsi, quand on écrit:
  60.  
  61. (defun memref (vm adr) (aref (vm-memtab vm) adr))
  62. (defun (setf memref) (val vm adr) (setf (aref (vm-memtab vm) adr) val))
  63.  
  64. on voit tout de suite qu'on indexe (avec aref), a memtab de la vm.
  65.  
  66.  
  67.  
  68. Si tu introduis l'abstraction fonctionnelle suivante pour les instructions:
  69. (defun operation (instruction) (car operation))
  70. (defun premier-operande (instruction) (cadr operation))
  71. (defun second-operande (instruction) (caddr operation))
  72.  
  73. Alors une fonction comme:
  74.  
  75. (defun sautp (inst)
  76. (member (operation inst) '(JMP JEQ JL JG JLE JGE JNE)))
  77.  
  78. devient tout de suite plus claire.
  79.  
  80. etc.
  81.  
  82.  
  83. Tel qu'il est, le code n'est pas clair; par exemple, on a du mal à
  84. comprendre quel est le format d'un programme assembleur
  85. source. D'après load-machine, on a une simple liste non structurée,
  86. mais comme on n'a pas d'abstraction fonctionnelle, on ne voit pas bien
  87. quelle syntaxe ASM doit avoir. Dans ce cas, tu aurais du le documenter!
  88. Mais mieux que documenter, c'est avoir un code limpide.
  89. Par exemple en écrivant l'abstraction fonctionnelle suivante:
  90.  
  91. (premiere-instruction code) -> instruction
  92. (instructions-suivantes code) -> code-ou-nil
  93. (fin-du-code-p code-ou-nil) -> boolean
  94.  
  95. (etiquette instruction) -> etiquette-ou-nil
  96. (operation instruction) -> operation
  97. (premier-operande instruction) -> operande
  98. (second-operande instruction) -> operande-ou-nil
  99.  
  100.  
  101. Avec de telles abstraction, on peut alors écrire de façon plus claire et lisible :
  102.  
  103. (defun load-machine (vm asm)
  104. (loop
  105. :with etiqLoc := (make-hash-table :size (get vm :taille))
  106. :with etiqLocNR := (let ((table (make-hash-table :size (get vm :taille))))
  107. (setf (gethash 'nb table) 0)
  108. table)
  109. :for code := asm :then (instructions-suivantes code)
  110. :for instruction := (premiere-instruction asm)
  111. :do (case (operation instruction)
  112. ((@) (case-adr vm code instrution etiqLoc etiqLocNR))
  113. ((JSR) (case-saut vm code instrution))
  114. ((FEntry) (case-fonction vm code instrution))
  115. (otherwise (case-other vm code instrution etiqLoc etiqLocNR)))
  116. :until (fin-du-code-p code)))
  117.  
  118.  
  119. Mais surtout, si on veut changer le format de ASM, ou changer
  120. l'implantation de VM, on n'a plus besoin de modifier le programme! Le
  121. programme devient indépendant des choix d'implantation de ces modules.
  122.  
  123. Il suffit de modifier l'implantation des abstractions fonctionnelles.
  124.  
  125.  
  126. Au lieu d'écire:
  127.  
  128. (defun vm-memory (vm) (get vm :memtab))
  129. (defun vm-r0 (vm) (get vm :r0))
  130. (defun vm-pc (vm) (get vm :pc))
  131.  
  132. on écrit:
  133.  
  134. (defstruct vm
  135. memory
  136. r0 r1 r2 r3
  137. pc sp
  138. …)
  139.  
  140. ou:
  141.  
  142. (defstruct (vm (:type vector))
  143. memory
  144. r0 r1 r2 r3
  145. pc sp
  146. …)
  147.  
  148. ou:
  149.  
  150. (defclass vm ()
  151. ((memory :initarg :memory :accessor vm-memory)
  152. (r0 :initarg :r0 :initform 0 :accessor :vm-r0)
  153. …))
  154.  
  155. ou n'importe quoi, qui défini ces fonctions, et on obtient
  156. automatiquement un programme qui fonctionne avec les nouvelles
  157. propriétés du module.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement