Difference between revisions of "pas2js/ru"

From Lazarus wiki
Jump to navigationJump to search
(Added page template. Deleted English category.)
 
(21 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Translate}}
+
{{pas2js(pg)}}
  
__TOC__
 
 
= Pas2js: что это? =
 
= Pas2js: что это? =
  
Line 29: Line 28:
 
</script>
 
</script>
 
</syntaxhighlight>
 
</syntaxhighlight>
pas2js can automatically include this file in the generated output, like this:
+
 
 +
pas2js может автоматически включить этот файл в сгенерированный вывод, например так:
 +
 
 
<pre>
 
<pre>
 
pas2js -Jc -Jirtl.js -Tbrowser hello.pas
 
pas2js -Jc -Jirtl.js -Tbrowser hello.pas
 
</pre>
 
</pre>
For nodejs, the compiler will insert the call to rtl.run() automatically at the end of the generated Javascript file.
 
  
There is a basic Object Pascal RTL, several units from the FPC Packages are also available
+
Для <tt>nodejs</tt> компилятор вставит вызов <tt>rtl.run()</tt> автоматически в конец сгенерированного файла Javascript.
 +
 
 +
Существует базовый Object Pascal RTL, также доступны несколько модулей из пакетов FPC.
 
* system
 
* system
 
* sysutils
 
* sysutils
Line 43: Line 45:
 
* classes
 
* classes
 
* contnrs
 
* contnrs
* DB (yes, TDataset)
+
* DB (да, TDataset)
 
* fpcunit testsuite
 
* fpcunit testsuite
 
* custapp
 
* custapp
 
* restconnection
 
* restconnection
* js (javascript system objects)
+
* js (системные объекты javascript)
* web (browser provided objects)
+
* web (объекты, предоставляемые браузером)
* libjquery (jquery is available too)
+
* libjquery (JQuery также доступен)
* nodejs (basic node runtime environment)
+
* nodejs (среда выполнения базового узла)
 
* typinfo
 
* typinfo
 
* objpas
 
* objpas
* browserconsole (support writeln)
+
* browserconsole (поддержка writeln)
 
* dateutils
 
* dateutils
 
* browserapp
 
* browserapp
 
* nodejsapp
 
* nodejsapp
  
= Where to get it =
+
= Где его взять =
The pas2js compiler and RTL are - naturally - open source and can be downloaded and used freely.
+
Компилятор pas2js и RTL - естественно - с открытым исходным кодом и могут быть загружены и использованы свободно.
  
== Snapshots ==  
+
== Снапшоты ==  
The snapshots contain binaries for Windows (32 and 64bit), Linux (64 bit) and MacOS.
+
Снапшоты содержат двоичные файлы для Windows (32 и 64-разрядная версия), Linux (64-разрядная версия) и MacOS.
  
The snapshots are uploaded to
+
Снапшоты загружены в
 
* ftp://ftpmaster.freepascal.org/fpc/contrib/pas2js
 
* ftp://ftpmaster.freepascal.org/fpc/contrib/pas2js
Every version has a directory with the version number.
+
Каждая версия имеет каталог с номером версии.
A list of changes can be found on the changelog page [[Pas2JS Version Changes]]
+
Список изменений можно найти на странице журнала изменений [[Pas2JS Version Changes]]
  
 
== SVN ==
 
== SVN ==
Line 75: Line 77:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You need [[FPC]] 3.0.4 or better to compile it.
+
Вам нужен [[FPC]] 3.0.4 или старше, чтобы скомпилировать его.
  
Change to the directory and build it with:
+
Перейдите в каталог и соберите его с помощью:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 83: Line 85:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This creates ''compiler/utils/pas2js/pas2js'' (Windows: compiler\utils\pas2js\pas2js.exe)
+
Это создаст ''compiler/utils/pas2js/pas2js'' (Windows: compiler\utils\pas2js\pas2js.exe)
  
= How to use pas2js =
+
= Как использовать pas2js =
  
The command-line arguments are kept mostly the same as the FPC command-line arguments.
+
Аргументы командной строки в основном остаются такими же, как аргументы командной строки FPC. Сообщения об ошибках также в том же формате.
Error messages are also in the same format.
 
  
The compiler needs access to all sources, and so you need to specify the path to the sources of
+
Компилятору необходим доступ ко всем источникам, поэтому вам необходимо указать путь к источникам всех используемых модулей.
all used units.  
 
  
As for the FPC compiler, a configuration file is supported, which has the same syntax as the FPC config file. Note that the snapshots and svn version already contains a default pas2js.cfg with unit search paths (-Fu) for the rtl and fcl.
+
Что касается компилятора FPC, поддерживается файл конфигурации, который имеет тот же синтаксис, что и файл конфигурации FPC. Обратите внимание, что снапшоты и версия svn уже содержат файл pas2js.cfg по умолчанию с путями поиска модулей (-Fu) для rtl и fcl.
  
