Transpilador PAS2JS de Pascal a JavaScript: incompatible con Delphi y soluciones alternativas

Hoy en día, en el bolsillo de una persona común se encuentra una poderosa computadora personal, con la que solo se podía soñar hace 10-20 años. Y si tiene kilómetros de código de Windows depurado y aplicaciones y utilidades perfectamente funcionales escritas en Delphi, seguramente querrá usar esta riqueza para el desarrollo móvil. Y también la experiencia adquirida durante la programación en Windows. PAS2JS lo ayudará a combinar dos mundos: el desarrollo para Windows y la creación de aplicaciones web y módulos Node.js.


Algunas de las dificultades descubiertas de la experiencia personal se discuten en este artículo.


¿Por qué no simplemente aprender JavaScript y escribir aplicaciones web en él?


He aprendido JavaScript lo suficientemente bien. Pero primero, programar para la Web es más que solo conocer el idioma. En segundo lugar, la capacidad de escribir un código para diferentes plataformas no tiene precio. Puede depurar módulos de aplicación en Delphi IDE utilizando su potente depurador y editor, y luego, agregando los enlaces necesarios, obtenga una aplicación de trabajo preparada para el sitio. Y cuando corrija el error o agregue nuevas funcionalidades a la aplicación para Windows, será suficiente simplemente recompilar los módulos JavaScript en PAS2JS .


Cabe señalar que si bien PAS2JS no admite todas las características del lenguaje Delphi, se enumeran en el sitio . Además, algunos fragmentos de código PAS2JS aparentemente simple no se pueden transponer a JavaScript.


Dificultades de traducción


Entonces, el nuevo paquete PAS2JS se descargó de FTP , tratamos de recompilar el simple "Hola Mundo" e inmediatamente nos detenemos en:


uses System.SysUtils; 

Error: no se puede encontrar la unidad "System.SysUtils"

Los paquetes PAS2JS listos para usar, que se pueden encontrar en la carpeta de paquetes, duplican parcialmente las unidades del sistema Delphi. Pero no tienen un prefijo en el nombre. La solución es simple: elimine el prefijo "Sistema". del nombre de la unidad. El programa se compila en Delphi (si no es así, verifique la presencia del prefijo "Sistema" en los Nombres de Alcance de la Unidad, en el menú Delphi Project | Opciones | Delphi Compiler).


Tipo de fundición en constantes


PAS2JS no admite la conversión de tipos en expresiones constantes:


 const CODE_A = Word('a'); 

Error: se espera una expresión constante

En el caso de los tipos enumerados, puede intentar cambiar, así, esto va:


 const CODE_A = Ord('a'); 

Además, PAS2JS no comprende las funciones integradas de los idiomas Lo y Hi. En la definición de constantes, se pueden reemplazar de la siguiente manera:


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

Caracteres y cadenas ANSI


Espero que ya haya cambiado a cadenas Unicode en sus proyectos de Delphi. Si dejó algunas de las líneas en formato ANSI para ahorrar memoria, no se convertirán a JavaScript: PAS2JS no conoce los tipos AnsiChar, AnsiString, Utf8String y RawByteString. Considere reemplazarlos con tipos Unicode, o Byte y Array of Byte.


Aquí hay un ejemplo de reemplazo de AnsiChar con 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; 

Carta sin vida ó


Como curiosidad: en polaco hay una letra ó - O kreskowane, Unicode # $ 00F3. Por alguna razón, a PAS2JS no le gustó y, en algunos casos, no puede percibir una línea si se incluye esta letra:


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

Declaración del caso


Una sorpresa repentina yacía en la declaración del caso, en la que PAS2JS se negó a aceptar las letras rusas como opciones:


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

La definición de constantes para las letras rusas necesarias ayudó:


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

Conclusiones


Logré compilar un pequeño proyecto de Delphi para la Web, haciendo cambios relativamente pequeños en el código fuente del programa, y ​​por el tiempo ahorrado escribí este artículo. Las pruebas mostraron que ambas versiones del programa: para Windows y para la Web, funcionan exactamente igual. Esto es sin duda un éxito: ahora puedo desarrollar este proyecto finalizando un programa en Delphi y traduciéndolo a JavaScript usando PAS2JS.


En cuanto a las fallas menores identificadas, estoy seguro de que se eliminarán rápidamente. Dado que el proyecto PAS2JS es abierto y gratuito, desarrollado activamente por la comunidad Free Pascal .

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


All Articles