Langage Script 3DVL

Introduction

Le langage 3DVL est un langage de type script mise au point vers 1990 afin d’être directement interfacé avec des données issues de systèmes d’analyse du mouvement (c3D, mdf etc.).

Ce langage script une un langage compilé sous forme de Opcode. Ceci permet d’être un peu plus rapide qu’un langage strictement interprété.

Ce langage est un véritable langage de programmation se rapprochant très fortement des langages “ C ” et “ Pascal ”. Il comprend donc les notions de variables, sous-programmes, programme principal etc. Cependant, la différence majeure réside dans le fait que ce langage est très faiblement typé. Ainsi une même variable peut être un nombre, puis une chaîne de caractères etc. Son type est déterminé lors de l’exécution du programme.

Vous pouvez réaliser des programmes simples, par exemple le calcul d’un ou de plusieurs marqueurs virtuels, ou des programmes complexes, comportant plusieurs modules (fichiers), par exemple pour le calcul de filtres, les calculs statistiques sur les courbes etc.

Module et Programme

Un module est l’unité de base d’un programme. Un programme peut comporter plusieurs modules.
Chaque module peut être compilé séparément, dans un fichier texte différent, avec une extension “ 3dl ” ou “3dh”.
Le module principal doit toujours exister. Il doit commencer par le mot clé : “ Main ”.
Un module se termine toujours par le mot clé “End”.

Exemple de modules:

Procedure Proc1()
end;

Function Func1()
return 0 ;
end ;

Procedure Main()
Proc1() ;
Print Func1() ;
end ;

Les mots clés “ Function ” et “ Procedure ” définissent les modules. Le module dont le nom est “ Main ” correspond au point d’entrée du programme. Les parenthèses () sont obligatoires, même vides, lors de la définition ou de l’appel d’une fonction ou d’une procédure.

Proc1 ainsi que Func1 sont des noms donnés par vous même lorsque vous créez ces modules.
Lorsque vous voulez utiliser un module d’un autre fichier, il faut utiliser la directive :

#include    « filename.3dl »

dans le fichier source.

Dans l’exemple ci dessus, si la procédure Proc1 et la fonction Func1 sont définies dans le fichier  MyLib.3dl, le programme sera alors de cette forme :

#include « MyLib.3dl »

Procedure Main()
Proc1() ;
Print Func1() ;
end ;

Tous les fichiers d’un même projet, c’est à dire pour un même programme doivent se trouver dans le même répertoire ou dans le répertoire des bibliothèques défini dans l’option du projet.

Mots Clés

Les mots clés sont des éléments réservés à un usage particulier et qui ne doivent pas être employés en tant qu’identificateur.

AND
BEGIN
CONST
DEFINE
DO
ELSE
END
ENDIF
ENDL
EXIT
FALSE
FOR
FUNC
FUNCTION
IF
IFDEF
IFNDEF
INCLUDE
LOOP
NIL
NOT
OR
PRINT
PROC
PROCEDURE
RETURN
STEP
STRUCT
THEN
TO
TRUE
UNDEF
VAR
WHILE

Contrairement au C,  ce langage ne fait pas de différence entre les minuscules et les majuscules.

Identificateurs

Les identificateurs sont des noms arbitraires donnés aux variables,  procédures et fonctions du programme. Ils peuvent contenir les lettres de a à z, le caractère de soulignement _  et les chiffres de 0 à 9. Il n’y a que deux restrictions

Le premier caractère ne doit pas être un chiffre.
Le nombre de caractère est limité à 32.
La casse des lettres

Contrairement au C, mais en accord avec le langage Pascal, 3DVL ne différencie pas les majuscules des minuscules, en sorte que Somme et somme représentent le même identificateur.

Séparateurs

Les séparateurs de 3DVL sont définis comme suit :
séparateur :

[ ] ( ) { } , ; * :=

Crochets [ ]

Les crochets [ ] ouvrant et fermant servent à spécifier un indice entier d’accès à un vecteur ou un tableau

Var Tableau ;
Tableau := Array(10) ;
Vecteur := Fvector(100) ;
Tableau[0] := 1 ;
Tableau[1] := 2 ;
Vecteur[50] := 45.45 ;
var t10 := Tableau[9] ;

Parenthèses ( )

Les parenthèses ouvrantes et fermantes ( )  permettent de grouper des expressions, d’indiquer des appels et des paramètres de fonctions et procédures.

d := c * (a + b) ;
s := Somme(a, b) ;

Function Somme(a, b)

 Accolades { }

Les accolades  ouvrantes et fermantes { } permettent d’initialiser un tableau et de définir une structure.

struct  abc {a,b,c};
var tab := {1, 2, 3, 4} ;

Virgule ,

La virgule (,) sépare les éléments de la liste d’argument d’une fonction ou d’une procédure.

Procedure Proc1(a, b, c, d) ;