Basically, the command is the same as any FPC command line. The only thing that is different is the target: ''-Tbrowser'' or ''-Tnodeejs''
+
По сути, команда такая же, как и в любой командной строке FPC. Единственное, что отличается - это цель: '-Tbrowser' или '-Tnodeejs'
  
Here is the complete list of [[pas2js command line arguments|command line arguments]].
+
Вот полный список аргументов командной строки: [[pas2js command line arguments|аргументы командной строки]].
  
== for the browser ==
+
== для браузера ==
Consider the classical:
+
Рассмотрим классику:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
program hello;
 
program hello;
Line 108: Line 108:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
Yes, writeln is supported. Here is how to compile it:
+
Да, writeln поддерживается. Вот как это скомпилировать:
  
 
<pre>
 
<pre>
 
pas2js -Jc -Jirtl.js -Tbrowser hello.pas
 
pas2js -Jc -Jirtl.js -Tbrowser hello.pas
 
</pre>
 
</pre>
When compiled succesfully, the code can be run in the browser by opening a html file in the browser with the following content:
+
После успешной компиляции код можно запустить в браузере, открыв в браузере html-файл со следующим содержимым:
 
<syntaxhighlight lang="html4strict">
 
<syntaxhighlight lang="html4strict">
 
<html>
 
<html>
Line 127: Line 127:
 
</html>
 
</html>
 
</syntaxhighlight>
 
</syntaxhighlight>
The files that are needed are:
+
Необходимые файлы:
 
* hello.html
 
* hello.html
 
* hello.js
 
* hello.js
Whether hello.html is opened by double-clicking it in the explorer or put on a server and opened with an URL, is not relevant for the functioning.
+
Независимо от того, открыт ли hello.html двойным щелчком по нему в проводнике или помещен на сервер и открыт с помощью URL, это не имеет значения.
  
The output is visible in the browser's web developer console.
+
Вывод отображается в консоли веб-разработчика браузера.
By including the browserconsole unit, it will be visible in the browser page:
+
Включив модуль browserconsole, это будет видно на странице браузера:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
program hello;
 
program hello;
Line 144: Line 144:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== for NodeJS ==
+
== для NodeJS ==
 
<pre>
 
<pre>
 
pas2js -Tnodejs hello.pas
 
pas2js -Tnodejs hello.pas
 
</pre>
 
</pre>
When compiled succesfully, the code can be run in node using the following command.
+
После успешной компиляции код можно запустить на узле с помощью следующей команды.
 
<pre>
 
<pre>
 
nodejs hello.js
 
nodejs hello.js
 
</pre>
 
</pre>
  
Note: on MacOS it is "node hello.js"
+
{{Note| в MacOS это "node hello.js"}}
  
 
= Supported syntax elements =
 
= Supported syntax elements =
  
Basically, [[Delphi]] 7 syntax is supported.  
+
В основном, поддерживается синтаксис [[Delphi]] 7. Это включает RTTI.
This includes RTTI.
+
Более подробный список можно найти в источниках файла [https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co translation.html].
A more detailed list can be found in the [https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co translation.html].file in the sources.
 
  
*[[Mode_Delphi|Delphi]] and [[Mode_ObjFPC|ObjFPC]] mode
+
*режим [[Mode_Delphi|Delphi]] и [[Mode_ObjFPC|ObjFPC]]
*[[Program]], [[Unit]]s, namespaces
+
*[[Program]], [[Unit]]s, пространства имен
*unit initialization, but not finalization
+
*инициализация модуля, но не финализация
 
*[[Var]], [[Const]], [[Type]]
 
*[[Var]], [[Const]], [[Type]]
 
*string (unicodestring), char (widechar), [[Boolean]], [[Double]], [[Byte]], [[Shortint]], [[Word]], [[Smallint]], longword, [[Longint]], nativeint(int53), nativeuint(int52), currency
 
*string (unicodestring), char (widechar), [[Boolean]], [[Double]], [[Byte]], [[Shortint]], [[Word]], [[Smallint]], longword, [[Longint]], nativeint(int53), nativeuint(int52), currency
 
*resourcestrings
 
