Folco (./53) :
Marrant, je suis du genre à laisser pisser dans un premier temps, finir le reste de ce que j'écris, et revenir dessus même longtemps après. C'est une erreur, une faute de discipline quand on code ?
Je ne pense pas. Mais mon avis n'est pas celui d'un informaticien qui a plusieurs années de métier... Je ne développe que des petits trucs, sur mon temps libre, comme toi en fait

En ce qui me concerne, tout dépend du contexte, mais j'essaie de ne pas garder trop longtemps des sources qui ne compilent pas, donc je bouche les trous assez vite quand même, et pour les gros truc, j'implémente une fonction vide (ou presque vide).
Kevin Kofler (./47) :
top-down
Je vous vois souvent avec ce mot, c'est pas ce qu'on appelle l'analyse descendante ?
Oui, c'est un peu ça

Sauf qu'en fait quand on parle d'analyse descendante, on commence vraiment loin du code, comme ce qu'a décrit Vertyos, pour finir dans les détails d'implémentations.
ie j'écris un bout de code qui a besoin de trier une liste, j'écris tout simplement "call TtriList(list)", puis je passe à la suite sans avoir écrit TriList ? Il faut au moins designer TriList quand même, non ?
Qu'appelles-tu "designer" ?
Je veux donc, en vrac :- assembler plusieurs sources
C'est-à-dire ? Assembler plusieurs fichiers .asm et les coller bout à bout au moment de l'édition de liens ? Ou bien gérer l'inclusion de fichiers ? Au fait, tu ne comptes pas séparer l'assemblage de l'édition des liens ?
- créer des relogements au format kernel et AMS-native- produire du kernel, du nostub, voire de la chaine exec (bonus, sachant que c'est fait pour PedroM : on peut classer ça à l'état de lubie).
Ces deux points se rejoignent non ? Je les aurais écrits sur la même ligne

Sinon, tu n'as pas parlé de lib, mais j'imagine que tu y songeais aussi non ?
Comment je compte m'y prendre ? ...Je dispose déjà d'un handle où sont écrits tous les pointeurs vers les sources ouverts
Ouch, à mon avis tu pars très vite dans un détail qui ne devrait te préoccuper que dans un moment... Et tout le reste de ton post ne porte que sur des détails d'implémentation qui à mon avis sont un peu prématurés (mais je ne me rends pas bien compte du recul que tu as sur ton projet).
Quelques questions/suggestions :
Tu veux transformer un (ou plusieurs) fichier texte en exécutable ;
Pour cela il faut lire le contenu du premier fichier source, et identifier les mots qui y sont inscrits. Quels types de mots peux-tu rencontrer (instructions, labels, opérandes, directives préprocesseur, etc.) ? Tu rencontreras aussi des expressions mathématiques, genre
move.w #2*(label2-label1), d0, comment gérer toutes les entrées possible sans écrire un code trop spaghetti ? Surtout que, en outre, tu devras être capable de
détecter et gérer les erreurs de syntaxe ! Ensuite, dans tout ce que tu liras, tu trouveras des appels de macro, des labels, des références à des labels non connus, etc. Pour simplifier les choses tu peux faire plusieurs passes sur chaque fichier source : une première où tu fais tout le travail du préprocesseur (inclusion de fichier, substitution des equ et des macros), une deuxième où tu références toutes les déclarations de labels, et une dernière où tu peux lire tout le fichier source et l'assembler en étant sûr de ne rencontrer aucun symbole inconnu. Mais tu peux aussi tout faire en une seule passe, mais ça implique quelques limitations : le programmeur ne pourra pas faire d'appel de macro sans avoir défini la macro auparavant, idem pour les equ, etc. À toi de peser le pour et le contre, de voir si toutes les features que tu veux seront respectées ou non si tu choisis l'une ou l'autre méthode, si tu estimes que ça va être le bordel à coder ou non, si tu estimes que tu vas gagner un sacré temps d'exécution, etc.
On pourrait décomposer l'analyse du texte en deux phases : une première qui permet d'identifier la nature des mots (ou caractères) que tu rencontres (genre ce fichier source contient une directive include, suivie d'une chaîne contenant
preos.h, suivie d'un retour à la ligne, suivi d'un identificateur (un nom) ayant pour valeur
main, suivi de deux points, suivi d'un retour à la ligne, suivi d'une tabulation, suivi d'un nom d'instruction, suivie d'un point, suivie d'une taille d'opérande correspondant à
byte, suivie du signe dièse, suivi d'un nombre, suivi d'une virgule, suivie d'un nom de registre, etc. un peu comme si dans une phrase en français tu décortiquais la nature de mots utilisés et de la ponctuation), et une deuxième phase qui analyserait le sens des mots précédemment reconnus (est-ce qu'ils forment une phrase correcte ?) et te permettrait d'obtenir une information du genre : déclaration d'un label
main, instruction
move opérant sur des bytes, dont le premier opérande est une valeur immédiate et le second est le registre de données
d0. La première phase s'appelle l'analyse lexicale et la seconde s'appelle l'analyse syntaxique (sur Internet tu pourras trouver des ressources là-dessus). Une fois que tu as toutes ces informations, tu peux aisément générer le code correspondant, tu te retrouveras avec un fichier contenant des suites d'opcodes correspondant aux instructions écrites dans le fichier source. Il te restera encore à ajouter les headers qui vont bien avant pour correspondre au format kernel (par exemple), si cela a été spécifié dans le source, par une directive d'assemblage (puisque c'est comme ça que fonctionne a68k si mes souvenirs sont bons, et que tu veux être compatible avec a68k).
Résumons, tu aurais donc 4 étapes :
- Analyse lexicale ;
- Analyse syntaxique ;
- Génération du code ;
- Édition des liens.
On peut reprendre ces étapes, une par une et essayer de les décomposer en processus plus simples, en vérifiant toujours qu'on reste compatible avec les features que tu veux. Par exemple, lors de l'analyse lexicale tu auras à gérer les directives du préprocesseur (include, macro, etc.), tu ne te limiteras pas à reconnaître les différents "mots" (ou caractères) écrits par le programmeur. Ainsi, quand tu rencontreras une directive include, tu devras probablement, plutôt que de l'extraire comme je l'ai écrit plus haut, directement ouvrir le fichier en question (s'il existe...) et aller y lire le prochain lexème (c'est comme ça qu'on appelle les différents mot ou caractères qui ont un sens différent pour ton assembleur (les identificateurs, les nombres, les opérateurs, etc.)) de telle sorte que pour l'analyseur syntaxique tout ça soit complètement transparent. Comment gérer les equ ? Comment gérer les macros ? Au final, tu vas te retrouver avec tout un tas de symboles définis par le programmeur qui auront des sens différents (des noms de labels, des noms de macros, des equ, etc.). Il serait judicieux de les ranger dans une table, au fur et à mesure où tu les rencontres, et où tu notes toutes les infos que tu as sur eux (par exemple quand tu rencontre le texte
SIZE equ 12, tu dois stocker dans ta table de symboles que l'identificateur
SIZE correspond à un equ et a pour valeur le texte
"12" (ou bien tu le stockes comme un lexème, c'est-à-dire que tu stockes le fait que c'est un nombre qui vaut
12. Ensuite, quand tu rencontreras ce symbole plus tard dans le texte du fichier source, tu regarderas dans ta table et tu verras qu'il s'agit d'un equ de valeur 12.
Voilà ma démarche à moi
