109Fermer111
BrunniLe 09/10/2009 à 21:56
Folco (./17) :
C'est surpuissant cette approche Sasume, ça permet de parser n'importe quoi avec le même code, pour peu que tu redéfinisse une nouvelle grammaire, je me trompe ?

Et puis, même question que squalyl, en plus "polissé", ai-je besoin de passer par cette étape nécessairement ? Ne puis-je pas faire quelque chose de plus intuitif ?
L'assembleur est simplissime en soi, sur une ligne, on a :

LABEL | DIRECTIVE | COMMENT[...]

En fait tu peux le faire autrement, c'est juste super joli de coder un assembleur avec la méthode à Sasume, et ça t'évite un max d'erreurs.
En plus avec ce principe ça devient plus aisé de supporter les macros, includes et autres directives. Genre un move peut s'écrire comme ça si tu as les fonctions qui vont bien:
Jeton *j = lit(IDENTIFICATEUR);     // Génère une erreur "identificateur attendu" s'il y a autre chose
if (j) {
    if (!strcmp(j->texte, "move")) {
        instr_move();
    }
    else
        erreur("instruction inconnue");
}

void instr_move() {
    Jeton *j;
    int largeur, valeur;
    enum {IMMEDIAT, REGISTRE} mode[2];

    lit(POINT);     // Je crois que c'est obligatoire, erreur sinon
    j = lit(IDENTIFICATEUR);
    if (!strcmp(j->texte, "b"))
        largeur = 1;
    else if (!strcmp(j->texte, "w"))
        largeur = 2;
    else if (!strcmp(j->texte, "l"))
        largeur = 4;
    else
        erreur("largeur: b, w ou l attendu");

    if (prochain(DIESE)) {    // mov #imm, ...
        lit(DIESE);
        valeur = litEntier();    // genre atoi(lit(NOMBRE)->texte) avec support de l'hexa et autres
        mode[0] = IMMEDIAT;
    }
    else if (prochain(IDENTIFICATEUR)) {    // mov reg, ...
        ...
    }
    ...
}

A noter que pour bien faire (je te préviens pour gérer les sauts et tout ça ne va pas être facile, d'où l'intérêt d'utiliser des structures faciles à maîtriser pour toi plutôt que du bidouillage) tu fais bien de générer des instructions intermédiaires, qui peuvent être liées entre elle (si elles utilisent un label en fait). Ensuite tu produis du code en fonction de ces instructions intermédiaires, et tu peux gérer des liens sans trop de peine. Le truc c'est que tu vas sûrement être amené à regénérer plusieurs fois du code, car les instructions n'ont pas une taille fixe, et tu ne sais donc pas à l'avance quelle sera l'adresse d'un label déclaré plus tard.
Je te mets un lien vers ma console virtuelle pour laquelle j'ai justement implémenté un assembleur comme ça:
http://www.playeradvance.org/forum/showthread.php?t=32838