LINUX.ORG.RU

Идёт большая работа по включению COBOL в готовящийся к релизу GCC-15

 , , ,


0

3

https://www.phoronix.com/news/134k-Lines-v2-COBOL-For-GCC

Более 134 тысяч строк кода было добавлено/изменено в недавнем наборе патчей, который добавляет фронт энд языка COBOL в набор компиляторов GCC.

А ты достаточно стар, чтобы оценить это? Тебе приходилось программировать на Коболе? Мне не приходилось, хотя однажды ненадолго попал в такой проект, где был и Кобол.

Цитата с https://gcc.gnu.org/pipermail/gcc-patches/2025-February/675873.html

The following 15 patches constitute 134,033 lines of code in 97 files
to build and document the COBOL front end.  The messages are
grouped by files in a more or less logical order. We have:

      4K dir  create gcc/cobol and libgcobol directories
      8K pre  introduce ChangeLog files
     92K bld  config and build machinery
    436K cfg  libgcobol/configure
    380K hdr  header files
    156K lex  lexer
    492K par  parser
    360K cbl  parser support
    532K api  GENERIC interface
    252K gen  GENERIC interface support
     72K doc  man pages and GnuCOBOL emulation
     24K pos  Posix adapter framework
     84K lhd  libgcobol header files
    480K lib  libgcobol support
    384K lcc  libgcobol, main file

Except for "lib", patches over 400 KB consist of just one big file. 

They are against the master branch as of 

	commit 3e08a4ecea27c54fda90e8f58641b1986ad957e1
	Date:   Wed Feb 5 14:22:33 2025 -0700

Our repository is 

	https://gitlab.cobolworx.com/COBOLworx/gcc-cobol/

using branch

	cobol-stage

I tested these patches using "git apply" to an unpublished branch
"cobol-patched". I will push it on request.  There are some whitespace
warnings that I understand, and some I do not.  There is no trailing
whitespace, and tabs occur only in lex/yacc files.

I have endeavored to address all the issues raised in Round 1.  In
particular: 

1.  The patches are against a recent commit.
2.  Generated files use Autoconf 2.69.
3.  Flex and Bison outputs respect --enable-generated-files-in-srcdir.
    We use the gcc FLEX and BISON make variables. 
4.  Documentation is generated as HTML and PDF. 
5.  Python machinery has been patched to add 'cobol' 
6.  ChangeLogs !
7.  libgcobol builds independent of gcc/cobol.  The library does not use
    compiler header files.  Shared information is maintained in library
    headers. 
8.  --enable-languages=all works. gcobol supports x86_64 and aarch64
    (so far, for now). For unsupported targets, configure reports
    gcobol is not built.  We have built with multilib enabled and
    from bootstrap. 
9.  Diagnostic messages go through the diagnostic framework, and report
    the location, including the column. 
10. Use xasprintf & friends from libiberty. Removed PATH_MAX. 

Still to come: 

11. Enumerated warnings in cobol/lang.opt. 
12. texinfo update to describe gcobol
13. cross-compilation

This patchset still excludes tests. I will supply tests separately.
Simplest I think is to use the NIST test suite, assuming the code and
documentation passes legal muster. 

I want to thank David and Matthias for their patches, which are
incorporated.  My thanks too to the many people contributed invaluable
advice and offered encouragement. 

