Création d'un guide de style de code

illustrations illustrations illustrations illustrations illustrations illustrations illustrations
post-thumb

Publié le 20 octobre 2022 par Andrew Owen (6 minutes)

J’ai déjà écrit sur l’importance d’un guide de style pour le contenu écrit. Il en va de même pour le code. On peut même dire que c’est encore plus important parce que le code est beaucoup plus difficile à comprendre. En ce qui concerne le style du code, vous ne trouverez jamais deux développeurs qui soient d’accord sur tout. Mon conseil serait donc de demander l’avis de tous ceux qui touchent au code et de parvenir à un consensus sur le style à adopter. N’oubliez pas qu’il s’agit d’un guide et non d’un ensemble de règles rigides.

Comme j’ai passé près de 15 ans à travailler comme rédacteur technique, la plupart des codages que j’ai effectués dans ma vie l’ont été pour mon propre amusement. Cela signifie que j’ai été libre de faire ce que je voulais. Mais pendant cette période, j’ai pris quelques mauvaises habitudes que j’ai essayé d’éviter. En particulier, j’ai eu affaire à beaucoup de code source en langage d’assemblage Z80. La plupart d’entre eux sont horribles. Mes griefs sont les suivants:

  • Fichiers d’assemblage uniques et monolithiques.
  • Ecrit en CAPITALES.
  • Décoration inutile des commentaires.
  • Trop peu de commentaires.
  • Étiquettes sans signification
  • Plein de nombres magiques
  • Lacunes inutiles entre les instructions et les paramètres
  • Assez d’espaces blancs pour remplir l’Albert Hall
  • Pas de documentation sur l’API.
  • Nombres écrits en hexadécimal alors qu’ils devraient l’être en décimal.
  • Instructions bitwise écrites en hexadécimal alors qu’elles devraient être écrites en binaire.
  • Codes pseudo-op non documentés.

Mon propre style de code est essentiellement une réaction contre cela. J’ai également été influencé par un document publié par Nikos Drakos et Ken Clowes à la Computer Based Learning Unit de l’Université de Leeds, et par le fait que j’ai eu l’habitude d’écrire de la documentation SDK pour les développeurs C++. Je vais maintenant tenter de le documenter formellement. À l’avenir, je devrais l’étendre. En cas d’information manquante, je m’en remets à l’avis de l’auteur de l’article C++ Core Guidelines.

Introduction

Ce document décrit les normes de codage pour les programmes en langage d’assemblage Z80. Les plug-ins suivants sont recommandés pour Visual Studio Code:

Si vous utilisez quelque chose de plus moderne que le Z80, je vous recommande également ces plug-ins:

API

Les appels à l’API doivent utiliser une table de vecteurs afin que la relocalisation du code cible ne perturbe pas les applications existantes. Par exemple, les appels d’API doivent utiliser une table de vecteurs:

org $04c4;

    ;;
    ; open a file for appending if it exists
    ; @param IX - pointer to ASCIIZ file path
    ; @throws sets carry flag on error
    ;;
    SEFileAppend:
    	jp v_open_w_append;					// $00

Personnages

Lorsque vous comparez des caractères ASCII, utilisez le caractère et non le point de code. Par exemple:

    	cp '(';								// opening parenthesis?

Comments

En Z80, le point-virgule ( ; ) indique qu’un commentaire suit. Cependant, il est le plus souvent utilisé comme terminaison de ligne. Les environnements de développement intégrés modernes sont conçus pour cela. Par conséquent, chaque ligne doit se terminer par un point-virgule. Les commentaires doivent être précédés d’une double barre oblique ( // ) pour plus de visibilité. Les commentaires autonomes doivent être écrits comme suit:

    ; // this is a standalone comment

Les commentaires en ligne doivent commencer au dixième taquet de tabulation (colonne 40), par exemple:

    	di;									// interrupts off

Les commentaires doivent être aussi courts que possible pour indiquer ce que fait le code. Lorsqu’une instruction ne peut avoir qu’une seule signification, il n’est pas nécessaire de commenter le code.

Utilisez des majuscules pour les noms de registres dans les commentaires. Par exemple:

    	ld d, e;							// E to D

Données

Dans la mesure du possible, les données doivent être stockées séparément du code.

En-têtes

Utiliser un fichier de définitions pour déclarer:

  • des constantes
  • les macros
  • les décalages des registres d’index

Registres d’index

Si vous utilisez une large gamme de registres d’index, par exemple comme un ensemble de variables, définissez le décalage avec le nom de la variable et un trait de soulignement. Par exemple: _kstate.

Longueur de la ligne

Les lignes ne doivent pas comporter plus de 80 caractères pour être affichées sur un terminal standard. Les commentaires en ligne doivent se situer au point 40 caractères afin d’apparaître sur la ligne suivante sur un écran de 40 colonnes.

Macros

Utilisez les macros avec parcimonie. Les différents assembleurs utilisent des syntaxes différentes et leur conversion peut prendre beaucoup de temps. Elles fonctionnent mieux pour les codes pseudo op.

Chiffres

Définir des noms significatifs pour les constantes et les variables. Éviter les nombres magiques.

Utilisez la décimale dans la mesure du possible.

Utilisez toujours le langage binaire pour les opérations par bit (AND, OR, XOR). Par exemple, et %00001111.

Écrivez l’hexadécimal avec des lettres minuscules et le signe du dollar en tête. Par exemple, $801c.

Pseudo-codes

N’utilisez jamais de pseudo-codes op. La prise en charge n’est pas uniforme d’un assembleur à l’autre. Si vous devez le faire, définissez un code pseudo-op comme une macro.

Documentation publique

Utilisez le script Perl asmdoc pour générer des documents d’API pour les routines publiques.

    ;;
    ; Short description.
    ; @author Name of contributing author.
    ; @deprecated Version deprecated in and replacement module.
    ; @param HL - Register contents.
    ; @return Result in register, such as <code>HL</code>.
    ; @see <a href="www.example.com">External reference</a>.
    ; @since Version in which module was introduced.
    ; @throws Error number and description handled by RST 8 routine.
    ; @version Version in which the module was last udpated. 
    ;;

Routines

Une routine est quelque peu analogue à une fonction en C. Une routine publique est précédée d’une définition asmdoc. Les noms des routines et des sous-programmes sont terminés par deux points. Les instructions de la routine ou du sous-programme sont indentées d’une tabulation. Par exemple, les instructions de la routine ou du sous-programme sont indentées d’une tabulation:

     joystick:
    	in a, (stick);						// read joystick
    	ld (jstate), a;						// store in system variable
    	ret;								// end of subroutine

Code d’auto-modification

Le code auto-modifiant doit être évité à deux exceptions près:

  • Lorsque cela est essentiel pour la rapidité d’exécution.
  • Lorsqu’il est essentiel pour la compacité du code.

Source

Divisez le code source en ensembles de modules apparentés et incluez ces modules dans le fichier d’assemblage principal. Les modules doivent commencer par un commentaire spécial. Par exemple:

    ;;
    ;	// --- ARITHMETIC ROUTINES -------------------------------------------------
    ;;
   :

Cordes

Utiliser les minuscules dans la mesure du possible. Utiliser la camelCase de préférence aux caractères de soulignement ( _ ). Réserver les MAJUSCULES aux substitutions dans les commentaires. Par exemple:

    	xor a;								// LD A, 0

Espace blanc

Utilise des tabulations (une tabulation correspond à quatre caractères). Cela permet d’accélérer les temps de recherche et de compilation.

Image: Détail de Rodnay Zaks’ “Programming the Z80” (Sybex)