# Introduction

Ce didacticiel est destiné aux utilisateurs maîtrisant la programmation en C ou C++, ainsi que l'architecture de la Simple Virtual Machine.

Dans ce didacticiel, vous allez créer et manipuler des structures d'extension de la machine virtuelle.

Le temps de lecture de ce didacticiel est estimé à 25 minutes.

# Mise en place

Pour commencer, créez le canevas de l'extension dans le fichier structures.svm_plugin en utilisant ce code :

    PLUGIN struct

    DEFINE

# Définition

Une structure d'extension est un conteneur de données réservé aux extensions. En particulier, une structure ne peut pas être écrite en mémoire, et ne peut pas apparaître en tant qu'argument d'instruction.

Un point important doit être mentionné : même si l'existence d'une structure d'extension est publique au sein de la machine virtuelle (les autres extensions en connaissent l'existence), le contenu de la structure en C/C++ doit être en général considéré comme privé à l'extension qui la définit.

## Structure

La première chose qu'une structure définit, c'est le conteneur de données lui-même.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}

Cette définition, très proche de celle d'un type, permet de définir la struct C/C++ qui a pour type le nom formé de la chaine fixe "struct_" suivie du nom de l'entrée de la structure.

## Destruction

La seule fonction obligatoire pour une structure est sa fonction de destruction.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}
    delete default: %{}

## Copie

La seconde fonction, optionnelle, permet d'activer la copie d'une structure.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}
    delete default: %{}
    copy default: %{}

Générez et compilez l'extension. Pour l'instant, l'utilisation de cette extension est ultra réduite, et écrire une application avec n'est guère utile.

- Une structure se définit avec le prototype `STRUCT plugin.entry` suivi d'un bloc décrivant le contenu de la structure C ou C++ associée à la structure extension.
- L'existence de cette structure est publiée par l'extension, mais son contenu reste privé à l'extension.
- La seule fonction obligatoire est la fonction de destruction dont la forme la plus simple se résume à `delete default: %{}`, forme appellant le destructeur de la structure C++.
- L'autre fonction disponible permet d'activer la copie de la structure.

# Opérations

## Création

La création d'une structure, au delà de celle en C/C++, se fait via l'interface programmatique.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}
    delete default: %{}
    copy default: %{}

    INSTRUCTION struct.example
    %{
    	auto rs = new struct_instance { 17, "text" };
    	SVM_Structure s = ::svm_structure_new(svm,CONST_PEP(struct,instance),rs);
    %}

Vous pouvez générer et compiler cette extension, mais son utilisation n'est guère spectaculaire.

Notez cependant la similarité entre l'appel à la fonction `svm_structure_new` et celle utilisée pour les types extension `svm_value_plugin_new`.

## Copie

La fonction de destruction d'une structure est automatiquement appellée par la machine virtuelle lorsque la structure n'est plus utile. La fonction de copie, quant à elle, n'est jamais appellée par la machine virtuelle : elle ne peut être appellée qu'explicitement via l'interface programmatique.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}
    delete default: %{}
    copy default: %{}

    INSTRUCTION struct.example
    %{
    	auto rs = new struct_instance { 17, "text" };
    	SVM_Structure s = ::svm_structure_new(svm,CONST_PEP(struct,instance),rs);
    	SVM_Structure c = ::svm_structure_copy(svm,s);
    %}

Vous pouvez générer et compiler cette extension, mais son utilisation n'est toujours pas spectaculaire.

## Introspection

Il est possible à partir d'une structure de récupérer son type et le pointeur vers la structure C/C++ contenue dans la structure.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	int _i;
    	std::string _s;
    %}
    delete default: %{}
    copy default: %{}

    INSTRUCTION struct.example
    %{
    	auto rs = new struct_instance { 17, "text" };
    	SVM_Structure s = ::svm_structure_new(svm,CONST_PEP(struct,instance),rs);
    	SVM_Structure c = ::svm_structure_copy(svm,s);
    	SVM_Value_PluginEntryPoint type = ::svm_structure_get_type(svm,c);
    	struct_instance *i = reinterpret_cast<struct_instance*>(::svm_structure_get_internal(svm,CONST_PEP(struct,instance),c));
    	i->_i = 42;
    %}