I remain obdurately hopeful the COBOL front end will be deemed ready
for gcc-15. The von Clausewitz test of any compiler is the real world.
Users kicking the tires push us to improve the compiler in ways that
are are practical to them. (Several features are now pending while we
strive to meet reviewers' concerns.)  To that end, I have also prepared
release notes for the www repository under separate cover.

Thank you for your kind consideration of our work.

--jkl

А ты достаточно стар, чтобы оценить это? Тебе приходилось программировать на Коболе?

не программировал активно, так, тыкал хелловорды и мануалы читал.

ну, и Lunar Lander на SDL2 и коболе потыкал.

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

записи там (таблицы) сделаны интересно. в целом, на этом можно какой-то парсер написать.

в языке примерно 300..450 встроенных ключевых слов «из коробки», так что язык сам по себе довольно функциональный. разве что для обработки строк чего-то типа продвинутого pattern matching в духе SNOBOL или похожего не хватает.

а, ну да. и с уникодом не то чтобы совсем проблема, скорее вместо изкоробочности уникода нужно в духе plan9 c utf runes обмазываться, или читать как с С уникодом его сопрягать.

в мануале примеры в стиле Jupiter Notebook/Literate Programming на RST/Sphinx подобной разметке, читается словно песня.

шаблоны еще там прикольные, COPYBOOK вместо #include. больше на литературные программы похоже.

еще был генератор конечных автоматов, Libero кажется. в котором настраивается шаблонами под что угодно. и в том числе, и COBOL там тоже есть «из коробки» (под него изначально писалось). Libero использовался в веб-сервере Xitami, там вся обработка HTTP протокола на конечных автоматах.

в целом, парсеры лучше писать на подобных конечных автоматах (если приспичит именно на коболе их писать – код который там в Libero грамотно использует кобольные таблицы для аналогичного destructuring bind в коммон лиспе.

видел даже попытку написания LISP интерпретатора (скорее LISP 1.5, чем CL) на GNU COBOL. и прототип какой-то операционки, но там все совсем уж сыро.

хотя операционки в духе ядро+СУБД встроенное в ядро в целом – идея не так уж плоха.

так что на коболе оно было бы воистену переносимо подо все, да еще и читалось бы словно пестня. да еще и с С подобными FFI библиотеками линковалось бы элементарно.

в общем, ядро ОС на коболе пока что общедоступного никто вроде бы не написал.

а жаль. успех был так близок. были какие-то операционки с интегрированной в ядро СУБД: на бейсике, BLISS, даже на МУМПСЕ были (ДИАМС).

а вот на коболе подобной ядро+СУБД операционки почему-то не видел.

вообще, тот же МУМПС следовало бы как раз на коболе написать. для наглядности. хотя там половина скорее на C привязках получится.

anonymous
()

Мне тоже не приходилось, но наслышан. Книжка, которую мы с одним чуваком одолжили в читальном зале ради Фортрана 77, содержала сабж, но в то время было не до него.

sparkie ★★★★★
()
Ответ на: комментарий от zg

для майнфреймов это все уже либо переписали, либо скодогенерировали из кобола в яву.

а где не скодогенерировали – внезапно, скодогенерировать кобол в сишечку со всеми нужными батарейками и привязками через C FFI внезапно, не такая уж и глупая идея чем изобретать на С++ свой велосипед на каждый чих вроде того же 1С .

а для винды например существует не такой уж и плохой Visual COBOL, с интеграцией в .NET.

Visual Prolog еще тоже прикольный – с объектами, формами, OnButtonClick-ами на объектно-ориентированном прологе, который напрямую в си конпелируется через вижуал студию.

anonymous
()
Ответ на: комментарий от zg

через сишечку и его C ABI и C FFI можно и с растом.

GNU COBOL кодогенерирует на выходе обычный код на си со своим особенным рантаймом – почти как Ада комплилятор GNAT из GCC, или GNU Modula-2.

anonymous
()

А ты достаточно стар, чтобы оценить это?

теперь осталось дождаться, когда pl1gcc в апстрим интегрируют.

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

модулу и аду и то активнее.

anonymous
()
Ответ на: комментарий от zg

рантайм в той же аде например отстегивается, и можно написать свой более минималистичный. в итоге программа например на С++ от программы на Си от программы на аде с точки зрения статической линковки отличается 1) другим рантаймом 2)-l ключиком при сборке.

ну там грамотно C FFI прагмами реализован, и в целом сишные типы и адские нормально разнесены по отдельным пакетам.

GCC модула-2 в этом смысле похожа на аду из GNAT. только язык проще и рантайм минималистичнее.

GNU COBOL кодогенерирует С код из кобольного исходника, который собирается 1)с другим рантаймом 2) -l ключиком libcobol при сборке.

nim с паскалеподобной семантикой, но с шаблонами в духе С++ и AST макросами в духе лиспа, с синтаксисом в духе питона. генерирует код на Си со своим особенным рантаймом (и этим похож на то, что выше по тексту)

в итоге бинарь на выходе похож на обычный си, просто со своим особенным рантаймом в статической или динамической линковке.

то что где-то есть полноценный бекенд вроде модулы-2 или ады в GNAT – или кодогенерация через сишечку – это просто детали реализации, не так существенные.