*resourcestrings
*[[Pointer]] (as a reference to a class, array, record, pointer of record, interface, but no pointer arithmetic)
+
*[[Pointer]] (как ссылка на класс, массив, запись, указатель записи, интерфейс, но без арифметики указателя)
*[[Record]] (but no variant records)
+
*[[Record]] (но не variant records)
*[[Function]]s, [[Procedure]]s, nested, anonymous functions
+
*[[Function]]s, [[Procedure]]s, вложенные, анонимные функции
*function types, of object, reference to (closures)
+
*типы функций: of object, reference to (закрытые)
*function arguments: default, const, var, out
+
*аргументы функций: default, const, var, out
 
*[[If]]-then-else
 
*[[If]]-then-else
 
*[[For]]-do
 
*[[For]]-do
Line 185: Line 184:
 
*class type, visibility, virtual, override, abstract, overload, properties, class properties, class var, class const, constructor, destructor
 
*class type, visibility, virtual, override, abstract, overload, properties, class properties, class var, class const, constructor, destructor
 
*class-of
 
*class-of
*nested classes
+
*вложенные классы
*interfaces: CORBA, COM, delegations, method resolution, reference counting, TVirtualInterface
+
*интерфейсы: CORBA, COM, delegations, method resolution, reference counting, TVirtualInterface
*external classes, vars, const
+
*внешние классы, переменные, константы
*Enumeration for..in..do
+
*Энумератор for..in..do
*Type alias, e.g. type TTranslateString = type string;
+
*Псевдоним типа, например, type TTranslateString = type string;
 
*RTTI
 
*RTTI
*asm block for embedding JavaScript directly
+
*asm блок для встраивания в JavaScript напрямую
*compiler directives (e.g. $ifdef, $if, $define, $modeswitch, $R+)
+
*директивы компилятора (e.g. $ifdef, $if, $define, $modeswitch, $R+)
*compile time and run time range checking
+
*проверка времени компиляции и времени выполнения
  
There are some constructs that are naturally not supported and will never be supported:
+
Есть некоторые конструкции, которые естественно не поддерживаются и никогда не будут поддерживаться:
*Anything involving memory pointers and pointer arithmetic.
+
*Все, что связано с указателями памяти и арифметикой указателей.
 
*Variant records
 
*Variant records
  
Details about supported elements and the conversion from Pascal to JavaScript: [https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co translation].
+
Подробно о поддерживаемых элементах и переходе с Pascal на JavaScript: [https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co translation].
  
= Planned language features =
+
= Планируемые языковые особенности =
Basically, the idea is to get the pas2js transpiler up to the same level as FPC or Delphi.  
+
По сути, идея состоит в том, чтобы вывести транспайлер pas2js на тот же уровень, что и FPC или Delphi.  
That means the following needs to be added:
+
Это означает, что необходимо добавить следующее:
* Advanced records
+
* Продвинутые записи(records)
* Runtime checks: Overflow -Co, $Q
+
* Проверка во время выполнения: переполнение(overflow) -Co, $Q
* Generics
+
* Обобщения(дженерики)
* Type helpers
+
* Тип помощников(helpers)
* Array of const
+
* Массив констант
  
Needless to say, anything requiring direct memory access is not going to be supported.
+
Излишне говорить, что все, что требует прямого доступа к памяти, не будет поддерживаться.
  
= Other not implemented features =
+
= Другие не реализованные функции =
  
*Attributes
+
*Атрибуты
*Enums with custom values
+
*Перечисления с пользовательскими значениями
*Global properties
+
*Глобальные свойства
 
*Futures
 
*Futures
*Helpers for types, classes, records
+
*Помощники(helpers) для типов, классов, записей
 
*Inline
 
*Inline
*Library
+
*Библиотека
*Objects
+
*Объекты
*Operator overloading
+
*Перегрузка оператора
*Pointer arithmetic
+
*Арифметика указателей
*Resources
+
*Ресурсы
*RTTI extended, $RTTI
+
*Расширение RTTI, $RTTI
*Variant records
+
*Вариантные записи(records)
*Variants
+
*Варианты(variants)
  
= Lazarus integration of pas2js =
+
= Интеграция pas2js в Lazarus =
  
Lazarus understands the concept of external classes as used by pas2js, so code completion will work.
+
Lazarus понимает концепцию внешних классов, используемую pas2js, поэтому автозавершение кода будет работать.
  
Since Lazarus 1.9 the IDE can use pas2js.exe as a normal compiler.
+
Начиная с Lazarus 1.9, среда IDE может использовать pas2js.exe в качестве обычного компилятора.
  
