Il s'agit de la commande prima-tmlink qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS
PROGRAMME:
Nom
gencls - compilateur d'interface de classe pour les modules de base Prima
SYNOPSIS
gencls --h --inc --tml -O -I --depend --sayparent nom_fichier.cls
DESCRIPTION
Crée des en-têtes avec des macros et des structures C pour les définitions d'objets du module de base Prima.
ARGUMENTS
gencls accepte les arguments suivants :
--h Génère un fichier .h (avec des déclarations à inclure dans un ou plusieurs fichiers)
--inc
Génère un fichier .inc (avec des déclarations à inclure dans un seul fichier)
-O Active l'algorithme d'optimisation pour les fichiers .inc. L'algorithme est basé sur une hypothèse,
que certaines fonctions sont déclarées à l'identique, donc le morceau de code qui gère
le paramètre et la conversion des résultats peuvent être partagés. Avec le drapeau "-O" activé, un corps de thunk est
remplacé par un appel à une fonction, dont le nom est composé de tous les paramètres de la méthode
plus le résultat. La fonction réelle n'est pas écrite dans le fichier .inc, mais dans le fichier .tml. Tous
les déclarations en double d'un ensemble de fichiers .tml peuvent être supprimées et le rappel
écrit dans un fichier par l'utilitaire tmlink.
--tml
Génère un fichier .tml. Active "-O" automatiquement.
-Idirname
Ajoute un répertoire à un chemin de recherche, où l'utilitaire recherche les fichiers .cls. Peut être
précisé plusieurs fois.
--dépendre
Imprime les dépendances pour un fichier donné.
--sayparent
Affiche le parent immédiat d'une classe dans un fichier donné.
SYNTAXE
En bref, la syntaxe d'un fichier .cls peut être décrite par le schéma suivant :
[ zéro ou plusieurs déclarations de type ]
[ zéro ou une déclaration de classe ]
Gencls produit des fichiers .h, .inc ou .tml, avec un nom de base du fichier .cls, si aucun objet ou
nom du package donné, ou avec un nom de l'objet ou du package dans le cas contraire.
Basic scalaire données types
Gencls a plusieurs types de données scalaires intégrés, qu'il sait gérer. Négocier'
signifie qu'il peut générer un code qui transfère des données de ces types entre C et perl,
en utilisant l'interface de la bibliothèque XS (voir perlguts).
Les genres sont :
int
Bool
Poignée
double
VS*
HT*
char *
chaîne ( la déclaration C est char[256] )
Il existe également des types intégrés dérivés, qui sont
Long
court
carboniser
Couleur
U8
qui sont mappés sur int. Les données ne subissent aucune conversion en int dans le processus de transfert, mais il
est stocké à la place dans le scalaire perl en utilisant nouveauSViv() fonction, qui, à son tour, peut perdre des bits
ou un signe.
Dérivé données types
La syntaxe d'une nouvelle définition de types de données est la suivante :
Une portée peut être l'un des deux pragmas, "global" ou "local". Ils suggèrent l'utilisation d'une nouvelle donnée
type, si le type sera utilisé uniquement pour un ou plusieurs objets. L'utilisation de "local" est
ressemble quelque peu à C pragma statique. Actuellement, la seule différence est qu'une fonction
en utilisant un type local complexe dans la liste des paramètres ou comme le résultat n'est pas un sujet pour
Optimisation "-O".
Scalaire types
Les nouveaux types scalaires ne peuvent être alias que ceux existants, principalement pour le codage C
commodité. Un type scalaire peut être défini de deux manières :
Crénelage direct
syntaxe:
$id => ;
Mise en situation :
global $Handle => int;
Le nouvel identifiant de type ne sera pas visible dans les fichiers C, mais le type sera remplacé par
tous les fichiers .cls qui incluent cette définition.
macro C
syntaxe:
id1 id2
Mise en situation :
API_HANDLE UV globale
Un tel code crée une définition de macro C dans le fichier d'en-tête .h sous la forme
#définir id1 id2
Les macros C avec des paramètres ne sont pas autorisées. id1 et id2 ne doivent pas obligatoirement être présents
dans l'espace de nom .cls, et aucune substitution n'est effectuée pendant le traitement du fichier .cls. Cette
l'utilisation du pragma est très limitée.
Complexe types
Les types de données complexes peuvent être des tableaux, des structures et des hachages. Ils peuvent être une combinaison ou un
vecteur de types de données scalaires (mais pas complexes).
Gencls permet plusieurs combinaisons de types de données complexes que le langage C ne permet pas
reconnaître. Ceux-ci seront décrits ci-dessous.
Les types de données complexes ne sont pas importés dans le code perl. Un programmeur perl doit se conformer à
le type de données utilisé lors de la transmission de paramètres à une fonction.
Arrays
syntaxe:
@identifiant [dimension];
Mise en situation :
global @FillPattern U8[8] ;
Exemple de fonctions utilisant des tableaux :
Tableau * func( Tableau a1, Tableau * a2) ;
Code Perl :
@ret = func( @array1, @array2);
Notez que les références de tableau ne sont pas utilisées et le nombre d'éléments dans tous les tableaux
les paramètres doivent être exactement comme les dimensions des tableaux.
Remarque : la déclaration suivante ne sera pas compilée avec le compilateur C, car C ne peut pas retourner
tableaux. Cependant, il n'est pas traité comme une erreur par gencls :
Tableau func();
Structures
syntaxe:
@identifiant {
;
;
};
Mise en situation :
globale @Struc {
nombre entier ;
identifiant de chaîne ;
}
Exemple de fonctions utilisant des structs :
Struc * func1( Struc a1, Struc * a2) ;
Struc func2( Struc a1, Struc * a2) ;
Code Perl :
@ret = func1( @struc1, @struc2);
@ret = func2( @struc1, @struc2);
Notez que les références de tableau ne sont pas utilisées, et le nombre et l'ordre des éléments dans tous
les paramètres du tableau doivent être définis exactement comme les dimensions et l'ordre des structures. Structurer
les noms de champs ne sont pas non plus utilisés dans le code perl.
Des hachis
syntaxe:
%identifiant {
;
;
};
Mise en situation :
hachage % global {
nombre entier ;
identifiant de chaîne ;
}
Exemple de fonctions utilisant des hachages :
Hash * func1( Hash a1, Hash * a2) ;
Hash func2( Hash a1, Hash * a2) ;
Code Perl :
%ret = %{func1( \%hash1, \%hash2)} ;
%ret = %{func2( \%hash1, \%hash2)} ;
Notez que seules les références de hachage sont utilisées et renvoyées. Quand un hachage est passé de perl
code, il se peut que certains ou tous les champs ne soient pas définis. La structure C est remplie et transmise à un
fonction C, et les champs qui ont été désactivés sont affectés à un correspondant
Valeur C_TYPE_UNDEF, où TYPE est l'un des littéraux NUMERIC, STRING et POINTER.
La conversion arrière ne compte pas sur ces valeurs et renvoie toujours toutes les clés de hachage avec un
paire correspondante.
Espace de noms
syntaxe:
{
}
Un fichier .cls peut avoir zéro ou une section d'espace de noms, remplie de descriptions de fonctions.
Les fonctions décrites ici seront exportées vers l'ID donné lors du code d'initialisation. UNE
l'espace de noms peut être soit "object" soit "package".
La syntaxe de l'espace de noms du package n'autorise que la déclaration de fonctions à l'intérieur d'un "package"
bloque.
emballer {
}
La syntaxe de l'espace de noms d'objet comprend des variables et des propriétés ainsi que des fonctions (
méthodes appelées dans la syntaxe de l'objet). La syntaxe générale de l'espace de noms d'objet est
objet [(ID de classe parent)] {
}
Dans un espace de nom d'objet, la syntaxe d'héritage peut être utilisée :
objet ( ) { ... }
ou une description d'objet racine nue ( sans ancêtre )
objet { ... }
pour la déclaration de classe d'objets.
Les fonctions
syntaxe:
[ ] ( ) [ => ] ;
Exemples :
int package_func1( int a, int b = 1) => c_func_2;
Point package_func2( Struc * x, ...);
méthode void object_func3( HV * profile);
Un préfixe est utilisé uniquement avec les fonctions d'objet (méthodes). En savoir plus sur le préfixe dans Méthodes
.
Une fonction ne peut rien renvoyer ( void ), un scalaire ( int, string, etc ) ou un complexe (
tableau, hachage ). Il peut aussi bien accepter des paramètres scalaires et complexes, de type
conversion qui correspond aux règles décrites ci-dessus dans "Types de données scalaires de base"
.
Si une fonction a des paramètres et/ou un résultat d'un type qui ne peut pas être converti
automatiquement entre C et perl, il est déclaré mais n'est pas exposé à l'espace de noms perl. Les
l'avertissement correspondant est émis. Il n'est pas possible d'utiliser la syntaxe gencls pour déclarer un
fonction avec des paramètres personnalisés ou des données de résultat. À cette fin, le C explicite
la déclaration de code avec l'appel "newXS" doit être faite.
Exemple : les points de suspension (...) ne peuvent pas être convertis par gencls, mais c'est un C légal
construction.
Point package_func2( Struc * x, ...);
La syntaxe de la fonction a plusieurs ajouts pratiques :
Valeurs des paramètres par défaut
Mise en situation :
void func(int a = 15);
Une fonction déclarée de cette manière peut être appelée à la fois avec 0 ou 1 paramètres. Si c'est
appelé avec 0 paramètres, une valeur entière de 15 sera automatiquement utilisée. Les
la syntaxe autorise les paramètres par défaut pour les types int, pointeur et chaîne et leur scalaire
alias.
Les paramètres par défaut peuvent être aussi nombreux que possible, mais ils doivent être à la fin du
liste des paramètres de fonction. La déclaration "func( int a = 1, int b)" est incorrecte.
Aliasing
Dans le code C généré, une fonction C doit être appelée après que les paramètres ont été
analysé. Gencls s'attend à ce qu'une fonction conforme soit présente dans le code C, avec un nom fixe
et la liste des paramètres. Cependant, si la tâche d'une telle fonction est un wrapper à un
fonction publiée sous un autre nom, l'aliasing peut être préformé pour enregistrer à la fois le code et
la vitesse.
Mise en situation :
forfait forfait {
void func( int x) => interne;
}
Une fonction déclarée de cette manière n'appellera pas Package_func() fonction C, mais
interne() fonction à la place. La seule demande est que interne() la fonction doit avoir
paramètre et déclaration de résultat identiques à un fonction().
Hachage en ligne
Un moyen pratique d'appeler une fonction avec un hachage comme paramètre à partir de perl a été conçu. Si un
la fonction est déclarée avec le dernier paramètre ou tapez "HV*", puis la traduction du paramètre
de perl à C est exécuté comme si tous les paramètres passés étaient un hachage. Ce hachage est
passé à une fonction C et son contenu est renvoyé puis renvoyé à perl sous forme de hachage.
Le contenu du hachage peut être modifié à l'intérieur de la fonction C.
Cette déclaration est largement utilisée dans les constructeurs, dont le code perl est typique
sous-initialisation
{
mon %ret = shift-> SUPER::init( @_);
renvoie %ret ;
}
et le code C est généralement
void Obj_init ( HV * profil) {
hérité init( profil);
... [ modifier le contenu du profil ] ...
}
Méthodologie
Les méthodes sont des fonctions appelées dans le contexte d'un objet. Pratiquement toutes les méthodes doivent
avoir accès à un objet avec lequel ils traitent. Les objets Prima sont visibles en C comme
Gérer le type de données. Un tel Handle est en fait un pointeur vers une instance d'objet, qui à son tour
contient un pointeur vers la table des méthodes virtuelles de l'objet ( VMT ). Pour faciliter un OO-like
syntaxe, ce paramètre Handle n'est presque jamais mentionné dans toutes les méthodes d'un objet
description dans un fichier cls, bien qu'étant implicitement compté, donc chaque méthode cls
déclaration
méthode void a( int x)
pour une classe d'objets L'objet est reflété dans C comme
void Object_a (Gérer soi, int x)
déclaration de fonction. Contrairement aux fonctions de package, ce gencls est incapable de publier si
il est incapable de gérer les paramètres non pris en charge sur unconvertible, il existe un moyen de
émettre une telle déclaration avec une méthode. L'utilisation principale pour cela est le nom de la méthode obtient
réservé dans le VMT de l'objet.
Les méthodes sont accessibles en code C par le déréférencement direct du nom d'un "Handle self" en tant que
structure correspondante :
((( PSampleObject) self)-> self)-> sample_method( self, ...);
Une méthode peut avoir l'un des six préfixes qui régissent la génération de code C :
méthode
C'est le premier type de méthode et le plus basique. C'est le nom du préfixe, "méthode" est
a donc été choisi comme le nom le plus descriptif. Les méthodes doivent être codées dans
C, le descripteur d'objet est implicite et n'est pas inclus dans une description .cls.
méthode void a()
résultats en
void Object_a( Gérer soi-même)
Déclaration C. Une méthode publiée convertit automatiquement ses paramètres et un résultat
entre C et perl.
public
Lorsque les méthodes qui ont des paramètres et/ou des résultats qui ne peuvent pas être automatiquement
converti entre C et perl doivent être déclarés, ou la déclaration de fonction ne
s'adapter à la syntaxe C, un préfixe "public" est utilisé. Les méthodes déclarées avec "public" sont
devrait communiquer avec perl au moyen de l'interface XS ( voir perlxs ). C'est aussi
s'attend à ce qu'une méthode "publique" crée à la fois des fonctions REDÉFINIE et FROMPERL ( voir
Prima::internals pour plus de détails). Les exemples sont nombreux dans Prima source, et
pas être montré ici. les méthodes "publiques" ont généralement un résultat vide et aucun paramètre, mais
cela n'a pas beaucoup d'importance, puisque gencls ne produit aucune conversion pour de telles méthodes.
importer
Pour les méthodes qui ne sont pas raisonnables à coder en C mais en perl à la place, gencls peut être
dit de produire les wrappers correspondants en utilisant le préfixe "import". Ce genre de
méthode peut être considérée comme une "méthode" à l'envers. La fonction "import" n'a pas besoin de C
contrepartie, à l'exception du code généré automatiquement.
statique
Si une méthode doit pouvoir fonctionner à la fois avec et sans instance d'objet, elle a besoin
à faire précéder du préfixe "statique". Les méthodes "statiques" sont toutes semblables aux "méthodes",
sauf que le premier paramètre "Handle self" n'est pas déclaré implicitement. Si un "statique"
méthode est appelée sans objet ( mais avec une classe ), comme
Class::Object-> static_method();
son premier paramètre n'est pas un objet mais une chaîne "Class::Object". Si une méthode jamais
traite d'un objet, il suffit d'utiliser sa déclaration comme
static a( char * className = "");
mais si c'est le cas, un
statique a( SV * class_or_object = nil);
une déclaration est nécessaire. Dans ce dernier cas, le code C lui-même doit déterminer ce qui a exactement
été adopté, si jamais. Notez le paramètre par défaut ici : une méthode « statique » est généralement
lisible pour appeler comme
Classe::Object::static_method();
où aucun paramètre ne lui est transmis. Sans le paramètre par défaut, un tel appel
génère une erreur d'exécution « paramètres insuffisants passés ».
bizarre
Nous ne pouvions pas trouver un meilleur nom pour cela. Le préfixe "bizarre" désigne une méthode qui combine
propriétés à la fois de "static" et "public". En d'autres termes, gencls ne génère aucun
code de conversion et n'attend pas de "Handle self" comme premier paramètre pour une telle méthode.
À titre d'exemple, Prima::Image::load peut être représenté, qui peut être appelé à l'aide d'un large
spectre de sémantique d'appel (voir Prima::image-load pour plus de détails).
c_seulement
Comme son nom l'indique, "c_only" est une méthode qui est présente sur un VMT mais n'est pas
accessible depuis perl. Il ne peut être surchargé qu'à partir de C. De plus, il est permis de
enregistrer une fonction perl avec le nom d'une méthode "c_only", et toujours ces entités
seront totalement indépendants les uns des autres - la surcharge n'aura pas lieu.
NB : méthodes qui ont des types de données résultat et/ou paramètres qui ne peuvent pas être convertis
automatiquement, changez leur préfixe en "c_only". C'est probablement le mauvais comportement,
et une telle condition doit signaler une erreur.
Propriétés
La boîte à outils Prima introduit une entité nommée propriété, qui devrait remplacer la méthode
paires dont la fonction est d'acquérir et d'affecter une variable objet interne, par exemple,
un nom d'objet, une couleur, etc. Au lieu d'avoir une paire de méthodes comme Object::set_color et
Object::get_color, une propriété Object::color est conçue. Une propriété est une méthode avec le
considérations spéciales, en particulier, lorsqu'il est appelé sans paramètres, un mode 'get'
est implicite. Au contraire, s'il est appelé avec un paramètre, un mode 'set' est déclenché.
Notez que sur les invocations 'set' et 'get', le premier paramètre implicite "Handle self" est
toujours présente.
Les propriétés peuvent fonctionner avec un nombre différent mais fixe de paramètres et effectuer un « ensemble »
et 'get' ne fonctionnent que pour un. Par défaut, le seul paramètre est le "Handle" implicite
soi":
propriété char * nom
a un homologue C
char * Object_name ( Handle self, Bool set, char * name)
Selon le mode, "Bool set" est soit "true" soit "false". En mode 'set' un code C
le résultat est ignoré, en mode 'get' la valeur du paramètre est indéfinie.
La syntaxe de la propriété multi-paramètres est
propriété long pixel( int x, int y);
et code C
long Object_pixel( Handle self, Bool set, int x, int y, pixel long)
Notez que dans le cas multi-paramètres, les paramètres déclarés après le nom de la propriété sont
toujours initialisé, dans les deux modes 'set' et 'get'.
Instance les variables
Chaque objet est caractérisé par son état interne unique. La syntaxe Gencls permet un
déclaration de variable, pour les variables qui sont allouées pour chaque instance d'objet. Même si
la validation du type de données n'est pas effectuée pour les variables et leurs déclarations sont simplement
copiés "en l'état", les déclarations C complexes impliquant des pointeurs de tableau, de structure et de fonction sont
pas reconnu. Pour contourner ce problème, des pointeurs vers des entités typedef sont utilisés. Exemple:
objet SampleObject {
int x;
Liste de liste ;
struct { int x } s; # déclaration illégale
}
Les variables sont accessibles en code C par déréférencement direct du nom d'un "Handle self" en tant que
structure correspondante :
((PSampleObject) self)-> x;
AUTEURS
Dmitri Karasik,[email protected]>. Anton Berezin,[email protected]>.
Utilisez prima-tmlink en ligne en utilisant les services onworks.net