13

Variant en C++ (part 1 : php side)

mar

Avant de commencer mon compilateur, il faut que je regarde la faisabilité du projet en essayant de convertir à la main un code PHP pour voir les possibilités qui s’offre à moi. J’ai opté pour une conversion en C++ car si ce n’est pas le plus simple des langages c’est en tout cas le plus riche (de plus il existe sur la plupart des systèmes). Comme la plupart des langages de script, le PHP utilise des variants en guise de variable. Je me suis donc attaché à implémenter le type variant en C++. Il existe déjà de nombreuse implémentation, mais rien ne vaut la sienne n’est-ce pas ;) ?

Type de variable

Un variant PHP peut contenir différents types de valeurs que l’on peut résumer ci-dessous

  • un entier
  • un flottant
  • un booléen : qui est finalement un entier
  • la valeur Null : qui est lui aussi un entier
  • une string
  • un tableau
  • un objet

Lorsqu’on applique une opération (une addition par exemple) entre 2 types différents de valeurs, le PHP se débrouille comme il peut pour convertir les données avant d’exécuter l’opération.
Cela fonctionne pour tous les types sauf pour les tableaux.

On se retrouve alors avec des étrangetés tel que

$a = 10 + true;					// ça marche
$b = 'yaourt' + null;			// ça aussi ça marche
$c = array() + 'fleur';		// ben là non !!! On ne peut pas ajouter un tableau à une chaîne.

De là à dire que c’est du gros n’importe quoi y a pas loin.
Dans la pratique, on essaye tant que possible d’éviter l’ajout d’un booléen avec un flottant, mais bon ça peut arriver.

Pourquoi le PHP permet-il l’addition de types incompatibles ?

C’est une bonne question! Je suppose qu’à l’origine Rasmus Lerdorf (le créateur du PHP) voulait éviter toute erreur d’exécution quitte à autoriser d’improbables opérations.
Dans la pratique on commet rarement ce genre d’erreur, car on sait quand même ce qu’on fait. De plus dès qu’on test on se rend vite compte que ca ne donne rien de bon !
En ce qui concerne les tableaux, il est peut être moins rare d’utiliser par erreur un tableau plutôt qu’un élément du tableau. Ainsi, pour aider au débuggage il aura été décidé de produire une erreur dans ce cas.
Au final, on se rend compte qu’on est au milieu du guet. Ce qui est assez étrange.

Les opérateurs du PHP dans le détails

Je me suis amusé à simuler toutes les opération type à type du PHP pour voir ce que cela donne.
Vous pouvez cliquer sur les liens des opérateurs ce-dessous pour voir comment le PHP gère les types de valeurs pour chaque opérateur.

Les opérateurs arithmétiques

Remarques

  • Sauf pour le +, toute opération impliquant un tableau est interdite.
  • Étrangement un objet est considéré comme valant 1.
  • null vaut 0, false vaut 0 et true vaut 1.
  • Si une des opérandes est un flottant alors le résultat sera flottant.
  • true + true = 2 !

Plus d’informations sur les opérateurs arithmétiques du PHP.

Les opérateurs binaires

Remarques

  • Les objets ET les tableaux sont considérés comme valant 1.
  • null vaut 0, false vaut 0 et true vaut 1.
  • Si les deux argument sont des chaines, alors l’opérateur est appliqué sur chaque octet
  • Tous les types de valeurs sont converti en entier (sauf dans le cas d’une opération entre deux chaînes)
  • Tous les résultats sont de type entier (sauf dans le cas d’une opération entre deux chaînes)

Plus d’informations sur les opérateurs binaires du PHP.

Les opérateurs de comparaison

Remarques

  • Les objets sont considérés comme valant 1 avant d’être comparé.
  • Les tableaux sont considérés comme valant 1 pour les opérateurs <, >, <= et >=.
  • Pour les opérateurs ==, !=, ===, !== appliqué sur des tableaux, tous les couples clé/valeur des tableaux sont testés.
  • null vaut 0, false vaut 0 et true vaut 1.
  • Tous les résultats sont de type boolean

Plus d’informations sur les opérateurs de comparaisons du PHP.

Ebola

Si je vais m’inspirer du PHP, mais je ne cherche pas à faire un compilateur de code PHP. Ce travail serait a mon avis trop titanesque pour moi !
Donc, certes, je vais prendre en compte tous les types de variables gérés par les variants du PHP, mais je ne gèrerai pas les opérations impliquant tableaux et objets.
Je ferai comme le PHP et considérerai que ces types ont la valeur entière 1 quelques soit l’opération.

Bon ben y a déjà de quoi faire !!!
On se retrouve bientôt pour l’implémentation en C++ des variants…

Répondre

Human control : 3 + 9 =