The integration is described here: [[lazarus pas2js integration]].
+
Интеграция описана здесь: [[lazarus pas2js integration/ru|Интеграция pas2JS в Lazarus]].
It is still under construction, but deep integration with lazarus is planned.
+
Он все еще находится в стадии разработки, но планируется глубокая интеграция с Lazarus.
  
= Importing Javascript classes =
+
= Импорт классов Javascript =
  
To import a javascript class, one writes a normal class definition that mimics the Javascript class.
+
Чтобы импортировать класс javascript, нужно написать обычное определение класса, которое имитирует класс Javascript.
It is possible to use properties. Many examples can be found in the JS, web, nodejs and libjquery units.
+
Можно использовать свойства. Многие примеры можно найти в модулях JS, web, nodejs и libjquery.
  
Here is a simple example:
+
Вот простой пример:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
   TJSFunction = class external name 'Function'(TJSObject)
 
   TJSFunction = class external name 'Function'(TJSObject)
Line 259: Line 258:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This declares the <code>TJSFunction</code> object : in Javascript, functions are objects.  
+
[Приведенный выше код] объявляет объект <code>TJSFunction</code>: в Javascript функции являются объектами.
* The "<code>external name 'Function'</code>" means that you declare a Javascript class where the Javascript name of the class is 'Function'.
+
* "<code>external name 'Function'</code>" означает, что вы объявляете класс Javascript, где именем класса Javascript является 'Function'.
* The <code>(TJSObject)</code> means it descends from <code>TJSObject</code> also an external class. There does not need to be an ancestor type.
+
* <code>(TJSObject)</code> означает, что он наследуется от <code>TJSObject</code> и внешнего класса. Там не должно быть типа предка.
* Fields are declared just as in Pascal.
+
* Поля объявлены так же, как в Паскале.
* To declare read-only fields, a trick can be used:</b> declare the field using an <var>external name "thename"</code> modifier, and declare a read-only property with the same name.<br>(see the length declaration)
+
* Чтобы объявить поля только для чтения, можно использовать хитрость: объявите поле с использованием модификатора <code>external name "thename"</code> и объявите свойство только для чтения с тем же именем (см. length declaration)
* <code>Varargs</code> can be used to indicate that a function accepts any number of arguments.
+
* <code>Varargs</code> может использоваться, чтобы указать, что функция принимает любое количество аргументов.
* <code>JSValue</code> can be used to indicate an unknown type. <br/>It is more or less equivalent to a Variant.
+
* <code>JSValue</code> может использоваться для указания неизвестного типа. Это более или менее эквивалентно типу Variant.
  
= Create simple JS objects with the new function =
+
= Создание простых объектов JS с новой функцией =
  
Some JS-framework functions expect an JS object as parameter. Here is how to do that in Pascal using the ''new'' function from unit ''JS'':
+
Некоторые функции JS-фреймворка ожидают JS-объект в качестве параметра. Вот как это сделать в Pascal, используя функцию ''new'' из модуля ''JS'':
  
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
Line 281: Line 280:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You can nest it to create sub objects:
+
Вы можете вложить его для создания субобъектов:
  
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
Line 293: Line 292:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You can use TJSArray._of to create JS arrays on the fly:
+
Вы можете использовать <tt>TJSArray._of</tt> для создания JS-массивов "на лету":
  
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
Line 305: Line 304:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
= Debugging =
+
= Отладка =
The generated Javascript source code is of course visible and debuggable in the browser.  
+
Сгенерированный исходный код Javascript, конечно, видим и доступен отладке в браузере.  
  
Moreover, the transpiler can generate a source map, which means that you will be able to see and debug the Pascal code in the browser.
+
Более того, транспайлер может генерировать  файл-маппер ([[User:Zoltanleo|прим.перев]]: это минифицированный/объединённый файл, связанный с файлами, из которых он получился), что означает, что вы сможете увидеть и отладить код Pascal в браузере (будет работать не [абсолютно] все, но многое. Это зависит [еще] и от браузера.)
(not everything will work, but many things do. This depends on the browser too.)
 
  
A source map can be generated using the command-line parameter
+
файл-маппер может быть сгенерирован с использованием параметра командной строки
 
<pre>
 
<pre>
 
-Jm
 
-Jm
 
</pre>
 
</pre>
  
The easiest is to include the Pascal sources in the source map
+
Проще всего включать исходники Pascal в файл-маппер
 
<pre>
 
<pre>
 
-Jminclude
 
-Jminclude
Line 322: Line 320:
  
 
You can tell the compiler to store all file names relative to a local base directory:
 
