Retrouvez cet article dans : Linux Magazine 97
One bytecode to rule them all
Le langage assembleur
Le langage d’assemblage est le seul langage de programmation lisible par un homme et aussi proche que possible du langage machine. Le code étant exclusivement binaire, il est impossible à un être humain de l’approcher en l’état. Ce sera donc par l’intermédiaire de mnémoniques et de symboles spécifiques qu’il sera rendu abordable. La particularité est que, contrairement à ce qui se passe dans un langage évolué, il existe une correspondance biunivoque entre les lignes du programme source et les instructions de la machine. Un programme spécifique, l’assembleur, transformera le code source en son équivalent binaire. Afin d’en faciliter l’utilisation, il autorise la gestion d’adresses symboliques, la manipulation de modules et la définition de macros. La structure syntaxique du langage d’assemblage est intimement liée à l’architecture du support. Ainsi, contrairement aux langages évolués, il n’en existe pas d’universel multiplateforme et une connaissance approfondie de la topologie de la machine est fondamentale pour le maîtriser et bien en comprendre l’utilisation. De cette constatation est né le principe de la machine virtuelle. Au début des années 1970, Niklaus Wirth de l’École Polytechnique de Zurich et initiateur de Pascal a défini pour son nouveau langage un interpréteur logiciel capable de s’exécuter sur différents systèmes, la P-machine [Pascal]. Cette même idée a été reprise chez Sun dans les années 1990 pour le développement de Java.Genèse de Parrot
La machine virtuelle Parrot
Parrot est une machine virtuelle développée par la communauté des programmeurs Perl. Elle servira, entre autres, de support au futur langage Perl6. Contrairement à la Java machine qui est construite autour d’une structure de pile, Parrot est une machine à base de registres. Cette conception influe particulièrement sur la programmation des expressions arithmétiques en les rendant plus lisibles. Dans une machine à pile, ce sont les éléments supérieurs qui représentent les opérateurs implicites de toute opération. Il est donc nécessaire de convertir une expression arithmétique en notation polonaise post-fixée avant d’effectuer un calcul [Lukasiewicz]. Méthode utilisée dans les années 1970 sur les anciennes calculatrices Hewlett-Packard [HP 35]. Dans ces conditions,Le poisson d’avril
Le premier avril 2001, Simon Cozens annonce sur le site de O’Reilly le livre Programming Parrot [Parrot]. Cet ouvrage présente la programmation Parrot comme étant la référence ultime des nouveaux langages de programmation dynamique. Parrot, un langage qui, in fine, fusionnera les forces vives des jumeaux de l’open source Perl et Python. En unissant la flexibilité de Perl avec la simplicité d’exploitation de Python, Parrot deviendra le premier langage de développement du vingt et unième siècle. C’est l’annonce officielle que tous les utilisateurs de Perl et Python attendaient, le point culminant d’un an de collaboration entre Larry Wall et Guido van Rossum, les développeurs de Perl et de Python. À l’appui, la jaquette du livre qu’ils ont écrit en commun et l’interview exclusive de Larry et Guido qui évoquent cette excitante perspective. Extrait :What about the name of the new language? GvR : Well, that was my idea. We went over lots of possible names: Chimera, Pylon, Perth, before finally coming up with Parrot. We had a few basic ideas: we wanted it to begin with “P”; it had to be something that wouldn’t sound stupid on the end ofC’est ainsi que le poisson d’avril est en fin de compte devenu réalité sous forme de perroquet [Monty Python]/usr/bin/. LW : We also wanted the name of an animal, to represent the combination of the camel and the python. It also helps with the book covers... GvR : Eventually, I came up with Parrot after thinking about Monty Python’s finest hour, the Parrot sketch. LW : It just sounded right – dynamic, colourful, exotic. I love it!
Premiers pas en Parrot
Le livre de référence
Documentation
Il n’existe qu’un livre sur ce sujet. Il est disponible chez O’Reilly et a été écrit en 2003 par Allison Randal, Dan Sugalski et Léopold Tötsch. Il détaille plusieurs aspects du projet, et, bien que ne reflétant pas tout à fait son état de développement actuel, c’est un bon ouvrage pour commencer à aborder la question.
Installation
Le site de référence du projet est <http://www.parrotcode.org/>. On peut y trouver la documentation en ligne et télécharger la dernière version Unix de la machine virtuelle http://svn.perl.org/snapshots/parrot/parrot-latest.tar.gz L’installation par elle-même ne pose aucun problème majeur.
Téléchargez le fichier parrot-latest.tar.gz et décomprimez la distribution dans le répertoire parrot/.
- configurez l’installation :
perl Configure.pl; - lancez la compilation :
make; - testez le résultat :
make test; - installez l’application :
make install.
Une version Windows précompilée est disponible sur le site de Jonathan Worthington [JWS]. Il ne faut jamais oublier que Parrot évoluant continuellement, certaines fonctions peuvent se transformer. Pour se maintenir informé des changements, il est bon de consulter régulièrement le site et la documentation en ligne http://www.parrotcode.org/docs/ Tous les exemples de cet article ont été testés sur un système Mac OS X.
coruscant:~/Langages/asmparrot chris$ parrot -V This is parrot version 0.4.10-devel built for ppc-darwin. Copyright (C) 2001-2007, The Perl Foundation.
Principe de fonctionnement
Le système Parrot est structuré en plusieurs éléments fondamentaux destinés chacun à une tâche bien spécifique.