ну, возможно, что бекенд GNAT и GCC Modula-2 лучше умеет оптимизировать – на уровне GIMPLE и SSA а не сишной скодогенерированной лапши.

anonymous
()
Ответ на: комментарий от anonymous

в этом смысле XPL проект позволяет скодогенерировать из PL1 кода код на обычной сишечке. и более перспективный чем свой какой-то отдельный бекенд.

имело бы смысл ради нормального препроцессора из PL1 – но он все равно полноценно реализован только в IBM-овских компиляторах PL1.

PL1 , кстати, более активно использовался чем тот же КОБОЛ.

по сути, PL/I как язык – это:

  1. кобольные таблицы и типы данных
  2. массивы как в фортране
    3)препроцессор, где можно делать что угодно (где он полноценно реализован)
    4)более прозрачная Си интеграция
  3. в остальном, практически полноценный язык.. ну разве что объектов не хватает.. хотя в Visual Age PL/I под OS/2 что-то такое было, но там вообще SOM был родной, через C ABI и FFI.

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

см. например в таблицах ключевые слова для генерации форм в ANSI графике. в Visual COBOL это превратилось в RC-ресурсы окон win32/64 и кажется, там что-то из объектов запилили.

хотя объекты и в сам КОБОЛ на уровне стандарта какого-то после 2000 года в язык добавили.

самодостаточная реализация PL/I – это PL/KT с сайта http://pl1.su Дмитрия Караваева.

win64 с примерами под DirectX под венду. нормальный FFI там реализован, единственно что Intel OMF формат объектников, и свой рантайм написать возможно, но документации не вполне хватает…

весь компилятор+тулчейн+линкер == это один exe файл PLINK64.exe размером 1,914,368 байт (в архиве pl64.zip размером всего 790,901 байт – на дискету еще влазит)

ну еще можно скачать документацию и ресурсы resource.zip. и например, примеры под DirectX чтобы понять как там пишется C FFI.

все остальное (рантайм, стандартные библиотеки, линкер, сам конпелятор) – оно носит в ресурсах этого единого .exe файла.

вот как надо писать самодостаточные компиляторы.

pl1gcc в отличие от него – бекенд для какой-то старой версии gcc.

в общем, PL1 в целом более полноценный язык чем КОБОЛ – а на КОБОЛЕ проще писать формы и какую-то опердень с таблицами и записями.

ну, и 300+ ключевых слов и встроенных функций «из коробки». какое богатство, да.

anonymous
()
Ответ на: комментарий от splinter

он там с русскими ключевыми словами?

вот и зачем же имея такое выразительное богатство великаго и могучего русскаго языка надобно было изобретать такой куцый недобейсик недодельфи недодотнет как этот ваш 1С:Basic, например?

мне это – решительно непонятно.

лучше бы нечто подобное 1С на этом вот напейсали бы.

тогда оно с сишечкой безо всяких проблем конпелировалось бы подо все.

даже под ОС ЕС, лолъ.

anonymous
()
Ответ на: комментарий от anonymous

а, ну да. и с уникодом не то чтобы совсем проблема, скорее вместо изкоробочности уникода нужно в духе plan9 c utf runes обмазываться, или читать как с С уникодом его сопрягать.

так что по идее, там можно писать на русском. но это не точно.

кириллические ключевые слова макросней какой-то придется делать, скорее всего.

с идентификаторами и стоками – зело полезнее. но в целом, он восьмибитный, под уникодовые строки что-то писали в рассылке и в мануалах и сошлись на том что там сильно рантайм придется патчить.

вообще, интересно как там у GNU COBOL c поддержкой русскоязычности, например, целого ГОСТ 22558-89.

как там с одиэсностью кобольной нынче? импортозаместили уже или еще «да,но пока нет»?

вот сюрприз же будет если реальный код на этом пространном будет невозбранно читаться проще чем на самом 1С.

anonymous
()

Поддержка COBOL в GCC это запрос от крупнейших игроков фин сектора. А где запрос индустрии та ми гранты/средства на поддержку и тд. Если хозяева рынка говорят что им надо - это будет сделано и не важно насколько там древний ЯП.