You can tell the compiler to store all file names relative to a local base directory:
 +
Вы можете указать компилятору хранить все имена файлов в [путях] относительно локального базового каталога:
 
<pre>
 
<pre>
 
-Jmbasedir=DirName
 
-Jmbasedir=DirName
 
</pre>
 
</pre>
  
And you can store an URL in the map, so the browser will use URL/above-relative-file-name to get the source:
+
И вы можете сохранять URL-адрес на карте, поэтому браузер будет использовать URL/вышеуказанное-относительное-имя-файла, чтобы получать исходный код:
 
<pre>
 
<pre>
 
-Jmsourceroot=URL
 
-Jmsourceroot=URL
 
</pre>
 
</pre>
  
= Bugs =
+
= Баги =
  
Please report bugs in the FPC bugtracker with category ''pas2js'': http://bugs.freepascal.org
+
Пожалуйста, сообщайте об ошибках в багтрекере FPC в категории ''pas2js'': http://bugs.freepascal.org
  
= Examples =
+
= Примеры =
  
*Time Tracking Application: https://www.devstructor.com/demos/pas2js-time/source.zip  (sources: https://www.devstructor.com/demos/pas2js-time/source.zip)
+
*Приложение для отслеживания времени: (исходный код: https://www.devstructor.com/demos/pas2js-time/source.zip)
*Drawing and animation on canvas: http://ragnemalm.se/images/santa/santa.html (sources: http://ragnemalm.se/images/santa/)
+
*Рисование и анимация на холсте: http://ragnemalm.se/images/santa/santa.html (исходный код: http://ragnemalm.se/images/santa/)
 
*WebGL: https://github.com/genericptr/Pas2JS-WebGL#pas2js-webgl
 
*WebGL: https://github.com/genericptr/Pas2JS-WebGL#pas2js-webgl
  
= Lazarus Widgetset =
+
= Виджеты Lazarus =
The ultimate goal is of course to have the LCL running in the web. Discussions on this topic are  delegated to a separate page. [[pas2js_widgetsets]]
+
Конечная цель, конечно, - запустить LCL в Всемирной сети. Обсуждения по этой теме делегированы на отдельной странице. [[pas2js_widgetsets]]
  
= FAQ =
+
= ЧаВо =
  
== Why is a simple hello world program so big? ==
+
== Почему простая программа "hello world" такая большая? ==
  
This is mainly due to the used rtl.js. The rtl.js contains code for Pascal modules, classes, RTTI, sets, range checks, etc and is written with big WebApps in mind, not for scripts with a few lines of code.
+
Это в основном связано с использованием rtl.js. Файл rtl.js содержит код для паскалевских модулей, классов, RTTI, наборов, проверок диапазона и т.д., и написан с учетом больших WebApp, а не для сценариев с несколькими строками кода.
  
# You can use a Javascript [[pas2js minifier|minifier]] to reduce the created Javascript
+
# Вы можете использовать Javascript [[pas2js minifier|minifier ("минимизатор")]], чтобы уменьшить созданный Javascript
# You can create your own minified rtl.js by removing all functions you don't need. Eventually this will be done automatically by pas2js.
+
# Вы можете создать свой собственный "минимизатор" rtl.js, удалив все ненужные вам функции. В конечном итоге это будет сделано автоматически pas2js.
  
[[Category:Pas2js]]
 
  
== Why are asm blocks bad? ==
+
== Почему [нежелательно] применение asm-вставок? ==
  
Asm blocks are useful for things you cannot do with pas2js. But there are some downsides:
+
Asm-вставки полезны для вещей, которые вы не можете сделать с [помощью] pas2js. Но есть некоторые недостатки:
pas2js does not parse the JS. Neither does it check the syntax, nor does it know what Pascal identifiers the code is referencing. That means any identifier only accessed by the asm block will be removed by the pas2js' optimizer.
+
pas2js не разбирает JS. Он также не проверяет синтаксис и не знает, на какие идентификаторы Паскаля ссылается код. Это означает, что любой идентификатор, доступный только блоку asm, будет удален оптимизатором pas2js.
  
Therefore always try to do it in Pascal. Remember you can typecast values to JSValue, objects to TJSObject, arrays to TJSArray, strings to TJSString, etc to use almost all JS features.
+
Поэтому всегда старайтесь делать это на Паскале. Помните, что вы можете типизировать значения в JSValue, объекты в TJSObject, массивы в TJSArray, строки в TJSString и т.д., чтобы использовать почти все функции JS.
  
== Why not parse asm blocks? ==
+
== Почему не парсятся(разбираются) asm-вставки? ==
  
Any compiletime JS parser can only do a syntax check and parse only simple JS. But since simple JS can be better written in Pascal, it is somewhat pointless and has therefore low priority.
+
Любой анализатор JS времени компиляции может выполнять только проверку синтаксиса и анализировать только простые JS. Но так как простой JS может быть лучше написан на Паскале, это несколько бессмысленно и поэтому имеет низкий приоритет.

Latest revision as of 20:47, 28 May 2022

English (en) русский (ru)

Pas2js: что это?

Компилятор

Pas2js - это транспилер(транскомпилятор) [кода] Pascal в JavaScript. Он парсит Object Pascal и выдает JavaScript. JavaScript в настоящее время имеет уровень ECMAScript 5 и должен запускаться в любом браузере или в Node.js (цель "nodejs"). Доступен в 3 формах:

  • как библиотека
  • как программа командной строки
  • как веб-сервер

Он транскомпилирует [код] из фактических исходников Pascal, у него нет промежуточных файлов .ppu. Это означает, что все исходники должны быть всегда доступны.

Через определения внешних классов компилятор может использовать классы JavaScript:

  • Все классы, доступные во время выполнения JavaScript и в браузере, доступны через модули импорта (сравнимо с модулями windows или unix для собственного компилятора).
  • Для Node.js доступна базовая поддержка среды выполнения nodejs.
  • Доступен модуль импорта для jQuery (libjquery)

RTL

Для работы сгенерированного кода требуется небольшой файл JavaScript: rtl.js. Он определяет объект RTL. Этот объект запустит код Object Pascal, если вы включите вызов rtl.run() на странице HTML.

<script type="application/javascript">
  rtl.run()
</script>

pas2js может автоматически включить этот файл в сгенерированный вывод, например так:

pas2js -Jc -Jirtl.js -Tbrowser hello.pas

Для nodejs компилятор вставит вызов rtl.run() автоматически в конец сгенерированного файла Javascript.

Существует базовый Object Pascal RTL, также доступны несколько модулей из пакетов FPC.

  • system
  • sysutils
  • Math
  • strutils
  • rtlconst
  • classes
  • contnrs
  • DB (да, TDataset)
  • fpcunit testsuite
  • custapp
  • restconnection
  • js (системные объекты javascript)
  • web (объекты, предоставляемые браузером)
  • libjquery (JQuery также доступен)
  • nodejs (среда выполнения базового узла)
  • typinfo
  • objpas
  • browserconsole (поддержка writeln)
  • dateutils
  • browserapp
  • nodejsapp

Где его взять

Компилятор pas2js и RTL - естественно - с открытым исходным кодом и могут быть загружены и использованы свободно.

Снапшоты

Снапшоты содержат двоичные файлы для Windows (32 и 64-разрядная версия), Linux (64-разрядная версия) и MacOS.

Снапшоты загружены в

Каждая версия имеет каталог с номером версии. Список изменений можно найти на странице журнала изменений Pas2JS Version Changes

SVN

svn co https://svn.freepascal.org/svn/projects/pas2js/trunk pas2js

Вам нужен FPC 3.0.4 или старше, чтобы скомпилировать его.

Перейдите в каталог и соберите его с помощью:

make clean all

Это создаст compiler/utils/pas2js/pas2js (Windows: compiler\utils\pas2js\pas2js.exe)

Как использовать pas2js

Аргументы командной строки в основном остаются такими же, как аргументы командной строки FPC. Сообщения об ошибках также в том же формате.

Компилятору необходим доступ ко всем источникам, поэтому вам необходимо указать путь к источникам всех используемых модулей.

Что касается компилятора FPC, поддерживается файл конфигурации, который имеет тот же синтаксис, что и файл конфигурации FPC. Обратите внимание, что снапшоты и версия svn уже содержат файл pas2js.cfg по умолчанию с путями поиска модулей (-Fu) для rtl и fcl.

По сути, команда такая же, как и в любой командной строке FPC. Единственное, что отличается - это цель: '-Tbrowser' или '-Tnodeejs'

Вот полный список аргументов командной строки: аргументы командной строки.

для браузера

Рассмотрим классику:

program hello;

begin
  Writeln('Hello, world!');
end.

Да, writeln поддерживается. Вот как это скомпилировать:

pas2js -Jc -Jirtl.js -Tbrowser hello.pas

После успешной компиляции код можно запустить в браузере, открыв в браузере html-файл со следующим содержимым:

<html>
  <head>
    <meta charset="utf-8"/>
    <script type="application/javascript" src="hello.js"></script>
  </head>
  <body>
    <script type="application/javascript">
     rtl.run();
    </script>
  </body>
</html>

Необходимые файлы:

  • hello.html
  • hello.js

Независимо от того, открыт ли hello.html двойным щелчком по нему в проводнике или помещен на сервер и открыт с помощью URL, это не имеет значения.

Вывод отображается в консоли веб-разработчика браузера. Включив модуль browserconsole, это будет видно на странице браузера:

program hello;

uses browserconsole;

begin
  Writeln('Hello, world!');
end.

для NodeJS

pas2js -Tnodejs hello.pas

После успешной компиляции код можно запустить на узле с помощью следующей команды.

nodejs hello.js
Light bulb  Примечание: в MacOS это "node hello.js"

Supported syntax elements

В основном, поддерживается синтаксис Delphi 7. Это включает RTTI. Более подробный список можно найти в источниках файла translation.html.

  • режим Delphi и ObjFPC
  • Program, Units, пространства имен
  • инициализация модуля, но не финализация
  • Var, Const, Type
  • string (unicodestring), char (widechar), Boolean, Double, Byte, Shortint, Word, Smallint, longword, Longint, nativeint(int53), nativeuint(int52), currency
  • resourcestrings
  • Pointer (как ссылка на класс, массив, запись, указатель записи, интерфейс, но без арифметики указателя)
  • Record (но не variant records)
  • Functions, Procedures, вложенные, анонимные функции
  • типы функций: of object, reference to (закрытые)
  • аргументы функций: default, const, var, out
  • If-then-else
  • For-do
  • Repeat-until
  • While-do
  • With-do
  • try-finally
  • try-except
  • enums
  • sets
  • arrays static, dynamic, open, multi dimensionals
  • String like array operations: a:=[1,2,3]+[1,1];
  • class type, visibility, virtual, override, abstract, overload, properties, class properties, class var, class const, constructor, destructor
  • class-of
  • вложенные классы
  • интерфейсы: CORBA, COM, delegations, method resolution, reference counting, TVirtualInterface
  • внешние классы, переменные, константы
  • Энумератор for..in..do
  • Псевдоним типа, например, type TTranslateString = type string;
  • RTTI
  • asm блок для встраивания в JavaScript напрямую
  • директивы компилятора (e.g. $ifdef, $if, $define, $modeswitch, $R+)
  • проверка времени компиляции и времени выполнения

Есть некоторые конструкции, которые естественно не поддерживаются и никогда не будут поддерживаться:

  • Все, что связано с указателями памяти и арифметикой указателей.
  • Variant records

Подробно о поддерживаемых элементах и переходе с Pascal на JavaScript: translation.

Планируемые языковые особенности

По сути, идея состоит в том, чтобы вывести транспайлер pas2js на тот же уровень, что и FPC или Delphi. Это означает, что необходимо добавить следующее:

  • Продвинутые записи(records)
  • Проверка во время выполнения: переполнение(overflow) -Co, $Q
  • Обобщения(дженерики)
  • Тип помощников(helpers)
  • Массив констант

Излишне говорить, что все, что требует прямого доступа к памяти, не будет поддерживаться.

Другие не реализованные функции

  • Атрибуты
  • Перечисления с пользовательскими значениями
  • Глобальные свойства
  • Futures
  • Помощники(helpers) для типов, классов, записей
  • Inline
  • Библиотека
  • Объекты
  • Перегрузка оператора
  • Арифметика указателей
  • Ресурсы
  • Расширение RTTI, $RTTI
  • Вариантные записи(records)
  • Варианты(variants)

Интеграция pas2js в Lazarus

Lazarus понимает концепцию внешних классов, используемую pas2js, поэтому автозавершение кода будет работать.

Начиная с Lazarus 1.9, среда IDE может использовать pas2js.exe в качестве обычного компилятора.

Интеграция описана здесь: Интеграция pas2JS в Lazarus. Он все еще находится в стадии разработки, но планируется глубокая интеграция с Lazarus.

Импорт классов Javascript

Чтобы импортировать класс javascript, нужно написать обычное определение класса, которое имитирует класс Javascript. Можно использовать свойства. Многие примеры можно найти в модулях JS, web, nodejs и libjquery.

Вот простой пример:

  TJSFunction = class external name 'Function'(TJSObject)
  private
    Flength: NativeInt external name 'length';
    Fprototyp: TJSFunction external name 'prototyp';
  public
    name: String;
    property prototyp: TJSFunction read Fprototyp;
    property length: NativeInt read Flength;
    function apply(thisArg: TJSObject; const ArgArray: TJSValueDynArray): JSValue; varargs;
    function bind(thisArg: TJSObject): JSValue; varargs;
    function call(thisArg: TJSObject): JSValue; varargs;
  end;

[Приведенный выше код] объявляет объект TJSFunction: в Javascript функции являются объектами.

  • "external name 'Function'" означает, что вы объявляете класс Javascript, где именем класса Javascript является 'Function'.
  • (TJSObject) означает, что он наследуется от TJSObject и внешнего класса. Там не должно быть типа предка.
  • Поля объявлены так же, как в Паскале.
  • Чтобы объявить поля только для чтения, можно использовать хитрость: объявите поле с использованием модификатора external name "thename" и объявите свойство только для чтения с тем же именем (см. length declaration)
  • Varargs может использоваться, чтобы указать, что функция принимает любое количество аргументов.
  • JSValue может использоваться для указания неизвестного типа. Это более или менее эквивалентно типу Variant.

Создание простых объектов JS с новой функцией

Некоторые функции JS-фреймворка ожидают JS-объект в качестве параметра. Вот как это сделать в Pascal, используя функцию new из модуля JS:

// JavaScript:
DoIt({name:"Fred", id:3, size:4.3});
// Pascal;
DoIt(new(['name','Fred', 'id',3, 'size',4.3]));

Вы можете вложить его для создания субобъектов:

// JavaScript:
DoIt({name:"Fred", size:{width:3,height:2}});
// Pascal;
DoIt(new(['name','Fred', 'size',new(['width',3, 'height',2])]));

Вы можете использовать TJSArray._of для создания JS-массивов "на лету":

// JavaScript:
DoIt({numbers:[1,2,3]});
// Pascal;
DoIt(new(['numbers',TJSArray._of(1,2,3)]));

Отладка

Сгенерированный исходный код Javascript, конечно, видим и доступен отладке в браузере.

Более того, транспайлер может генерировать файл-маппер (прим.перев: это минифицированный/объединённый файл, связанный с файлами, из которых он получился), что означает, что вы сможете увидеть и отладить код Pascal в браузере (будет работать не [абсолютно] все, но многое. Это зависит [еще] и от браузера.)

файл-маппер может быть сгенерирован с использованием параметра командной строки

-Jm

Проще всего включать исходники Pascal в файл-маппер

-Jminclude

You can tell the compiler to store all file names relative to a local base directory: Вы можете указать компилятору хранить все имена файлов в [путях] относительно локального базового каталога:

-Jmbasedir=DirName

И вы можете сохранять URL-адрес на карте, поэтому браузер будет использовать URL/вышеуказанное-относительное-имя-файла, чтобы получать исходный код:

-Jmsourceroot=URL

Баги

Пожалуйста, сообщайте об ошибках в багтрекере FPC в категории pas2js: http://bugs.freepascal.org

Примеры

Виджеты Lazarus

Конечная цель, конечно, - запустить LCL в Всемирной сети. Обсуждения по этой теме делегированы на отдельной странице. pas2js_widgetsets

ЧаВо

Почему простая программа "hello world" такая большая?

Это в основном связано с использованием rtl.js. Файл rtl.js содержит код для паскалевских модулей, классов, RTTI, наборов, проверок диапазона и т.д., и написан с учетом больших WebApp, а не для сценариев с несколькими строками кода.

  1. Вы можете использовать Javascript minifier ("минимизатор"), чтобы уменьшить созданный Javascript
  2. Вы можете создать свой собственный "минимизатор" rtl.js, удалив все ненужные вам функции. В конечном итоге это будет сделано автоматически pas2js.


Почему [нежелательно] применение asm-вставок?

Asm-вставки полезны для вещей, которые вы не можете сделать с [помощью] pas2js. Но есть некоторые недостатки: pas2js не разбирает JS. Он также не проверяет синтаксис и не знает, на какие идентификаторы Паскаля ссылается код. Это означает, что любой идентификатор, доступный только блоку asm, будет удален оптимизатором pas2js.

Поэтому всегда старайтесь делать это на Паскале. Помните, что вы можете типизировать значения в JSValue, объекты в TJSObject, массивы в TJSArray, строки в TJSString и т.д., чтобы использовать почти все функции JS.

Почему не парсятся(разбираются) asm-вставки?

Любой анализатор JS времени компиляции может выполнять только проверку синтаксиса и анализировать только простые JS. Но так как простой JS может быть лучше написан на Паскале, это несколько бессмысленно и поэтому имеет низкий приоритет.