# Introduction

Ce didacticiel est destiné aux nouveaux utilisateurs de la Simple Virtual Machine.

Dans ce didacticiel, vous allez manipuler un concept important lié aux extensions.

Le temps de lecture de ce didacticiel est estimé à 15 minutes si l'utilisation des instructions, types et interruptions extensions a été abordée.

# Mise en place

Pour commencer, créez le canevas de l'application dans le fichier exécutable points_entree_extension.svm en utilisant ce code :

    #!/usr/bin/env svm
    DESCRIPTION
    Plugin entry points example
    END
    LOG
    DEBUG "Plugin entry points" STYLE "default"
    PLUGIN "svmcom.so"
    PLUGIN "svmrun.so"
    PLUGIN "svmreal.so"
    PLUGIN "svmstr.so"
    PROCESS "application"
    	CODE "main" INLINE
    		:debug BREAK
    	END
    END

# Point d'entrée d'extension

## Classification

Modifiez le code pour obtenir :

    #!/usr/bin/env svm
    DESCRIPTION
    Plugin entry points example
    END
    LOG
    DEBUG "Plugin entry points" STYLE "default"
    PLUGIN "svmcom.so"
    PLUGIN "svmrun.so"
    PLUGIN "svmreal.so"
    PLUGIN "svmstr.so"
    PROCESS "application"
    	CODE "main" INLINE
    		:debug BREAK
    		:memory com.device/stdin, real.number/r, STR/s, real.number/i
    		CONST real.number "0" -> &r
    		:com.open com.terminal STDIN -> &stdin
    		:interruption !com.interrupted retry
    	:label input_loop
    		:com.read @&stdin com.line -> &s
    		:goto input_end :unless &s INITIALISED
    		:str.replace @&s 1 CONST str.pattern "\n" => ""
    		:real.parse @&s -> &i
    		:real.add @&r @&i -> &r
    		:goto input_loop
    	:label input_end
    		:real.mul @&r CONST real.number "3.14159" -> &r
    		:com.message "Result: " @&r
    		:shutdown
    	:label retry
    		:run.retry
    	END
    END

Vous pouvez lancer l'application, et constater sa relative utilité :

    cat << EOM | ./points_entree_extension.svm
    1.4
    2.5
    3.6
    EOM

    Result: 23.561925

Ce qui nous intéresse plus sur cette application, c'est son code. Dans ce code se trouvent plusieurs fois la construction `identifiant.identifiant`.

Placez ces constructions en différentes catégories selon leur usage : types, instructions, interruptions, ou autres.

Vous devez obtenir :

Types | Instructions | Interruptions | Autres
--- | --- | --- | ---
com.device real.number str.pattern | com.open com.read str.replace real.parse real.add real.mul com.message run.retry | com.interrupted | com.terminal com.line

## Une petite anomalie

Dans le tableau que vous venez d'obtenir, la majorité de ces constructions sont dans une catégorie évidente. Il en reste seulement deux ici qui ont une utilisation non décrite jusqu'ici.

De par leur placement dans le code, ces valeurs semblent être des arguments pour les instructions où elles se trouvent !

La construction `identifiant.identifiant` est une valeur spécifique de la machine virtuelle, représentant un point d'entrée d'une extension. La catégorie de l'objet est déduite de l'endroit où se trouve cette construction dans le code.

Elle est dédiée à l'utilisation des extensions.

# Utilisation

Modifiez le code, pour ajouter un tableau de points d'entrée d'extension et les utiliser par lecture en mémoire partout où cela est possible :

    #!/usr/bin/env svm
    DESCRIPTION
    Plugin entry points example
    END
    LOG
    DEBUG "Plugin entry points" STYLE "default"
    PLUGIN "svmcom.so"
    PLUGIN "svmrun.so"
    PLUGIN "svmreal.so"
    PLUGIN "svmstr.so"
    PROCESS "application"
    	CODE "main" INLINE
    		:memory PEP*12/pep
    		[ com.device , real.number , com.open , com.terminal , com.read , com.line , str.replace , real.parse , real.add , real.mul , com.message , run.retry ] -> pep
    		:debug BREAK
    		:memory @(pep/0)/stdin, @(pep/1)/r, STR/s, @(pep/1)/i
    		CONST real.number "0" -> &r
    		:@(pep/2) @(pep/3) STDIN -> &stdin
    		:interruption !com.interrupted retry
    	:label input_loop
    		:@(pep/4) @&stdin @(pep/5) -> &s
    		:goto input_end :unless &s INITIALISED
    		:@(pep/6) @&s 1 CONST str.pattern "\n" => ""
    		:@(pep/7) @&s -> &i
    		:@(pep/8) @&r @&i -> &r
    		:goto input_loop
    	:label input_end
    		:@(pep/9) @&r CONST real.number "3.14159" -> &r
    		:@(pep/10) "Result: " @&r
    		:shutdown
    	:label retry
    		:@(pep/11)
    	END
    END

Relancez l'application pour constater que le comportement est exactement le même :

    cat << EOM | ./points_entree_extension.svm
    1.4
    2.5
    3.6
    EOM

    Result: 23.561925

Déja, le point est accordé, le code est beaucoup moins lisible ainsi ! En règle générale, l'utilisation d'un point d'entrée d'extension lue depuis la mémoire est plutôt limitée, même si en certaines circonstances cela peut être très utile.

- Un point d'entrée d'extension est une valeur de la machine qui porte le type `PEP` (pour "plugin entry point" en anglais) lorsqu'elle est écrite en mémoire.
- Dans le code, un point d'entrée d'extension peut être remplacé par une lecture en mémoire sauf après les symboles `!` et `CONST`.
- Les points d'entrée d'extension peuvent être utilisés comme arguments d'instruction. Souvent, cela signifie que l'instruction va accéder à un autre point d'entrée d'extension lors de son exécution.

# Conclusion

Vous venez de voir comment utiliser les points d'entrée d'extension depuis le code et la mémoire de la machine virtuelle.

Les extensions sont une capacité majeure de la machine virtuelle pour l'écriture d'applications. Les points d'entrée d'extension sont un concept permettant au code de manipuler les objets définis dans les extensions. Ils sont donc vitaux lorsque l'application devient conséquente.