La fonction `svm_structure_get_type` permet de récupérer le type d'une structure sous la forme d'un point d'entrée d'extension. De même, la fonction `svm_structure_get_internal` permet de récupérer le pointeur sur la structure C/C++ conservée par la structure. Notez la présence du type dans cette fonction, qui sert de garant pour la validité de l'appel au reinterpret_cast du C++.

Vous pouvez générer et compiler cette extension, mais son utilisation ne présente toujours pas un grand intérêt.

- Une structure est créé avec l'appel à la fonction de l'interface programmatique `svm_structure_new`.
- Une structure qui supporte l'opération de copie peut être copiée avec l'appel à la fonction de l'interface programmatique `svm_structure_copy`.
- Il est possible de faire de l'introspection sur une structure grâce aux fonctions de l'interface programmatique `svm_structure_get_type` et `svm_structure_get_internal`.

# Usages

Les usages d'une structure d'extension peuvent être multiples, et le présent didacticiel ne saurait toutes les décrire. Cependant, certains usages caractéristiques des structures méritent une attention particulière.

## Composition de type

La première utilisation est la composition de type : il s'agit de définir un type dont une ou plusieurs parties sont des structures, pour rendre ce type polymorphe.

Modifiez le code de l'extension :

    PLUGIN struct

    DEFINE

    STRUCT struct.instance
    %{
    	long long int _i;
    	std::string _s;
    %}
    delete default: %{}
    copy default: %{}

    TYPE struct.interface
    %{
    	bool _b;
    	SVM_Structure _s;
    %}
    delete default:
    %{
    	VARIABLE_LOCAL(object->_s);
    %}
    copy object:
    %{
    	auto c = new type_interface;
    	c->_b = object->_b;
    	c->_s = ::svm_structure_copy(svm,object->_s);
    	VARIABLE_GLOBAL(c->_s);
    	return c;
    %}

    INSTRUCTION struct.new BLN INT STR -> struct.interface
    %{
    	auto b = ARGV_VALUE(0,boolean);
    	auto i = ARGV_VALUE(1,integer);
    	auto s = ARGV_VALUE(2,string);
    	auto t = new type_interface;
    	t->_b = b==TRUE;
    	auto rs = new struct_instance { i , RAW_STRING(s) };
    	t->_s = ::svm_structure_new(svm,CONST_PEP(struct,instance),rs);
    	VARIABLE_GLOBAL(t->_s);
    	return NEW_PLUGIN(struct,interface,t);
    %}

Dans cet exemple, la composition est limitée. Mais dans un didacticiel à venir, un autre objet des extensions va rendre cela beaucoup plus utile : lorsque cette construction est poussée à ses limites, on obtient le type `com.device` qui est une interface ultra-générique pour réaliser des entrées/sorties.

Générez et compilez l'extension. Vous pouvez créer une petite application qui crée une valeur du type `struct.interface`. Vous pouvez améliorer l'extension pour afficher l'ensemble de la valeur.

Notez que pour la composition soit fonctionnelle, il est impératif de rendre globale la variable Simple Virtual Machine de la structure. De la même manière, une structure extension qui contient des variables Simple Virtual Machine peut être amenée à rendre ces variables globales le temps de l'existence de la structure.

## Paramètre d'interface programmatique

Les structures sont également utilisées par l'interface programmatique de la machine virtuelle pour spécifier d'une manière générique (mais toutefois contrôlée par la machine virtuelle) des valeurs utilisateur.

Des exemples de cet usage seront présentés dans un didacticiel ultérieur.

- Les structures peuvent être utilisées comme partie d'un type pour introduire du polymorphisme dans les types. Contrairement au polymorphisme C/C++, ce polymorphisme par composition peut être contrôlé depuis le code machine via les valeurs de type `PEP`.
- L'interface programmatique utilise les structures comme conteneurs utilisateur dans certaines fonctions.

# Conclusion

Vous venez de voir comment créer et manipuler les structures extensions depuis une extension.

Les structures sont un concept relativement pauvre en eux-mêmes, et vont prendre toute leur importance avec un autre concept des extensions qui sera abordé dans un prochain didacticiel.

Combinée correctement avec les autres objets des extensions, les structures apportent une flexibilité très intéressante dans l'écriture des extensions.