Sign in Join
Wiki copytemporary

pas2js/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: pas2js/ru

OldNewLine
1+# Pas2js: что это?
2+
3+## Компилятор
4+
5+Pas2js - это транспилер(транскомпилятор) \[кода\] [[Pascal]] в [[JavaScript/ru|JavaScript]]. Он парсит Object Pascal и выдает JavaScript. JavaScript в настоящее время имеет уровень ECMAScript 5 и должен запускаться в любом браузере или в Node.js (цель "nodejs"). Доступен в 3 формах:
6+
7+- как библиотека
8+- как программа командной строки
9+- как веб-сервер
10+
11+Он транскомпилирует \[код\] из фактических исходников Pascal, у него нет промежуточных файлов .ppu. Это означает, что все исходники должны быть всегда доступны.
12+
13+Через определения внешних классов компилятор может использовать классы JavaScript:
14+
15+- Все классы, доступные во время выполнения JavaScript и в браузере, доступны через модули импорта (сравнимо с модулями windows или unix для собственного компилятора).
16+- Для Node.js доступна базовая поддержка среды выполнения nodejs.
17+- Доступен модуль импорта для jQuery (libjquery)
18+
19+## RTL
20+
21+Для работы сгенерированного кода требуется небольшой файл JavaScript: rtl.js. Он определяет объект RTL. Этот объект запустит код Object Pascal, если вы включите вызов `rtl.run()` на странице [[HTML]].
22+
23+```html4strict
24+<script type="application/javascript">
25+ rtl.run()
26+</script>
27+```
28+
29+pas2js может автоматически включить этот файл в сгенерированный вывод, например так:
30+
31+ pas2js -Jc -Jirtl.js -Tbrowser hello.pas
32+
33+Для `nodejs` компилятор вставит вызов `rtl.run()` автоматически в конец сгенерированного файла Javascript.
34+
35+Существует базовый Object Pascal RTL, также доступны несколько модулей из пакетов FPC.
36+
37+- system
38+- sysutils
39+- Math
40+- strutils
41+- rtlconst
42+- classes
43+- contnrs
44+- DB (да, TDataset)
45+- fpcunit testsuite
46+- custapp
47+- restconnection
48+- js (системные объекты javascript)
49+- web (объекты, предоставляемые браузером)
50+- libjquery (JQuery также доступен)
51+- nodejs (среда выполнения базового узла)
52+- typinfo
53+- objpas
54+- browserconsole (поддержка writeln)
55+- dateutils
56+- browserapp
57+- nodejsapp
58+
59+# Где его взять
60+
61+Компилятор pas2js и RTL - естественно - с открытым исходным кодом и могут быть загружены и использованы свободно.
62+
63+## Снапшоты
64+
65+Снапшоты содержат двоичные файлы для Windows (32 и 64-разрядная версия), Linux (64-разрядная версия) и MacOS.
66+
67+Снапшоты загружены в
68+
69+- <ftp://ftpmaster.freepascal.org/fpc/contrib/pas2js>
70+
71+Каждая версия имеет каталог с номером версии. Список изменений можно найти на странице журнала изменений [[Pas2JS Version Changes]]
72+
73+## SVN
74+
75+``` bash
76+svn co https://svn.freepascal.org/svn/projects/pas2js/trunk pas2js
77+```
78+
79+Вам нужен [[FPC]] 3.0.4 или старше, чтобы скомпилировать его.
80+
81+Перейдите в каталог и соберите его с помощью:
82+
83+``` bash
84+make clean all
85+```
86+
87+Это создаст *compiler/utils/pas2js/pas2js* (Windows: compiler\utils\pas2js\pas2js.exe)
88+
89+# Как использовать pas2js
90+
91+Аргументы командной строки в основном остаются такими же, как аргументы командной строки FPC. Сообщения об ошибках также в том же формате.
92+
93+Компилятору необходим доступ ко всем источникам, поэтому вам необходимо указать путь к источникам всех используемых модулей.
94+
95+Что касается компилятора FPC, поддерживается файл конфигурации, который имеет тот же синтаксис, что и файл конфигурации FPC. Обратите внимание, что снапшоты и версия svn уже содержат файл pas2js.cfg по умолчанию с путями поиска модулей (-Fu) для rtl и fcl.
96+
97+По сути, команда такая же, как и в любой командной строке FPC. Единственное, что отличается - это цель: '-Tbrowser' или '-Tnodeejs'
98+
99+Вот полный список аргументов командной строки: [[pas2js command line arguments|аргументы командной строки]].
100+
101+## для браузера
102+
103+Рассмотрим классику:
104+
105+``` pascal
106+program hello;
107+
108+begin
109+ Writeln('Hello, world!');
110+end.
111+```
112+
113+Да, writeln поддерживается. Вот как это скомпилировать:
114+
115+ pas2js -Jc -Jirtl.js -Tbrowser hello.pas
116+
117+После успешной компиляции код можно запустить в браузере, открыв в браузере html-файл со следующим содержимым:
118+
119+```html4strict
120+<html>
121+ <head>
122+ <meta charset="utf-8"/>
123+ <script type="application/javascript" src="hello.js"></script>
124+ </head>
125+ <body>
126+ <script type="application/javascript">
127+ rtl.run();
128+ </script>
129+ </body>
130+</html>
131+```
132+
133+Необходимые файлы:
134+
135+- hello.html
136+- hello.js
137+
138+Независимо от того, открыт ли hello.html двойным щелчком по нему в проводнике или помещен на сервер и открыт с помощью URL, это не имеет значения.
139+
140+Вывод отображается в консоли веб-разработчика браузера. Включив модуль browserconsole, это будет видно на странице браузера:
141+
142+``` pascal
143+program hello;
144+
145+uses browserconsole;
146+
147+begin
148+ Writeln('Hello, world!');
149+end.
150+```
151+
152+## для NodeJS
153+
154+ pas2js -Tnodejs hello.pas
155+
156+После успешной компиляции код можно запустить на узле с помощью следующей команды.
157+
158+ nodejs hello.js
159+
160+> **Note:** в MacOS это "node hello.js"
161+
162+# Supported syntax elements
163+
164+В основном, поддерживается синтаксис [[Delphi]] 7. Это включает RTTI. Более подробный список можно найти в источниках файла [translation.html](https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co).
165+
166+- режим [[Mode Delphi|Delphi]] и [[Mode ObjFPC|ObjFPC]]
167+- [[Program]], [[Unit|Units]], пространства имен
168+- инициализация модуля, но не финализация
169+- [[Var]], [[Const]], [[Type]]
170+- string (unicodestring), char (widechar), [[Boolean]], [[Double]], [[Byte]], [[Shortint]], [[Word]], [[Smallint]], longword, [[Longint]], nativeint(int53), nativeuint(int52), currency
171+- resourcestrings
172+- [[Pointer]] (как ссылка на класс, массив, запись, указатель записи, интерфейс, но без арифметики указателя)
173+- [[Record]] (но не variant records)
174+- [[Function|Functions]], [[Procedure|Procedures]], вложенные, анонимные функции
175+- типы функций: of object, reference to (закрытые)
176+- аргументы функций: default, const, var, out
177+- [[If]]-then-else
178+- [[For]]-do
179+- [[Repeat]]-until
180+- [[While]]-do
181+- [[With]]-do
182+- try-finally
183+- try-except
184+- enums
185+- sets
186+- arrays static, dynamic, open, multi dimensionals
187+- String like array operations: *a:=\[1,2,3\]+\[1,1\];*
188+- class type, visibility, virtual, override, abstract, overload, properties, class properties, class var, class const, constructor, destructor
189+- class-of
190+- вложенные классы
191+- интерфейсы: CORBA, COM, delegations, method resolution, reference counting, TVirtualInterface
192+- внешние классы, переменные, константы
193+- Энумератор for..in..do
194+- Псевдоним типа, например, type TTranslateString = type string;
195+- RTTI
196+- asm блок для встраивания в JavaScript напрямую
197+- директивы компилятора (e.g. \$ifdef, \$if, \$define, \$modeswitch, \$R+)
198+- проверка времени компиляции и времени выполнения
199+
200+Есть некоторые конструкции, которые естественно не поддерживаются и никогда не будут поддерживаться:
201+
202+- Все, что связано с указателями памяти и арифметикой указателей.
203+- Variant records
204+
205+Подробно о поддерживаемых элементах и переходе с Pascal на JavaScript: [translation](https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co).
206+
207+# Планируемые языковые особенности
208+
209+По сути, идея состоит в том, чтобы вывести транспайлер pas2js на тот же уровень, что и FPC или Delphi. Это означает, что необходимо добавить следующее:
210+
211+- Продвинутые записи(records)
212+- Проверка во время выполнения: переполнение(overflow) -Co, \$Q
213+- Обобщения(дженерики)
214+- Тип помощников(helpers)
215+- Массив констант
216+
217+Излишне говорить, что все, что требует прямого доступа к памяти, не будет поддерживаться.
218+
219+# Другие не реализованные функции
220+
221+- Атрибуты
222+- Перечисления с пользовательскими значениями
223+- Глобальные свойства
224+- Futures
225+- Помощники(helpers) для типов, классов, записей
226+- Inline
227+- Библиотека
228+- Объекты
229+- Перегрузка оператора
230+- Арифметика указателей
231+- Ресурсы
232+- Расширение RTTI, \$RTTI
233+- Вариантные записи(records)
234+- Варианты(variants)
235+
236+# Интеграция pas2js в Lazarus
237+
238+Lazarus понимает концепцию внешних классов, используемую pas2js, поэтому автозавершение кода будет работать.
239+
240+Начиная с Lazarus 1.9, среда IDE может использовать pas2js.exe в качестве обычного компилятора.
241+
242+Интеграция описана здесь: [[lazarus pas2js integration/ru|Интеграция pas2JS в Lazarus]]. Он все еще находится в стадии разработки, но планируется глубокая интеграция с Lazarus.
243+
244+# Импорт классов Javascript
245+
246+Чтобы импортировать класс javascript, нужно написать обычное определение класса, которое имитирует класс Javascript. Можно использовать свойства. Многие примеры можно найти в модулях JS, web, nodejs и libjquery.
247+
248+Вот простой пример:
249+
250+``` pascal
251+ TJSFunction = class external name 'Function'(TJSObject)
252+ private
253+ Flength: NativeInt external name 'length';
254+ Fprototyp: TJSFunction external name 'prototyp';
255+ public
256+ name: String;
257+ property prototyp: TJSFunction read Fprototyp;
258+ property length: NativeInt read Flength;
259+ function apply(thisArg: TJSObject; const ArgArray: TJSValueDynArray): JSValue; varargs;
260+ function bind(thisArg: TJSObject): JSValue; varargs;
261+ function call(thisArg: TJSObject): JSValue; varargs;
262+ end;
263+```
264+
265+\[Приведенный выше код\] объявляет объект `TJSFunction`: в Javascript функции являются объектами.
266+
267+- "`external name 'Function'`" означает, что вы объявляете класс Javascript, где именем класса Javascript является 'Function'.
268+- `(TJSObject)` означает, что он наследуется от `TJSObject` и внешнего класса. Там не должно быть типа предка.
269+- Поля объявлены так же, как в Паскале.
270+- Чтобы объявить поля только для чтения, можно использовать хитрость: объявите поле с использованием модификатора `external name "thename"` и объявите свойство только для чтения с тем же именем (см. length declaration)
271+- `Varargs` может использоваться, чтобы указать, что функция принимает любое количество аргументов.
272+- `JSValue` может использоваться для указания неизвестного типа. Это более или менее эквивалентно типу Variant.
273+
274+# Создание простых объектов JS с новой функцией
275+
276+Некоторые функции JS-фреймворка ожидают JS-объект в качестве параметра. Вот как это сделать в Pascal, используя функцию *new* из модуля *JS*:
277+
278+``` javascript
279+// JavaScript:
280+DoIt({name:"Fred", id:3, size:4.3});
281+```
282+
283+``` pascal
284+// Pascal;
285+DoIt(new(['name','Fred', 'id',3, 'size',4.3]));
286+```
287+
288+Вы можете вложить его для создания субобъектов:
289+
290+``` javascript
291+// JavaScript:
292+DoIt({name:"Fred", size:{width:3,height:2}});
293+```
294+
295+``` pascal
296+// Pascal;
297+DoIt(new(['name','Fred', 'size',new(['width',3, 'height',2])]));
298+```
299+
300+Вы можете использовать `TJSArray._of` для создания JS-массивов "на лету":
301+
302+``` javascript
303+// JavaScript:
304+DoIt({numbers:[1,2,3]});
305+```
306+
307+``` pascal
308+// Pascal;
309+DoIt(new(['numbers',TJSArray._of(1,2,3)]));
310+```
311+
312+# Отладка
313+
314+Сгенерированный исходный код Javascript, конечно, видим и доступен отладке в браузере.
315+
316+Более того, транспайлер может генерировать файл-маппер (прим.перев: это минифицированный/объединённый файл, связанный с файлами, из которых он получился), что означает, что вы сможете увидеть и отладить код Pascal в браузере (будет работать не \[абсолютно\] все, но многое. Это зависит \[еще\] и от браузера.)
317+
318+файл-маппер может быть сгенерирован с использованием параметра командной строки
319+
320+ -Jm
321+
322+Проще всего включать исходники Pascal в файл-маппер
323+
324+ -Jminclude
325+
326+You can tell the compiler to store all file names relative to a local base directory: Вы можете указать компилятору хранить все имена файлов в \[путях\] относительно локального базового каталога:
327+
328+ -Jmbasedir=DirName
329+
330+И вы можете сохранять URL-адрес на карте, поэтому браузер будет использовать URL/вышеуказанное-относительное-имя-файла, чтобы получать исходный код:
331+
332+ -Jmsourceroot=URL
333+
334+# Баги
335+
336+Пожалуйста, сообщайте об ошибках в багтрекере FPC в категории *pas2js*: <http://bugs.freepascal.org>
337+
338+# Примеры
339+
340+- Приложение для отслеживания времени: (исходный код: <https://www.devstructor.com/demos/pas2js-time/source.zip>)
341+- Рисование и анимация на холсте: <http://ragnemalm.se/images/santa/santa.html> (исходный код: <http://ragnemalm.se/images/santa/>)
342+- WebGL: <https://github.com/genericptr/Pas2JS-WebGL#pas2js-webgl>
343+
344+# Виджеты Lazarus
345+
346+Конечная цель, конечно, - запустить LCL в Всемирной сети. Обсуждения по этой теме делегированы на отдельной странице. [[pas2js widgetsets]]
347+
348+# ЧаВо
349+
350+## Почему простая программа "hello world" такая большая?
351+
352+Это в основном связано с использованием rtl.js. Файл rtl.js содержит код для паскалевских модулей, классов, RTTI, наборов, проверок диапазона и т.д., и написан с учетом больших WebApp, а не для сценариев с несколькими строками кода.
353+
354+1. Вы можете использовать Javascript [[pas2js minifier|minifier ("минимизатор")]], чтобы уменьшить созданный Javascript
355+2. Вы можете создать свой собственный "минимизатор" rtl.js, удалив все ненужные вам функции. В конечном итоге это будет сделано автоматически pas2js.
356+
357+## Почему \[нежелательно\] применение asm-вставок?
358+
359+Asm-вставки полезны для вещей, которые вы не можете сделать с \[помощью\] pas2js. Но есть некоторые недостатки: pas2js не разбирает JS. Он также не проверяет синтаксис и не знает, на какие идентификаторы Паскаля ссылается код. Это означает, что любой идентификатор, доступный только блоку asm, будет удален оптимизатором pas2js.
360+
361+Поэтому всегда старайтесь делать это на Паскале. Помните, что вы можете типизировать значения в JSValue, объекты в TJSObject, массивы в TJSArray, строки в TJSString и т.д., чтобы использовать почти все функции JS.
362+
363+## Почему не парсятся(разбираются) asm-вставки?
364+
365+Любой анализатор JS времени компиляции может выполнять только проверку синтаксиса и анализировать только простые JS. Но так как простой JS может быть лучше написан на Паскале, это несколько бессмысленно и поэтому имеет низкий приоритет.
366+
367+---
368+*From the Free Pascal wiki, page "pas2js/ru", as it stood on 2022-05-28 after a change by FTurtle, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history