Obezyan
()
Ответ на: комментарий от splinter
ГОСТ 22558—89 С. 67
3. ГЕНЕРАТОР ОТЧЕТОВ
Назначением генератора отчетов является организация, фор­
матирование и представление содержания выдаваемых отчетов.
Хотя отчет может быть составлен без использования этих средств,
генератор отчетов обеспечивает более удобные возможности для
построения и составления отчетов. Программирование процедур,
которое обычно производит программист, автоматически обеспе­
чивается системой управления генератором отчетов. Таким обра­
зом, программист избавлен от написания процедур перемещения
данных, конструирования печатаемых строк, подсчета строк на
странице, нумерации страниц, составления строк заголовка и
строк концовки, распознавания конца логических подразделений
данных, обновления счетчиков сумм и т. п. Все эти действия вы­
полняются автоматически на основании спецификаций, главным
образом, секции отчетов раздела данных исходной программы.

как одна из причин почему КОБОЛ. плюс формы. плюс таблицы.

но вообще, полноценный генератор отчетов называется RPG у которого как раз коболий синтаксис.

еще в SAP R/3 кажется в Adabas и там для генератора отчетов было что-то RPG или КОБОЛоподобное.

про RPG, кажется, тоже успели какой-то ГОСТ перевести.

anonymous
()
Ответ на: комментарий от anonymous

стр. 71

4.1. Определение таблиц
Чтобы определить одномерную таблицу, программист исполь­
зует фразу OCCURS (ПОВТОРЯЕТСЯ) как часть описания таб­
личного элемента, но фраза OCCURS (ПОВТОРЯЕТСЯ) не долж­
на появляться в описании групповых данных, которые содержат
табличный элемент. Пример 1 показывает одномерную таблицу,
определяемую данным TABLE-ELEMENT (ТАБЛИЧНЫЙ-ЭЛЕ-
МЕНТ).
Пример 1
01 TABLE-1.
02 TABLE-ELEMENT OCCURS 20 TIMES.
03 FAM ...
03 NAME . ..
01 ТАБЛИЦА-1.
02 ТАБЛИЧНЫИ-ЭЛЕМЕНТ ПОВТОРЯЕТСЯ 20 РАЗ.
03 ФАМИЛИЯ ...
03 ИМЯ ...
71
С. 72 ГОСТ 22558— 89
В примере 2 TABLE-ELEMENT (ТАБЛИЧНЫЙ-ЭЛЕМЕНТ)
определяет одномерную таблицу, но FIO (ФИО) не определяет од­
номерную таблицу, поскольку в описании группового данного
TABLE-ELEMENT (ТАБЛИЧНЫЙ-ЭЛЕМЕНТ), содержащего
FIO (ФИО), имеется фраза OCCURS (ПОВТОРЯЕТСЯ).
Пример 2
02 TABLE-1.
03 TABLE-ELEMENT OCCURS 20 TIMES.
04 FIO OCCURS 5 TIMES.
05 FAM ...
05 NAME ...
02 ТАБЛИЦА-1.
03 ТАБЛИЧНЫЙ-ЭЛЕМЕНТ ПОВТОРЯЕТСЯ 20 РАЗ.
04 ФИО ПОВТОРЯЕТСЯ 5 РАЗ.
05 ФАМИЛИЯ ...
05 ИМЯ ...
В обоих случаях полному набору вхождений данного TABLE-
ELEMENT (ТАБЛИЧНЫЙ-ЭЛЕМЕНТ) присвоено имя TABLE-1
(ТАБЛИЦА-1). Тем не менее, нет необходимости давать таблице
имя группы, если не требуется ссылка на всю таблицу как на груп­
повое данное.
Ни одна из трех одномерных таблиц, приведенных в двух сле­
дующих примерах, не имеет имени группы.
Пример 3
01 INFORMATION.
02 OTDEL ...
02 FIO OCCURS 20 TIMES ...
02 N-ROOM ...
01 СВЕДЕНИЯ.
02 ОТДЕЛ . ..
02 ФИО ПОВТОРЯЕТСЯ 20 РАЗ . . .
02 N-КОМНАТЫ . ..
Пример 4
01 INFORMATION.
02 DEPARTMENT OCCURS 20 TIMES ...
02 FIO ...
02 N-ROOM OCCURS 5 TIMES ...
01 СВЕДЕНИЯ.
02 ЦЕХ ПОВТОРЯЕТСЯ 20 РАЗ ...
02 ФИО ...
02 N-КОМНАТЫ ПОВТОРЯЕТСЯ 5 РАЗ ...
Определение одномерной таблицы внутри каждого вхождения
элемента другой одномерной таблицы приводит к образованию
двумерной таблицы. Для определения двумерной таблицы фраза
OCCURS (ПОВТОРЯЕТСЯ) должна появиться в описании данных
72
Г О С Т 22558— 89 С. 73
табличного элемента и в описании только одного группового эле­
мента данных, который содержит этот табличный элемент. Так, в
примере 5 N-ROOM (N-КОМНАТЫ) является элементом двумер­
ной таблицы — он входит 5 раз в каждый элемент данного
DEPARTMENT (ЦЕХ), который сам повторяется 20 раз.
FIO (ФИО) является элементом одномерной таблицы.
П р и м е р 5
02 DEPARTMENT OCCURS 20 TIMES ...
03 FIO ...
03 N-ROOM OCCURS 5 TIMES . . .
02 ЦЕХ ПОВТОРЯЕТСЯ 20 РАЗ ...
03 ФИО ...
03 N-КОМНАТЫ ПОВТОРЯЕТСЯ 5 РАЗ ...
В общем случае для определения n-мерной таблицы фраза
OCCURS (ПОВТОРЯЕТСЯ) должна появиться в описании дан­
ного элемента таблицы и в описаниях (п— 1) групповых данных,
содержащих этот элемент.
4.2. Начальные значения таблиц