Point-virgule ;

Le point virgule [ ; ] est le terminateur d’instruction. Toute expression légale en 3DVL (C et Pascal) qui est suivi pas un point virgule est interprété en tant qu’instruction .

Astérisque *

L’astérisque (*) dans une déclaration d’une variable indique la création d’une référence à cette variable.

Proc Inc(x)
x:=x+1;
end;

var x:=0;
Inc(x);
Print x ;         // affiche 0
Inc(*x);
Print x ;         // affiche 1

L’expression Inc(x) renvoie zéro (0) car la valeur de la variable x est copiée et envoyée à la procédure Inc. La variable x n’est donc pas modifiée.

Dans l’expression Inc(*x), c’est une référence directe à la variable x qui est passée à la procédure Inc. La variable x est donc modifiée.
Les tableaux sont toujours passés par références

L’astérisque s’utilise aussi pour la multiplication.

Signe := (initialisateur)

Le signe deux points égale (:= ) permet de séparer les déclarations de variables des listes d’initialisation.

var x := 0 ;
var tab := {1, 2, 3, 4} ;

Avec 3DVL, tous types de déclaration peuvent apparaître en tous points du code source.

Le signe := est aussi utilisé en tant qu’opérateur d’affectation dans les expressions :

var x, a, b, c ;
x := 0 ;
a := {1, 2, 3}
b := a[0] ;
c := x + b ;

Types Fondamentaux

Les spécificateurs de types fondamentaux sont établis comme suit :

string  : chaîne de caractères
double  : nombre réel en double précision
long : entier long signé
array : tableau d’éléments quelconques
Vecteur : Tableau unidimensionnel de nombres (réels ou entier)

Il n’existe pas de mot clé pour spécifier un type de variable. Le type d’une variable est spécifié au moment de son instanciation :

var a ;
a := 0 ;
var b ;
b := 3.1415 ;

var c ;
c := {0.0, 1.232, 7.45} ;

var s ;
s := « Ceci est une chaîne de caractères »;
var vf := Fvector(100) ;
var vi := Ivector(100) ;

Les trois variables a, b et c n’ont aucun type lors de leur déclaration.

a devient un nombre entier (de type long) par l’instruction a := 0 ;
b devient un nombre réel (de type double) par l’instruction  b := 3.1415 ;
c devient un tableau (array) par l’instruction c := {0.0, 1.232, 7.45} ;
vf devient un vecteur de 100 éléments (nombres réels en double précision)
vi devient un vecteur de 100 éléments (nombres entiers)

Ainsi, au cours de cette documentation, lorsque le type d’une variable n’est pas définie, la variable sera de type « variant ». Par contre, lorsque le type doit être définie, par exemple lors de l’appel d’une procédure, une variable pourra être du type, string, double, long etc…

Opérateurs unaires

Opérateur d’incrémentation ++

Cet opérateur incrémente une variable entière. Il est surtout utilisé dans les boucles for()

var i ;
for(i :=0 ; i < 100 ; i++)
Print i, endl ;
end ;

Opérateur SizeOf()

Cet opérateur retourne la taille de la variable. Si cette variable est un tableau ou un vecteur, sizeof() retourne le nombre d’éléments.

var table := Array(100) ;
print sizeof(table), endl ;
var i : = 0 ;
print sizeof(i), endl ;

 Opérateur TypeOf()

Cet opérateur retourne le type de variable. Les types sont retournés sous forme d'une chaîne de caractères.: " Number", "Real", "String", "Bool", "Nil", "Array", "Ivector", "Fvector".

Exemple:

Procedure Main()
var i:= 0;        // entier
      var f:= 0.5;      // reel
      var s:= « Chaine »;
var b:= false;
var n := Nil;
var t:= Array(10);
var vi := IVector(10);
var vf := FVector(10);
Print TypeOf(i), endl;
Print TypeOf(f), endl;
Print TypeOf(s), endl;
Print TypeOf(b), endl;
Print TypeOf(n), endl;
Print TypeOf(t), endl;
Print TypeOf(vi), endl;
Print TypeOf(vf), endl;
End;

 Opérateur Empty()

Cette opérateur permet de tester une variable et de déterminer si celle-ci est vide (NIL) ou pas.

Exemple

Procedure Main()
Var x, y, z;
x := 12;
y := Array(10);
if Empty(x) then Print « x est vide « ; end;
if Empty(y[0]) then Print « y[0] est vide « ; end;
if Empty(z) then Print « z est vide « ; end;
End;

Opérateur de référence *

Cet opérateur permet de spécifier, lors de l'appel des fonctions, l'adresse d'une variable. Il doit toujours être utilisé si la variable doit être modifiée par la fonction appelée. Dans l'exemple ci-dessous, seul l'appel Inc(*i2) permet de modifier la variable i2.

Exemple

