从Pascal到JavaScript的PAS2JS转译器:与Delphi和解决方法不兼容

如今,一台功能强大的个人计算机装在一个普通人的口袋中,您只能在10到20年前就梦想着。 而且,如果您有数以百计的经过调试的Windows代码以及用Delphi编写的可以完美运行的应用程序和实用程序,那么您肯定会想将这些财富用于移动开发。 以及在Windows下进行编程时获得的经验。 PAS2JS将帮助您结合两个世界:Windows开发以及Web应用程序和Node.js模块的创建。


本文讨论了一些从个人经验中发现的困难。


为什么不只是学习JavaScript并在其上编写Web应用程序呢?


我已经足够了解JavaScript。 但是首先,Web编程不仅仅是了解语言。 其次,为不同平台编写一个代码的能力是无价的。 您可以使用其强大的调试器和编辑器在Delphi IDE中调试应用程序模块,然后添加必要的绑定,以获取该站点的现成的工作应用程序。 而且,当您纠正错误或为Windows应用程序添加新功能时,仅重新编译PAS2JS中的JavaScript模块就足够了


应该注意的是,尽管PAS2JS不支持Delphi语言的所有功能,但它们在网站上列出。 同样,看似简单的PAS2JS代码的某些片段也无法转换为JavaScript。


翻译困难


因此,从FTP下载了新的PAS2JS软件包,我们尝试重新编译简单的“ Hello World”,然后立即停止在:


uses System.SysUtils; 

错误:找不到单元“ System.SysUtils”

现成的PAS2JS软件包(可在packages文件夹中找到)部分复制了Delphi系统单元。 但是它们的名称中没有前缀。 解决方案很简单:删除前缀“ System”。 从单位名称开始。 该程序在Delphi中编译(如果不是,请在Delphi项目|选项| Delphi编译器菜单中检查“单元作用域名称”中是否存在“系统”前缀)。


常量类型转换


PAS2JS不支持常量表达式中的类型转换:


 const CODE_A = Word('a'); 

错误:预期为常数运算式

对于枚举类型,可以尝试进行更改,这是这样的:


 const CODE_A = Ord('a'); 

另外,PAS2JS不理解Lo和Hi语言的内置功能。 在常量的定义中,可以按以下方式替换它们:


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

ANSI字符和字符串


我希望您已经在Delphi项目中切换到Unicode字符串了吗? 如果为了节省内存而以ANSI格式保留了某些行,则这些行将不会转换为JavaScript:PAS2JS不知道AnsiChar,AnsiString,Utf8String和RawByteString类型。 考虑用Unicode类型或Byte和Byte Array替换它们。


这是用字节替换AnsiChar的示例:


 //  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; 

没有生气的信件


出于好奇:波兰语中有一个字母ó-O kreskowane,Unicode#$ 00F3。 由于某些原因,PAS2JS不喜欢它,并且在某些情况下,如果其中包含此字母,它将无法感知到一行:


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

案例陈述


案例声明突然令人惊讶,其中PAS2JS拒绝接受俄语字母作为选项:


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

必要的俄语字母常量的定义有助于:


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

结论


我设法为Web编译了一个小型的Delphi项目,对该程序的源代码进行了较小的更改,并节省了我写这篇文章的时间。 测试表明,该程序的两个版本:Windows和Web都完全相同。 毫无疑问,这是成功的:现在,我可以通过在Delphi中完成程序,然后使用PAS2JS将其转换为JavaScript来开发该项目。


至于确定的微小缺陷,我相信它们会很快消除。 由于PAS2JS项目是开放和免费的,因此由Free Pascal社区积极开发。

Source: https://habr.com/ru/post/zh-CN436920/


All Articles