вот это ей-богу, читается проще и легче чем какая-то простыня на недовижуалдотнетбейсике типа 1C.

anonymous
()
Ответ на: комментарий от anonymous

Голый Си и плюсанутый Си++ медленно работают на некоторых мейнфреймах - как ни странно, но им мешают указатели… Просто ты привык все воспринимать сквозь призму x86/x64.

anonymous
()
Ответ на: комментарий от anonymous

формы

то есть, SCREEN SECTION: примеры

  1. Colors
CS Cobol Xref v2.02.02          Dictionary File for COLORS    07/12/2019  16:57:00:16                                 Page    1

     1          >>SOURCE FREE
     2   IDENTIFICATION DIVISION.
     3   PROGRAM-ID. colors.
     4   DATA DIVISION.
     5   WORKING-STORAGE SECTION.
     6   SCREEN SECTION.
     7   01 S-COLORTST-SCR BACKGROUND-COLOR 0 FOREGROUND-COLOR 7 BLANK SCREEN.
     8   05 LINE 01.
     9   10 COL 1 VALUE ' LOWLIGHT  -------- HIGHLIGHT  LOWLIGHT  -------- HIGHLIGHT'.
    10   05 LINE + 1.
    11   10 COL 1 VALUE ' --------  --------  --------  --------  --------  --------'.
    12   05 LINE + 1.