La machine virtuelle
La structure de la machine virtuelle est extrêmement simple. On ne distingue que quatre types de données, les entiers, les flottants, les chaînes de caractères et les PMC. À chaque type, sera associé un jeu de 32 registres. On disposera donc de :
- 32 registres
IV(entiers) (I0 .. I31) - 32 registres
NV(flottants) (N0 .. N31) - 32 registres
STRING(chaînes de caractères) (S0 .. S31) - 32 registres
PMC(Parrot Magic Cookie) (P0 .. P31)
Si les trois premières appellations ne présentent aucune difficulté pour comprendre à quel type de données elles font référence, leur nom parlant par lui-même, le dernier mérite quelques explications supplémentaires sur lesquelles nous reviendrons ultérieurement. PMC signifie Parrot Magic Cookies.
Les piles
La machine dispose de sept piles distinctes. Chacun des quatre jeux de registres possède sa propre pile qui va permettre de sauvegarder et restaurer aussi rapidement que possible leur contenu. Dans ce cas, les opérations ne portent pas sur un registre particulier, mais sur la famille concernée afin d’empiler ou de dépiler en une seule instruction les 32 registres. L’utilité première de ce mécanisme est de procéder à une sauvegarde très rapide lorsque cette opération s’avère nécessaire, lors des appels de fonction par exemple. Une pile spécifique est dédiée à la sauvegarde et à la restauration des entiers utilisés intensivement par les expressions régulières. Une pile garde la trace de toutes les informations de contrôle des gestionnaires d’exceptions. En fin de compte, on dispose d’une pile banalisée qui va permettre le stockage des données individuelles. Elle sera utilisée pour répondre aux opérations nécessaires à un travail de programmation standard, car elle permet d’empiler ou de dépiler individuellement un registre, quel qu’il soit. Il est cependant important de noter que les informations sont typées, ce qui interdit, par exemple, d’empiler une valeur numérique pour le dépiler ultérieurement dans un registre chaîne.
Les débuts en programmation Parrot
Le premier programme
Pour le réaliser, nous devons disposer d’un éditeur de texte et, selon une tradition désormais bien établie, le premier programme que nous allons écrire nous affichera le classique message de bienvenue " Bonjour. ". Une fois écrit, le source sera stocké dans un fichier dont l’extension doit impérativement être .pasm (Parrot assembly).
Pour procéder à son exécution, il suffit d’ouvrir une fenêtre terminal, de se positionner dans le dossier qui contient le programme à exécuter et de le soumettre à l’interpréteur.
coruscant:~/Langages/asmparrot chris$ cat hello.pasm
print "Bonjour.\n"
end
coruscant:~/Langages/asmparrot chris$ parrot hello.pasm
Bonjour.
coruscant:~/Langages/asmparrot chris$
Ce que nous venons d’écrire est, volontairement, quelque peu provocateur. Cela ne ressemble que de très loin à ce que l’on a l’habitude de voir lorsque l’on pratique l’assembleur. C’est l’avantage de Parrot, mettre à notre disposition un langage qui a toutes les caractéristiques d’un véritable assembleur sans en avoir les inconvénients. Reprenons le même programme mais, cette fois, en utilisant un registre pour mémoriser la chaîne de caractères que nous désirons imprimer.
coruscant:~/Langages/asmparrot chris$ cat hello.pasm
set S1, "Bonjour."
print S1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot hello.pasm
Bonjour.
coruscant:~/Langages/asmparrot chris$
L’instruction Syntaxe de l’assembleur
Ceci nous amène à définir la syntaxe générale de l’assembleur. Elle est simple et se résume en quelques principes. Une instruction tient sur une ligne dont le format est constant.[Etiquette] Code Opération Destinations, Source_1, ..., Source_nSi l’opération retourne un résultat, c’est le toujours premier argument qui représente la destination et, dans certains cas, il peut simultanément être une source et la destination. Les arguments sont indifféremment des registres ou des valeurs explicites, mais seules les sources peuvent être représentées par des constantes. L’étiquette permet d’identifier une ligne de code à laquelle d’autres instructions pourront faire référence (rupture de séquence, branchement à un sous-programme). Les caractères utilisables pour définir une étiquette sont :
- les lettres majuscules et minuscules ;
- les chiffres ;
- le blanc souligné.
La représentation des données
Les constantes numériques
Une constante entière précédée d’un signe (set I1, 42 # Constante entière positive. set I2, -68 # Constante entière négative. set I3, 0x2A # Constante hexadécimale. set I4, 0b1001 # Constante binaire. set I5, -0B1101 # Constante binaire négative.Les constantes flottantes sont, elles aussi, signées, c’est-à-dire qu’elles peuvent être précédées d’un signe (
set N2, 1E6 # Constante en notation scientifique. set N3, -1.5E-2 # Constante en notation scientifique.
Les chaînes de caractère
La syntaxe des chaînes de caractères est identique à celle utilisée dans Perl. Une chaîne de caractères peut être encadrée par des doubles quotes (set S1, "Chaine.\n" # Le mot : Chaine suivi d’un retour chariot. set S2, "\\" # un antislash. set S3, ‘L\’etau’ # La chaine : L’etau set S4, ‘a\n’ # La lettre a, suivie d’un antislash puis d’un n.
Les registres
Référence à un registre
Un registre sera référencé par son type et par son numéro. Le type est toujours une lettre majuscule :Ipour un registre entier ;Npour un registre flottant ;Spour un registre chaîne de caractères ;Ppour un registre PMC.
coruscant:~/Langages/asmparrot chris$ cat regs.pasm
# Stockage des caractères "Bonjour." dans le registre chaîne 10.
set S10, "Bonjour."
# Stockage de la valeur entière 2005 dans le registre entier 17.
set I17, 2005
# Stockage de la valeur réelle 3.14159 dans le registre flottant 20.
set N20, 3.14159
# Impression diverses valeurs précédemment mémorisées.
print S10
print "\n"
print I17
print “\n”
print N20
print “\n”
end
coruscant:~/Langages/asmparrot chris$ parrot regs.pasm
Bonjour.
2005
3.14159
coruscant:~/Langages/asmparrot chris$
Une instruction spécifique coruscant:~/Langages/asmparrot chris$ cat regs.pasm
set I10, 10
set I20, 20
print “Avant exchange \n”
print “Le registre 10 contient : “
print I10
print "\n"
print “Et le registre 20 contient : “
print I20
print "\n"
exchange I10, I20
print "Apres exchange \n"
print “Le registre 10 contient : “
print I10
print "\n"
print “Et le registre 20 contient : “
print I20
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot regs.pasm
Avant exchange
Le registre 10 contient : 10
Et le registre 20 contient : 20
Apres exchange
Le registre 10 contient : 20
Et le registre 20 contient : 10
coruscant:~/Langages/asmparrot chris$
Particularité des registres
Les registresset I0, 33 # Mettre la valeur 33 dans le registre I0 set I1, I0 # Transférer le contenu du registre I0 dans le registre I1.Dans un premier temps, la valeur 33 est stockée dans le registre entier
coruscant:~/Langages/asmparrot chris$ cat ptrs.pasm
set S0, "Chaine initiale\n"
set S1, S0
set S0, "Nouvelle affectation\n"
print “Contenu du registre S0 : “
print S0
print “Contenu du registre S1 : “
print S1
end
coruscant:~/Langages/asmparrot chris$ parrot ptrs.pasm
Contenu du registre S0 : Nouvelle affectation
Contenu du registre S1 : Chaine initiale
coruscant:~/Langages/asmparrot chris$
Nous verrons plus loin que la même opération sur les registres PMC produit un résultat fondamentalement différent.
Manipulation des données
Travail sur les valeurs numériques
Voici un programme simple mettant en évidence quelques-unes des opérations arithmétiques et des fonctions de base disponibles. Cette liste est, bien entendu, non exhaustive. coruscant:~/Langages/asmparrot chris$ cat arith.pasm
set N1, 50
set N2, 3
add N0, N1, N2
print “La somme de “
print N1
print “ et de “
print N2
print “ est egale a :”
print N0
print “\n”
mul N0, N1, N2
print “Le produit de “
print N1
print “ et de “
print N2
print “ est egal a :”
print N0
print “\n”
div N0, N1, N2
print “Le quotient de “
print N1
print “ par “
print N2
print “ est egal a :”
print N0
print “\n”
set N15, 99
inc N15
print “Incrementer “
print N15
print “ donne :”
print N15
print "\n"
set N12, -5.28547
abs N10, N12
print “La valeur absolue de “
print N12
print “ est egale a :”
print N10
print “\n”
set I20, 10
fact I22, I20
print “La factorielle de “
print I20
print “ est egale a :”
print I22
print "\n"
set N27, 3.14159
sin N8, N27
print “Le sinus de “
print N27
print “ est egal a :”
print N8
print “\n”
end
coruscant:~/Langages/asmparrot chris$ parrot arith.pasm
La somme de 50.000000 et de 3.000000 est egale a :53.000000
Le produit de 50.000000 et de 3.000000 est egal a :150.000000
Le quotient de 50.000000 par 3.000000 est egal a :16.666667
Incrementer 100.000000 donne :100.000000
La valeur absolue de -5.285470 est egale a :5.285470
La factorielle de 10 est egale a :3628800
Le sinus de 3.141590 est egal a :0.000003
coruscant:~/Langages/asmparrot chris$
Travail sur les chaînes de caractères
À l’instar de Perl, la machine Parrot propose de nombreux outils pour permettre la manipulation des chaînes de caractère. Dans la majorité des cas, les opérations concernées génèrent de nouvelles chaînes dans le registre destination. Il est toutefois possible, dans certaines conditions, de faire porter la modification sur la source elle-même. Par exemple, l’instruction de concaténation coruscant:~/Langages/asmparrot chris$ cat conc.pasm
set S1, "Bonjour"
set S2, “ la Compagnie.”
concat S0, S1, S2 # Concaténer S1 avec S2, résultat dans S0.
print S0
print "\n"
concat S1, S2 # Concaténer S1 avec S2, résultat dans S1.
print S1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot conc.pasm
Bonjour la Compagnie.
Bonjour la Compagnie.
coruscant:~/Langages/asmparrot chris$
L’instruction substr Sa, Sb, Ic, IdUn registre string (Sb) contient une chaîne de référence. Les valeurs numériques sont stockées dans des registres entiers (
coruscant:~/Langages/asmparrot chris$ cat sst.pasm set S1, "0123456789" set I1, 2 set I2, 5 substr S10, S1, I1, I2 print S10 print "\n" end coruscant:~/Langages/asmparrot chris$ parrot sst.pasm 23456 coruscant:~/Langages/asmparrot chris$Comme dans toutes les instructions Parrot, on peut indifféremment utiliser comme sources des références à des registres ou des valeurs explicites.
substr S10, S1, 3, 5 substr S10, "012345", 3, I3Si l’indice du premier caractère est une valeur négative, le décompte se fera à partir de la fin de la chaîne, le dernier caractère ayant la position -1. L’instruction
coruscant:~/Langages/asmparrot chris$ cat sst1.pasm
set S0, "abcdef"
# Remplacer les deux caractères "cd" par la chaîne ----
substr S1, S0, 2, 2, "----"
print S1
print "\n"
print S0
print "\n"
# supprimer la chaîne "----"
substr S1, S0, 2, 4, ""
print S1
print "\n"
print S0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot sst1.pasm
cd
ab----ef
----
abef
coruscant:~/Langages/asmparrot chris$
La même opération peut aussi être réalisée sans procéder à la capture de la sous-chaîne. Dans ce cas, le registre destination n’apparaît pas.
coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S0, "abcdef"
substr S0, 2, 2, "----"
print S0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
ab----ef
coruscant:~/Langages/asmparrot chris$
L’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S2, "0123456789"
length I1, S2
print “La chaine “
print S2
print “ comporte “
print I1
print “ caracteres.\n”
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
La chaine 0123456789 comporte 10 caracteres.
coruscant:~/Langages/asmparrot chris$
Comme en Perl, il existe une instruction de multiplication de chaîne : son code est coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S0, "x0x-"
set I1, 5
repeat S1, S0, I1
print S1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
x0x-x0x-x0x-x0x-x0x-
coruscant:~/Langages/asmparrot chris$
Suppression de caractères
L’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S0, "abcdef"
chopn S0, 2
print S0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
abcd
coruscant:~/Langages/asmparrot chris$
Si le nombre spécifié dans l’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S0, "abcdef"
chopn S0, -3
print S0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
abc
coruscant:~/Langages/asmparrot chris$
Une variante à trois arguments permet de conserver intacte la chaîne d’origine. Le résultat de l’opération est alors stocké dans un registre explicitement spécifié.
coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S0, "abcdef"
# Retirer les deux derniers caractères.
chopn S1, S0, 2
print S1
print "\n"
# Conserver les trois premiers caractères.
chopn S2, S0, -3
print S2
print "\n"
# La chaîne origine n’a pas été modifiée.
print S0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
abcd
abc
abcdef
coruscant:~/Langages/asmparrot chris$
Indexation d’une chaîne
L’instruction coruscant:~/Langages/asmparrot chris$ cat ind.pasm
set S0, "abcdef"
index I0, S0, "cd"
print I0
print "\n"
index I1, S0, "gh"
print I1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot ind.pasm
2
-1
coruscant:~/Langages/asmparrot chris$
Conversion de caractères
On dispose de deux opérations qui convertissent une valeur numérique en caractère et inversement. L’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
chr S0, 65 # 65 est le code ASCII décimal de "A"
print S0
print "\n"
ord I0, "x" # Le code ASCII de "x" est 120 décimal.
print I0
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
A
120
coruscant:~/Langages/asmparot chris$
Une variante à trois arguments de l’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
ord I0, "ABCDEF", 2 # On convertit le caractère C.
print I0
print "\n"
ord I1, “ABCDEF”, -3 # On convertit le caractère D.
print I1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
67
68
coruscant:~/Langages/asmparrot chris$
Changement de type
Le simple fait de transférer une valeur d’un registre vers un autre effectue le changement de type de celui correspondant au registre d’origine vers celui correspondant au registre de destination. coruscant:~/Langages/asmparrot chris$ cat exo.pasm
set S1, "5" # Caractère.
set S2, 10 # Caractère
set N1, S1 # Transfert vers un registre flottant
set N2, S2 # Transfert vers un registre flottant
mul N1, N2 # Calcul en flottant
print "Calcul en flottant :"
print N1
print "\n"
set I1, N1 # Conversion en entier
print "Conversion en entier :"
print I1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot exo.pasm
Calcul en flottant :50.000000
Conversion en entier :50
coruscant:~/Langages/asmparrot chris$
Les Parrot Magic Cookies
Qu’est ce qu’un PMC ?
Un PMC définit un type qui se comporte de manière particulière. Il va utiliser une structure particulière appelée " v-table " pour référencer des méthodes spécifiques. De plus, des fonctions appropriées permettent de remplacer l’implémentation de la classe de base par une séquence définie par l’utilisateur. Pour simplifier, un registre PMC contient un pointeur vers la v-table qui est elle-même une liste de pointeurs vers des fonctions dont le code réalise l’opération voulue pour le PMC concerné. Ainsi, toute instruction qui fait référence à un PMC, utilise la v-table qui lui a été associée pour accéder à la fonction appropriée. Essentiellement, les PMC héritent d’une classe de base et exécutent les opérations demandées en accord avec les caractéristiques spécifiques inhérentes aux structures concernées. Nous détaillerons tout ceci lorsque nous aborderons la programmation objet. Par exemple, pour deux langages distincts, une fonction équivalente peut occasionner deux comportements fondamentalement différents. Pour illustrer ceci, considérons deux programmes équivalents, le premier écrit en Perl, le second en Python et comparons les résultats obtenus. coruscant:~/Langages/perl chris$ cat ch.pl
#!/usr/bin/perl
$x = "ABCDEF";
$z = ++$x;
print "$z\n";
coruscant:~/Langages/perl chris$ ch.pl
ABCDEG
coruscant:~/Langages/python chris$ cat ch.py
#!/usr/bin/python
x = "ABCDEF"
z = ++x
print z, "\n"
coruscant:~/Langages/python chris$ ch.py
Traceback (most recent call last):
File "ess.py", line 4, in ?
z = ++x;
TypeError: bad operand type for unary +
coruscant:~/Langages/python chris$
C’est pour tenir compte de cette singularité, que l’assembleur disposera à terme de deux PMC Quels sont les PMC disponibles ?
Le nombre de PMC installés peut varier d’une version à l’autre. En connaître la liste peut se révéler utile. Voici un petit programme qui permet de la générer. Dans la version utilisée pour les tests, son exécution, dans la version actuelle, génère 81 lignes, correspondant aux 81 PMC existants. C’est pourquoi j’en ai volontairement tronqué les résultats. coruscant:~/Langages/asmparrot chris$ cat listePMC.pasm
set I0, 1
BOUCLE:
# Test si le numéro correspond à un type de PMC valide.
valid_type I1, I0
eq I1, 0, FIN
# Récupération du nom du PMC correspondant au numéro.
typeof S0, I0
# Impression des résultats.
set S1, I0
concat S1, " ", S1
substr S2, S1, -2
print "Nom du PMC numero "
print S2
print " : "
print S0
print "\n"
inc I0
branch BOUCLE
FIN:
end
coruscant:~/Langages/asmparrot chris$ parrot listePMC.pasm
Nom du PMC numero 1 : Null
Nom du PMC numero 2 : Env
Nom du PMC numero 3 : Key
Nom du PMC numero 4 : Random
* * *
* * *
Nom du PMC numero 66 : ParrotRunningThread
Nom du PMC numero 67 : PCCMETHOD_Test
Nom du PMC numero 68 : ResizableBooleanArray
Nom du PMC numero 69 : ResizableFloatArray
Nom du PMC numero 70 : ResizableIntegerArray
Nom du PMC numero 71 : ResizablePMCArray
Nom du PMC numero 72 : ResizableStringArray
* * *
Nom du PMC numero 79 : STMVar
Nom du PMC numero 80 : Super
Nom du PMC numero 81 : Undef
coruscant:~/Langages/asmparrot chris$
Manipulation des registres PMC
Il a été précisé que les registres PMC stockent un pointeur. C’est ainsi que le code opération coruscant:~/Langages/asmparrot chris$ cat ptrs.pasm
new P1, .String
set P1, "Chaine un\n"
set P2, P1
set P2, “Chaine deux\n”
print “Le PMC P1 pointe sur la chaine : “
print P1
print “Le PMC P2 pointe sur la chaine : “
print P2
end
coruscant:~/Langages/asmparrot chris$ parrot ptrs.pasm
Le PMC P1 pointe sur la chaine : Chaine deux
Le PMC P2 pointe sur la chaine : Chaine deux
coruscant:~/Langages/asmparrot chris$
Après la création de l’instance coruscant:~/Langages/asmparrot chris$ cat ptrs.pasm
new P1, .String
set P1, "Chaine un\n"
clone P2, P1
set P2, “Chaine deux\n”
print “Le PMC P1 pointe sur la chaine : “
print P1
print “Le PMC P2 pointe sur la chaine : “
print P2
end
coruscant:~/Langages/asmparrot chris$ parrot ptrs.pasm
Le PMC P1 pointe sur la chaine : Chaine un
Le PMC P2 pointe sur la chaine : Chaine deux
coruscant:~/Langages/asmparrot chris$
Les entrées sorties
Lecture d’information
La lecture d’information à partir du clavier se fait sous la forme d’une chaîne de caractères. On dispose de deux instructions différentes pour effectuer cette opération. La première ne fait pas appel à un PMC :read S1, I1Elle effectue la lecture d’une chaîne de caractères dans le registre
coruscant:~/Langages/asmparrot chris$ cat lec.pasm
getstdin P0
set I1, 5
read S1, I1
print S1
print "\n"
end
coruscant:~/Langages/asmparrot chris$ parrot lec.pasm
12
12
coruscant:~/Langages/asmparrot chris$ parrot lec.pasm
123456789
12345
coruscant:~/Langages/asmparrot chris$
Il existe une autre possibilité pour accéder à une information. C’est l’instruction coruscant:~/Langages/asmparrot chris$ cat exo.pasm
getstdin P0
readline S1, P0
print “Chaine lue : “
print S1
end
coruscant:~/Langages/asmparot chris$ parrot exo.pasm
Bonjour
Chaine lue : Bonjour
coruscant:~/Langages/asmparot chris$
Sortie d’information
L’instruction coruscant:~/Langages/asmparot chris$ cat exo.pasm
getstdin P0
getstdout P1
readline S1, P0
print P1, “Chaine lue : “
print P1, S1
end
coruscant:~/Langages/asmparot chris$ parrot exo.pasm
Bonjour
Chaine lue : Bonjour
coruscant:~/Langages/asmparot chris$
L’utilisation de PMC pour effectuer les entrées sorties se justifie pleinement lorsqu’on désire pouvoir changer facilement de gestionnaire d’entrée. Cette possibilité sera, elle aussi, développée dans la partie consacrée aux fichiers.
Conclusion
Cette approche du langage machine peut sembler quelque peu surprenante à ceux qui utilisent de manière courante un assembleur. Elle a toutefois un grand mérite, celui de permettre l’écriture facile et rapide de programmes qui auraient demandé beaucoup de conception et de travail sur un support réel. La caractéristique principale est de mettre à la disposition des utilisateurs un jeu d’instruction extrêmement varié et particulièrement développé. Cet aspect du problème a été mis en évidence dans cette première présentation. Par la suite, nous en détaillerons d’autres caractéristiques et nous verrons comment gérer sans difficulté des structures plus complexes. Références- [Pascal] http://www.infeig.unige.ch/support/cpil/lect/mvp/
- [Lukasiewicz] Jan Lukasiewicz http://www-groups.mcs.st-and.ac.uk/history/Biographies/Lukasiewicz.html
- [HP 35] Calculatrices Reverse Polish Notation pour Linux http://www.linuxfocus.org/Francais/January2004/article319.shtml
- [Parrot] Programming Parrot http://www.perl.com/pub/a/2001/04/01/parrot.htm
- [Monty Python] The Parrot Sketch http://video.google.com/videoplay?docid=5775099474392087542
- [JWS] http://www.jwcs.net/~jonathan/perl6/parrot-win32.zip





Donnez votre avis
Vous devez avoir ouvert une session pour écrire un commentaire.