Procedure Inc(x)
x := x+1;
end;

Procedure main()
var i1 := 1;
var i2 := 1;
Inc(i1);
Inc(*i2);
Print i1,  »  « , i2, endl;
end;

Négation logique !

Cet opérateur s'emploie uniquement sur les variables logiques (Bool ou résultant d'un test). Il a pour effet d'inverser la variable (true et false).

Exemple

Procedure main()
var b := true;
print b,  »  « , !b, endl;
end;

 Opérateur d’inversion ‘-‘

Cet opérateur agit sur les nombres (entiers ou réels), les booléens, les chaînes de caractères et les tableaux.

Exemple:

Procedure main()
var i := -1;
var b := true;
var s:= « 0123456789 »;
var t:= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
var v:= FVector(10);
print i,  »  « , -i, endl;
print b,  »  « , -b, endl;
print s,  »  « , -s, endl;
print t,  »  « , -t, endl;
var nv := – v;
end;

Opérateurs binaires

Ces opérateurs s’utilisent habituellement sur des scalaires (nombres réels ou entiers). Le résultat est du même type que les arguments utilisés.

Opérateur d’addition +

Var i1 := 100 ;
var i2 := 200 ;
var i3 := i1+i2 ; //résultat est un nombre entier

Var r1 := 100.0 ;
var r2 := 200.0 ;
var r3 := r1+r2 ; //résultat est un nombre réel

Var i1 := 100 ;
var r2 := 200.0 ;
var r3 := i1+r2 ; //résultat est un nombre réel

Opérateur de soustraction

var x := 100
var y := 200 ;
var z ;
z := x – y ;

Opérateur de multiplication *

var x := 100
var y := 200 ;
var z ;
z := x * y ;

Opérateur de division /

var x := 100
var y := 200 ;
var z ;
z := x / y ;

Ces opérateurs binaires peuvent être utilisés avec d’autres types :

Les chaînes de caractères (+ uniquement)
Les vecteurs. Dans ce cas, le nombre d’éléments des deux vecteurs doit être le même. Si ce nombre est différent, le vecteur résultant contient le nombre minimum d’éléments.
var v1 := FVecteur(100) ;
var v2 := FVecteur(100) ;
….//remplissage des deux vecteurs
var v3 := (v1+v2)/2.0 ; //calcul du milieu

Opérateurs Logiques

AND,
OR
NOT

Opérateurs relationnels

Ces opérateurs s'utilisent lors de tests. Le résultat est une valeur booléenne (true or false).

Opérateur Inférieur à <
Opérateur supérieur à >
Opérateur égal à =
Opérateur inférieur ou égal à <=
Opérateur supérieur ou égal à >=

Exemple :

Procedure Main()
Var x, y, z;
x := 12;
y := 23.56;
z := 0;
if x > y then print « x > y »; end;
if x = y then print  » x = y »; end;
if z <= x then
print  » z <= x »;
else
print « z > x »;
end;
End;

Opérateur d’affectation :=

Le signe := est utilisé en tant qu’opérateur d’affectation dans les expressions :

var x, a, b, c ;
x := 0 ;
a := {1, 2, 3}
b := a[0] ;
c := x + b ;

Instructions

Blocs

Une instruction composée, ou bloc, est une liste d’instruction délimitée par les mots clés Begin et end.

begin
expr1;
expr2;

exprn;
end;

Le mot clé “ begin ” est être remplacé par

Proc
Procedure
Func
Function

exemple :

Procedure Truc()
expr1 ;
expr2 ;
end ;

Instructions de sélection

Elles permettent de choisir une direction particulière dans le déroulement du programme, par test de certaines valeurs : If .... Then ...else...end ;

var valeur := 0 ;
if Valeur > Seuil Then
Print ‘Le seuil est dépassé’, end ;
else
Valeur++ ;
end ;

Instructions d’itération

Ces instructions permettent d’établir des boucles . Il existe trois formes de boucles : while do , for () , For to Step

while (i > seuil) do
i := i-1 ;
end ;

var i ;
for(i := 0 ; i < seuil ; i++)
Print i ; endl ;
end ;

for i := 0 to seuil Step 2 do
Print i , endl ;
end ;

Instruction de branchement

Une instruction de branchement, lorsque elle est exécutée, passe le contrôle à l’instruction suivante sans condition. Il existe trois instructions de branchement : Exit, Loop et Return.

Func OverFlow(v)

End;

Var i ;
for (i := 0 ; i < Max ; i++)

if  OverFlow(i) then exit ; end ;  // sort de la boucle
….
end ;

func Nul (v);
Var i ;
for (i := 0 ; i < Max ; i++)

if  Nul(i) then Loop ; end ;       // itération suivante
….
end ;

Const seuil := 100 ;

Function Sup(var x)
if ( x > seuil) then
return True ;
else
return false ;
end ;
end ;