13   10 COL 1 VALUE ' --------  --------  --------   REVERSE   REVERSE   REVERSE'.
    14   05 LINE + 1.
    15   10 COL 1 VALUE ' 01234567  01234567  01234567  01234567  01234567  01234567'.
    16   05 LINE + 1.
    17   10 COL 1 VALUE '0         0         0         0         0         0        '.
    18   05 LINE + 1.
    19   10 COL 1 VALUE '1         1         1         1         1         1        '.
    20   05 LINE + 1.
    21   10 COL 1 VALUE '2         2         2         2         2         2        '.
    22   05 LINE + 1.
    23   10 COL 1 VALUE '3    1    3    2    3    3    3    4    3    5    3    6   '.
    24   05 LINE + 1.
    25   10 COL 1 VALUE '4         4         4         4         4         4        '.
    26   05 LINE + 1.
    27   10 COL 1 VALUE '5         5         5         5         5         5        '.
    28   05 LINE + 1.
    29   10 COL 1 VALUE '6         6         6         6         6         6        '.
    30   05 LINE + 1.
    31   10 COL 1 VALUE '7         7         7         7         7         7        '.
    32   05 LINE + 1.
    33   10 COL 1 VALUE ' LOWLIGHT  -------- HIGHLIGHT  LOWLIGHT  -------- HIGHLIGHT'.
    34   05 LINE + 1.
    35   10 COL 1 VALUE '    BLINK     BLINK     BLINK     BLINK     BLINK     BLINK'.
    36   05 LINE + 1.
    37   10 COL 1 VALUE ' --------  --------  --------   REVERSE   REVERSE   REVERSE'.
    38   05 LINE + 1.
    39   10 COL 1 VALUE ' 01234567  01234567  01234567  01234567  01234567  01234567'.
    40   05 LINE + 1.
    41   10 COL 1 VALUE '0         0         0         0         0         0        '.
    42   05 LINE + 1.
    43   10 COL 1 VALUE '1         1         1         1         1         1        '.
    44   05 LINE + 1.
    45   10 COL 1 VALUE '2         2         2         2         2         2        '.
    46   05 LINE + 1.
    47   10 COL 1 VALUE '3    7    3    8    3    9    3   10    3   11    3   12   '.
    48   05 LINE + 1.
    49   10 COL 1 VALUE '4         4         4         4         4         4        '.
    50   05 LINE + 1.
    51   10 COL 1 VALUE '5         5         5         5         5         5        '.
    52   05 LINE + 1.
    53   10 COL 1 VALUE '6         6         6         6         6         6        '.
    54   05 LINE + 1.<<..tl;dr..>>
anonymous
()
Ответ на: комментарий от anonymous
  1. GCic

This is MUCH more than a mere demonstration program – it’s also a very practical utility! The «GCic» (GnuCOBOL Interactive Compiler) is a TUI (Textual User Interface) program that may be used as a full-screen interface to the «cobc» compiler. In addition, GCic can produce neat, concise and useful cross-reference listings of GnuCOBOL programs, showing not only where user-defined names and built-in registers and intrinsic functions are referenced, but also where user-defined data items ARE MODIFIED by program code!

код после 357 строки тоже интересный.

вот такие и подобные текстовые консольные TUI утилиты из нескольких экранов, форм вокруг SCREEN SECTION пишутся на КОБОЛе легко и невозбранно.

anonymous
()
Ответ на: комментарий от anonymous

манул с примерами и ещё один

модный и молодёжный

хабростатья со ссылками

версии стандартов:

  • КОБОЛ 1985 – более нормальный синтаксис, необязательные номера строк

  • КОБОЛ 2002 – объектно-ориентированный

  • КОБОЛ 2014 – XML, коллекции классов

  • КОБОЛ 2023 – асинхронщина, транзакции (не реализован почти нигде)

anonymous
()
Ответ на: комментарий от Obezyan

Ну привычно как то было что IT-гиганты вкладываются в проекты под пермиссивными лицензиями. А тут мало того что компилятор под жопелем, так ещё оно и рантайм с собой тащит...

thunar ★★★★★
()
Ответ на: комментарий от thunar

Ну привычно как то было что IT-гиганты вкладываются в проекты под пермиссивными лицензиями. А тут мало того что компилятор под жопелем, так ещё оно и рантайм с собой тащит…

Дело в том что это не ИТ гиганты. Это финкорпы уровня JP Morhgan Chase Bank которые держат долларовые корр счета банков всего мира (просто пример). И плевали они на все эти пермиссивные лицензии потому что над ними только ФРС. Им нужны конкретные технические инструменты и их поддержка - они их получат.

Почему COBOL - там запредельные требования по надежности, ни один адекватный системный архитектор не поставит свой анус на переход с COBOL (инструмент заточенный для работы бизнес объектами) на что-то смузихлебно-молодежное общего назначения. Проще и дешевле заплатить чтобы поддержка используемого языка продолжала вноситься в используемые инструменты сборки.

Аргумент что он устарел в данным случае не валиден, потому что он предназначен для работы с вещами которые появились до него, а не после: транзакции-проводки, фьючерсы, деривативы и тд.

Все что появилось нового, например смарт-контракты, пошло в блокчейн ориентрованный язык Solidity. И в него также вкладывются те же корпы что и в Cobol.

Obezyan
()

Идёт большая работа по включению COBOL в готовящийся к релизу ...

Я чето думал что в конце будет linux kernel, а не gcc, а было бы забавно

Kolins ★★★★★
()