Transpilateur PAS2JS de Pascal à JavaScript: incompatible avec Delphi et solutions

De nos jours, dans la poche d'une personne ordinaire se trouve un puissant ordinateur personnel, dont vous ne pouviez rêver qu'il y a environ 10 à 20 ans. Et si vous avez des kilomètres de code Windows débogué et des applications et utilitaires fonctionnant parfaitement écrits en Delphi, vous voudrez sûrement utiliser cette richesse pour le développement mobile. Et aussi l'expérience acquise lors de la programmation sous Windows. PAS2JS vous aidera à combiner deux mondes: le développement pour Windows et la création d'applications Web et de modules Node.js.


Certaines des difficultés découvertes de l'expérience personnelle sont discutées dans cet article.


Pourquoi ne pas simplement apprendre JavaScript et y écrire des applications Web?


J'ai assez bien appris JavaScript. Mais d'abord, la programmation pour le Web est plus que la simple connaissance de la langue. Deuxièmement, la possibilité d'écrire un code pour différentes plates-formes est inestimable. Vous pouvez déboguer des modules d'application dans l'IDE Delphi à l'aide de son puissant débogueur et éditeur, puis, en ajoutant les liaisons nécessaires, obtenir une application de travail prête à l'emploi pour le site. Et lorsque vous corrigez l'erreur ou ajoutez de nouvelles fonctionnalités à l'application pour Windows, il suffira de recompiler les modules JavaScript dans PAS2JS .


Il convient de noter que même si PAS2JS ne prend pas en charge toutes les fonctionnalités du langage Delphi, elles sont répertoriées sur le site . De plus, certains fragments de code PAS2JS apparemment simple ne peuvent pas être transposés en JavaScript.


Difficultés de traduction


Ainsi, le nouveau package PAS2JS a été téléchargé à partir de FTP , nous essayons de recompiler le simple "Hello World", et nous nous arrêtons immédiatement à:


uses System.SysUtils; 

Erreur: impossible de trouver l'unité "System.SysUtils"

Les packages PAS2JS prêts à l'emploi, qui se trouvent dans le dossier packages, dupliquent partiellement les unités système Delphi. Mais ils n'ont pas de préfixe dans le nom. La solution est simple: supprimez le préfixe «System». du nom de l'unité. Le programme est compilé dans Delphi (sinon, vérifiez la présence du préfixe «System» dans Unit Scope Names, dans le menu Delphi Project | Options | Delphi Compiler).


Transtypage de type en constantes


PAS2JS ne prend pas en charge la conversion de type dans les expressions constantes:


 const CODE_A = Word('a'); 

Erreur: expression constante attendue

Dans le cas des types énumérés, vous pouvez essayer de changer ainsi, cela va:


 const CODE_A = Ord('a'); 

PAS2JS ne comprend pas non plus les fonctions intégrées des langues Lo et Hi. Dans la définition des constantes, elles peuvent être remplacées comme suit:


 const LO_BYTE = $1234 and $FF; // Lo($1234); HI_BYTE = $1234 shr 8;// Hi($1234); 

Caractères et chaînes ANSI


J'espère que vous êtes déjà passé aux chaînes Unicode dans vos projets Delphi? Si vous avez laissé certaines lignes au format ANSI afin d'économiser de la mémoire, elles ne seront pas converties en JavaScript: PAS2JS ne connaît pas les types AnsiChar, AnsiString, Utf8String et RawByteString. Pensez à les remplacer par des types Unicode ou Byte et Array of Byte.


Voici un exemple de remplacement d'AnsiChar par Byte:


 //  procedure TestAnsiCharAndByte1; const SMALL_ENG_LETTERS = ['a'..'z']; CAPITAL_ENG_LETTERS = ['A'..'Z']; var ch: AnsiChar; engs: set of AnsiChar; begin engs := SMALL_ENG_LETTERS + CAPITAL_ENG_LETTERS; ch := 'Z'; if ch in engs then Writeln('It''s an English letter'); end; //  procedure TestAnsiCharAndByte2; const SMALL_ENG_LETTERS = [Ord('a')..Ord('z')]; CAPITAL_ENG_LETTERS = [Ord('A')..Ord('Z')]; var ch: Byte; engs: set of Byte; begin engs := SMALL_ENG_LETTERS + CAPITAL_ENG_LETTERS; ch := Ord('Z'); if ch in engs then Writeln('It''s an English letter'); end; 

Lettre sans vie ó


Par curiosité: en polonais, il y a une lettre ó - O kreskowane, Unicode # $ 00F3. Pour une raison quelconque, PAS2JS ne l'aimait pas, et dans certains cas, il ne peut pas percevoir une ligne si cette lettre y est incluse:


 var s: string; begin s := #$00F3'abdef'; //  s := 'abdef'#$017C; //  s := #$00F3'abdef'#$017C; // Error: Illegal character s := #$00F3; s := s + 'abdef'#$017C; //    end; 

Déclaration de cas


Une surprise soudaine réside dans la déclaration de cas, dans laquelle PAS2JS a refusé d'accepter les lettres russes comme options:


  ch := ''; case ch of '': Writeln(' ""'); // Error: Incompatible types: got "Char" expected "Char" (???) ''..'': Writeln('   '); // Error: char expected, but string found end; 

La définition des constantes pour les lettres russes nécessaires a aidé:


 const ckbA = #$410; //  ckbB = #$411; //  ckbYa = #$42F; //  var ch: Char; begin ch := ''; case ch of ckbA: Writeln(' ""'); ckbB..ckbYa: Writeln('   '); end; 

Conclusions


J'ai réussi à compiler un petit projet Delphi pour le Web, apportant des modifications relativement petites au code source du programme, et pour le temps gagné j'ai écrit cet article. Les tests ont montré que les deux versions du programme: pour Windows et pour le Web, fonctionnent exactement de la même manière. C'est sans aucun doute un succès: je peux maintenant développer ce projet en finalisant un programme en Delphi, et en le traduisant en JavaScript à l'aide de PAS2JS.


Quant aux défauts mineurs identifiés, je suis sûr qu'ils seront rapidement éliminés. Le projet PAS2JS étant ouvert et gratuit, développé activement par la communauté Free Pascal .

Source: https://habr.com/ru/post/fr436920/


All Articles