PAS2JS Transporter from Pascal to JavaScript: Delphi incompatibilities and workarounds
Nowadays, in the pocket of an ordinary person lies a powerful personal computer, which 10-20 years ago could only be dreamed of. And if you have kilometers of debugged Windows code and perfectly working applications and utilities written in Delphi, you probably would like to use this wealth for mobile development. As well as the experience gained during programming under Windows. PAS2JS will help you to combine two worlds: development for Windows and the creation of Web applications and Node.js modules.
Some of the difficulties found from personal experience are discussed in this article.
Why not just learn JavaScript and write Web applications on it?
I learned the javascript language sufficiently. But first, programming for the Web is more than just language skills. Secondly, the ability to write one code for different platforms is priceless. You can debug application modules in Delphi IDE, using its powerful debugger and editor, and then, adding the necessary binding, get a ready-made application for the site. And when you correct the error or add new functionality to the application for Windows, it will be enough just to recompile the JavaScript modules in PAS2JS .
It should be noted that while PAS2JS does not support all the features of the Delphi language, they are listed on the site . Also, some fragments of seemingly simple PAS2JS code cannot transpose into JavaScript.
Translation difficulties
So, the fresh PAS2JS package is downloaded from FTP , we try to recompile a simple “Hello world”, and immediately stop at:
uses
System.SysUtils;
Error: can't find unit "System.SysUtils"
Ready-made PAS2JS packages, which can be found in the packages folder, partially duplicate Delphi system units. But they do not have a prefix in the name. The solution is simple: we delete the “System.” Prefix from the unit name. A program in Delphi is compiled (if not, check the presence of the “System” prefix in the Unit Scope Names, in the Delphi Project | Options | Delphi Compiler menu).
Type reduction in constants
PAS2JS does not support type conversion in constant expressions:
const
CODE_A = Word('a');
Error: Constant expression expected
In the case of enumerated types, you can try to change it, so it passes:
const
CODE_A = Ord('a');
Also, PAS2JS does not understand the built-in functions of the Lo and Hi languages. In the definition of constants they can be replaced as follows:
const
LO_BYTE = $1234and $FF; // Lo($1234);
HI_BYTE = $1234shr8;// Hi($1234);
ANSI characters and strings
I hope you have switched to Unicode strings in your Delphi projects? If you have left part of the strings in ANSI format in order to save memory, they will not be converted to JavaScript: PAS2JS does not know the types AnsiChar, AnsiString, Utf8String and RawByteString. Consider replacing them with Unicode types, or Byte and Array of Byte.
Here is an example of replacing AnsiChar with Byte:
// БылоprocedureTestAnsiCharAndByte1;const
SMALL_ENG_LETTERS = ['a'..'z'];
CAPITAL_ENG_LETTERS = ['A'..'Z'];
var
ch: AnsiChar;
engs: setof AnsiChar;
begin
engs := SMALL_ENG_LETTERS + CAPITAL_ENG_LETTERS;
ch := 'Z';
if ch in engs then
Writeln('It''s an English letter');
end;
// СталоprocedureTestAnsiCharAndByte2;const
SMALL_ENG_LETTERS = [Ord('a')..Ord('z')];
CAPITAL_ENG_LETTERS = [Ord('A')..Ord('Z')];
var
ch: Byte;
engs: setof Byte;
begin
engs := SMALL_ENG_LETTERS + CAPITAL_ENG_LETTERS;
ch := Ord('Z');
if ch in engs then
Writeln('It''s an English letter');
end;
The unsubstantiated letter ó
As a curiosity: in Polish there is the letter ó - O kreskowane, Unicode # $ 00F3. For some reason, PAS2JS disliked it, and in some cases can not take a string if it includes this letter:
var
s: string;
begin
s := #$00F3'abdef'; // Компилируется
s := 'abdef'#$017C; // Компилируется
s := #$00F3'abdef'#$017C; // Error: Illegal character
s := #$00F3; s := s + 'abdef'#$017C; // Так снова компилируетсяend;
Case operator
A sudden surprise came up in the case statement, in which PAS2JS refused to accept Russian letters as options:
ch := 'Я';
case ch of'А': Writeln('Это "А"'); // Error: Incompatible types: got "Char" expected "Char" (???)'Б'..'Я': Writeln('Это другая русская буква'); // Error: char expected, but string foundend;
The definition of constants for the desired Russian letters helped:
const
ckbA = #$410; // А
ckbB = #$411; // Б
ckbYa = #$42F; // Яvar
ch: Char;
begin
ch := 'Я';
case ch of
ckbA: Writeln('Это "А"');
ckbB..ckbYa: Writeln('Это другая русская буква');
end;
findings
I managed to compile a small Delphi project for the Web, making relatively small changes to the source code of the program, and for the time saved I wrote this article. Testing has shown that both versions of the program: for Windows and for the Web, work in exactly the same way. This is undoubtedly a success: now I can develop this project, modifying the program in Delphi, and transpiling it into JavaScript using PAS2JS.
As for the minor shortcomings revealed, I am sure they will be quickly eliminated. Since the project PAS2JS - open and free, actively developed by the community Free Pascal .
Only registered users can participate in the survey. Sign in , please.