Transpiler PAS2JS de Pascal para JavaScript: incompatível com Delphi e soluções alternativas

Hoje em dia, no bolso de uma pessoa comum, encontra-se um poderoso computador pessoal, com o qual você só poderia sonhar 10 a 20 anos atrás. E se você tem quilômetros de código do Windows depurado e aplicativos e utilitários que funcionam perfeitamente escritos em Delphi, você certamente desejaria usar essa riqueza para o desenvolvimento móvel. E também a experiência adquirida durante a programação no Windows. O PAS2JS ajudará você a combinar dois mundos: desenvolvimento para Windows e criação de aplicativos da Web e módulos Node.js.


Algumas das dificuldades descobertas da experiência pessoal são discutidas neste artigo.


Por que não apenas aprender JavaScript e escrever aplicativos da Web nele?


Eu aprendi JavaScript bem o suficiente. Mas primeiro, programar para a Web é mais do que apenas conhecer o idioma. Em segundo lugar, a capacidade de escrever um código para plataformas diferentes não tem preço. Você pode depurar módulos de aplicativos no Delphi IDE usando seu poderoso depurador e editor e, adicionando as ligações necessárias, pode obter um aplicativo de trabalho pronto para o site. E quando você corrige o erro ou adiciona nova funcionalidade ao aplicativo para Windows, basta recompilar os módulos JavaScript no PAS2JS .


Note-se que, embora o PAS2JS não suporte todos os recursos da linguagem Delphi, eles estão listados no site . Além disso, alguns fragmentos de código PAS2JS aparentemente simples não podem ser transpostos para JavaScript.


Dificuldades de tradução


Portanto, o novo pacote PAS2JS foi baixado do FTP , tentamos recompilar o simples “Hello World” e paramos imediatamente em:


uses System.SysUtils; 

Erro: não foi possível encontrar a unidade "System.SysUtils"

Pacotes PAS2JS prontos, que podem ser encontrados na pasta packages, duplicam parcialmente as unidades do sistema Delphi. Mas eles não têm um prefixo no nome. A solução é simples: remova o prefixo "Sistema". do nome da unidade. O programa é compilado no Delphi (caso contrário, verifique a presença do prefixo “System” no Unit Scope Names, no menu Delphi Project | Options | Delphi Compiler).


Tipo de conversão em constantes


O PAS2JS não suporta conversão de tipo em expressões constantes:


 const CODE_A = Word('a'); 

Erro: expressão constante esperada

No caso de tipos enumerados, você pode tentar alterar, assim:


 const CODE_A = Ord('a'); 

Além disso, o PAS2JS não entende as funções internas dos idiomas Lo e Hi. Na definição de constantes, elas podem ser substituídas da seguinte maneira:


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

Caracteres e seqüências ANSI


Espero que você já tenha mudado para strings Unicode em seus projetos Delphi? Se você deixou algumas das linhas no formato ANSI para economizar memória, elas não serão convertidas para JavaScript: o PAS2JS não conhece os tipos AnsiChar, AnsiString, Utf8String e RawByteString. Considere substituí-los por tipos Unicode ou Byte e Matriz de bytes.


Aqui está um exemplo de substituição do AnsiChar por 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 sem vida ó


Como curiosidade: em polonês, há uma letra ó - O kreskowane, Unicode # $ 00F3. Por alguma razão, o PAS2JS não gostou e, em alguns casos, não pode perceber uma linha se esta carta estiver incluída nela:


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

Declaração de caso


Uma surpresa repentina estava na declaração do caso, na qual o PAS2JS se recusou a aceitar letras russas como opções:


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

A definição de constantes para as letras russas necessárias ajudou:


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

Conclusões


Consegui compilar um pequeno projeto Delphi para a Web, fazendo alterações relativamente pequenas no código fonte do programa e, pelo tempo economizado, escrevi este artigo. Os testes mostraram que ambas as versões do programa: para Windows e para a Web, funcionam exatamente da mesma forma. Sem dúvida, este é um sucesso: agora eu posso desenvolver este projeto finalizando um programa em Delphi e traduzindo-o para JavaScript usando o PAS2JS.


Quanto às pequenas falhas identificadas, tenho certeza que elas serão rapidamente eliminadas. Como o projeto PAS2JS é aberto e gratuito, desenvolvido ativamente pela comunidade Free Pascal .

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


All Articles