Транскомпилируемые языки: проекты конвертации код-в-код
Источник: Ward Cunningham
Транспиляция — это конвертация кода одного языка в другой. С помощью специального транспилера (транскомпилятора) один язык программирования общего назначения можно перенести на любой другой язык программирования общего назначения.
Если необходимо переключиться на другой язык, транспилеры помогут разработчикам сохранить бóльшую часть существующего кода, не переписывая весь код вручную. Например, при преобразовании программ из Python 2 в Python 3, или при переносе софта от старого API в новый.
Термины «транспилер» и «транскомпилятор» часто взаимозаменяемы, но все же считается, что различия есть. Например, для преобразования кода C++ в C потребуется транспилер, а для конвертации Python-Ruby — транскомпилятор. Babel для JavaScript — это транспилер, а TypeScript — транскомпилирумый язык.
Иногда после конвертации транспилером для правильной работы кода требуется ручная настройка, в то время как в транскомпилируемых языках код должен работать без изменений. Сегодня поговорим о тех и о других, но главное — расскажем о популярных транс-проектах, которые разработчики могут использовать в повседневной работе.
Транспилирование во фронтенде
Конвертация — важная часть фронтенд-разработки: поскольку новые фичи в браузерах появляются медленно, были созданы языки с экспериментальными возможностями, которые транспилируются в совместимые с браузерами языки.
За буйный расцвет транс-языков для JavaScript также несут ответственность разработчики браузеров, использующие в каждом проекте свой механизм JavaScript. В результате браузеры имеют различную производительность, реализуют свой набор функций JavaScript, и к полному соответствию спецификации приближаются с разной скоростью.

Sass, Less и Stylus упрощают создание CSS-кода. Так Sass обладает гибким синтаксисом, логикой (@if, each), математикой (можно складывать числа, строки и цвета), за счет чего все богатство кода транспилируется ruby-программой в обычный CSS.
Less (Leaner Style Sheets) выглядит так же, как CSS, но имеет удобные дополнения: переменные, миксины, арифметические операции (как у Sass) и т.д.
Stylus написан на Node.js и отличается от Sass и Less более чистым синтаксисом. Но фактически эти три языка очень похожи друг на друга, поэтому не ошибетесь, если выберите любой из них.

Скажем «Hello, World!» на CoffeeScript — что может быть проще:
CoffeeScript долгое время оставался самым популярным проектом для JavaScript. Это неудивительно: совмещая доступность (документация умещается на одной странице), функциональные фичи (скобки, отступы и т.д.) и чистый, вдохновленный Ruby, синтаксис, этот язык дает разработчикам много степеней свободы и позволяет сделать JS более выразительным.

TypeScript — конкурирующий проект под JavaScript, скриптовый язык с добавлением опциональной статичной типизации. Позволяет более полно описывать свойства и методы объектов и классов, в отличие от JS, избавляя от необходимости осуществлять проверку всех аргументов, входящих в метод или функцию.
Существует мнение, что JavaScript — это язык с фундаментальными изъянами. Иначе трудно объяснить популярность транс-языков, работающих именно над исправлением его недостатков. Помимо вышеназванных проектов есть еще гибкий язык веб-программирования Dart, компилятор из JavaScript в JavaScript Closure Compiler и многие другие решения, узнать о которых вы можете на странице «Список языков, которые компилируются в JS».
Конвертируем в С

В 2006 г. появился проект Vala, состоящий из двух языков: Vala и Genie, транслирующих самый обычный код на С, который, в свою очередь, компилируется в исполняемый файл или библиотеку.
Синтаксис Vala очень похож на C#, но адаптирован для лучшей совместимости с системами GObject, в то время как Genie имеет много общего с Python. Первый язык сейчас более распространен, чем Genie, поэтому рассмотрим его подробнее.
Почему возникла необходимость в таком проекте? Многие разработчики хотели писать приложения и библиотеки для GNOME на высокоуровневых языках, но по разным причинам не могли или не хотели использовать C# или Java. Vala позволяет быстро создать сложный объектно-ориентированный код, поддерживая стандартные C API и ABI при низких требованиях к памяти.
Библиотеки C# и Java нельзя использовать так же, как нативные библиотеки GObject из C и других языков, и нельзя считать их частью платформы GNOME. Valac, транскомпилятор Vala, создает файлы C из исходных файлов Vala так, словно вы написали свою библиотеку или приложение непосредственно на C. Использование библиотеки Vala из приложения C не отличается от использования любой другой библиотеки на основе GObject.
Читаем и записываем файл на Vala:
С другими примерами кода вы можете ознакомиться на сайте.
От Flash до мультиплатформенности

Haxe создавался одновременно с Vala, но предназначен для транспилирования во Flash, JavaScript и Neko. С таким набором скиллов язык был обречен на вымирание, однако он не только выжил, но и завоевал большую популярность.
Секрет успеха заключается в мультиплатформенности. Со временем Haxe разросся до мощного набора инструментов, поддерживающих транскомпиляцию на разные языки и платформы, включая JavaScript, C++, C#, Java, JVM, Python, Lua, PHP и Flash.
Haxe — современный, высокоуровневый, строго типизированный язык программирования. В то же время он довольно простой и практичный, благодаря чему компиляцию можно приспособить к различным целевым платформам. Его синтаксис в основном соответствует стандарту ECMAScript, но при необходимости изменяется.
«Hello World» на Haxe:
В JavaScript эти строчки кода будут выглядеть следующим образом:
Бóльшая часть кода Haxe организована в классы и функции, что делает его ООП-языком, напоминающим Java, ActionScript 3 и C#. Тем не менее Haxe разрабатывался с упором на прагматичность и легкость синтаксиса.
И о транспилерах
-
и Corrode — две не безгрешные возможности перенестись из C в Rust.
— транспилер из Python 3.4+ в Java, который поможет создавать приложения для Android на базе кода Python.
— интересное решение для тех, кому не нравится Java, или не нравится ничего, кроме Java. Это плагин компилятора, добавляющий в Java новые «ключевые слова» и превращающий аннотации в Java-код, сокращая усилия на разработку и обеспечивая дополнительную функциональность. Например, он позволяет в обычном коде на Java использовать ключевое слово val (аналог var из C#).
позволяет использовать в JavaScript производительность C#, а также мощные VisualStudio IDE и стандартные инструменты .NET (такие как msbuild, рефакторинг, модульное тестирование, статический анализ, визуализация кода, FxCop).
обеспечивает трансляцию кода на языке Python в представление на языке Go и позволяет бесшовно запускать Python-программы в runtime-окружении Go. Проект избавляет от проблемы глобальной блокировки интерпретатора, не допускающей параллельного выполнения нескольких нитей кода.
Заключение
Существует огромное количество других языков, поэтому для своего проекта вы всегда можете подобрать самый подходящий. Но ситуации, когда необходима конвертация код-в-код — не такая уж редкость, так как транспиляции C++ в C, PHP в C++ и «что угодно в JavaScript» случаются довольно часто.
«Переводчик» с одного языка на другой — хорошая идея, но лишь до тех пор, пока результат можно четко предсказать и использовать без рисков. Так, переход с COBOL на Java давался тяжело, поскольку в Java до версии JDK 1.4 не было memory-mapped files. А упомянутые в статье C2Rust и Corrode на выходе дают не идиоматичный код, помеченный как unsafe и наполненный «сырыми» указателями.
Что такое транспиляция

Понять, что такое транспайлеры и какова их роль в программировании, поможет следующий пример. Представим, что вы разрабатываете софт для TV-приставок и вам нужно добавить калькулятор на все приставки определенной фирмы. Есть одно но — некоторые приставки не обновлялись уже 7 лет и могут работать только со старой версией языка, на котором написан калькулятор. Тут появляется выбор:
- Разрабатывать программу для двух типов приставок: на старой версии языка для тех, которые давно не обновлялись, и на новой — для современных.

- Использовать «переводчик» с версии языка, которую используете вы, на версии, работающие на всех устройствах
Роль такого переводчика выполняют транспайлеры: они преобразуют код, на котором мы пишем, в другой, который может применяться и работать у конечного пользователя на любых устройствах с любыми версиям языка разработки.
Транспиляция — преобразование программы, написанной на одном языке программирования в качестве исходных данных, в эквивалентный код другой версии этого языка или в другой язык программирования того же уровня абстракции.
Когда нужна транспиляция?
Рассмотрим практический пример, в котором пригодится транспайлер. За основу возьмем кейс с обновлением софта в TV-приставках, но дополним его деталями.
Калькулятор запускается на встроенном браузере TV-приставки и написан на JavaScript последней версии. Также учтем, что приставки выпускались каждый год с ограниченным сроком поддержки и сейчас мы имеем множество устройств с разными версиями браузера (а, следовательно, и отличающиеся версии поддерживаемого JS-кода). Кроме того, браузер пользователя давно не обновлялся и код на JS, который может там работать, сильно отличается от текущих версий языка.
В такой ситуации чаще всего может пригодиться транспиляция кода. Транспайлеры помогут преобразовать код, написанный на последней версии JavaScript, в тот, который будет работать у всех пользователей независимо от времени, прошедшего с последнего обновления.
Как используют транспайлеры?
Тринспайлеры широко используются во многих областях программирования. В целом можно выделить две основных области применения:
Транспиляция одной версии языка в другую. Поскольку языки программирования постоянно обновляются, возникают ситуации, когда разработчик уже пишет на новой версии языка, а среда, где используется код, поддерживает и работает только с предыдущими версиями. Например, для переходов между версиями стандарта ECMAScript используется Babel. Транспайлеры позволяют преобразовывать код и в другую сторону: например, помогают перевести проект на более новую версию языка. Делать это вручную долго и больно. Например, если проект написан на Python 2.x, перевести его на Python 3 можно с помощью трансплайнера 2to3
Транспиляция между разными языками. Например преобразование TypeScript в JS. Подробнее об этом расскажем ниже
Как работают транспайлеры?
В качестве примера рассмотрим работу транспайлера над возведением в квадрат кода на JS:
Вот как выглядит то же преобразование, проведенное с помощью объекта Math — он и использовался для операций по возведению в квадрат в старых версиях языка:
В данном случае у нас есть начальное и желаемое конечное состояния. Мы уже знаем, что для транспайлера не составит труда провести такое преобразование. Однако для нас механизм его работы пока выглядит как черный ящик. Пора в деталях разобраться, как происходит транспиляция.
Преобразование исходного кода в абстрактною форму
На первом этапе транспайлер создает на основе кода абстрактное представление. В общем случае такое преобразование происходить в два этапа — сначала программа проводит лексический, а затем синтаксический анализ.
- Лексический анализ берёт «сырой» код и разбивает его на изолированные части, которые называются токенами. Это могут быть цифры, пунктуация, метки, операторы: всё, что угодно. В нашем случае токенами будут бинарный оператор (применяется к двум операндам, например 2 + 2) и его операнды:

- Синтаксический анализ строит объект, который описывает все токены и их связи между собой. Он называется AST (abstract syntax tree или абстрактное синтаксическое дерево). Оператор возведения в квадрат является бинарным выражением внутри программы (в нашем случае — единственным), а операнды станут идентификаторами в этом выражении:

Трансформация AST
После преобразования в абстрактную модель происходит трансформация, которая производит все необходимые для дальнейшей работы изменения в AST.
На этом этапе дерево из предыдущего шага изменяется: трансформация меняет текущий код на код на предыдущей версии языка. В данном случае оператор умножения заменяется на вызов выражения, при этом его операнды становятся аргументами выражения (Math.pow):

Генерация конечного кода
Когда все изменения внесены, транспайлер берёт трансформированное AST кода и на его основе генерирует новый код.

В итоге код из начального состояния проходит ряд преобразований (анализ -> трансформация -> генерация) до конечного состояния — этот процесс и называется транспиляцией.
Обратная связь
После всех преобразований мы получили конечный код, который работает на нужной нам версии языка. Но представим, что после трансилиляции в нашей программе появились ошибки. Как понять, где именно находится ошибка, если она ссылается какое-то место в трансипилированном коде (который может значительно отличаться от того, что мы писали изначально)?
Использование транспайлеров может затруднить отладку, когда нам нужно найти точное место поломки в исходном коде по транспилированному коду. В таких случаях используются различные утилиты, позволяющие сопоставить результат транспиляции с оригинальным кодом. Например, в JS есть утилита SourceMap, которая в процессе создания конечного кода создает файл-маппер — с его помощью можно связать исходный и конечный код.
Инструменты (реализации) транспиляции кода
Для фронтенд-разработки основной инструмент транспиляции — Babel. Он позволяет не только выполнять транспиляцию между версиями, которую мы рассмотрели выше, но и:
- преобразовывать JSX-код в JavaScript при разработке на React
- трансформировать LESS/SCSS в CSS при использовании CSS препроцессоров
- транспилировать TypeScript в JS, когда нужно использовать типизацию
Среди транспиляторов, которые трансформируют код на бэкэнд языках программирования в код на других языках, популярностью пользуются:
- Haxe предназначен для транспилирования во Flash, JavaScript и Neko. Со временем Haxe разросся до набора инструментов, поддерживающих транспиляцию на разные языки и платформы, включая JavaScript, C++, C#, Java, JVM, Python, Lua, PHP и Flash.
- Lombok — решение для тех, кому хочется расширить возможности Java. Это плагин, добавляющий в Java новые «ключевые слова» и превращающий аннотации в Java-код. Он сокращает время на разработку и обеспечивает дополнительную функциональность.
- Bridge.NET позволяет использовать в JavaScript производительность C#, а также мощные VisualStudio IDE и стандартные инструменты .NET. Grumpy обеспечивает трансляцию кода на языке Python в представление на языке Go и позволяет бесшовно запускать Python-программы в runtime-окружении Go.
Итого
В мире, где есть огромное количество языков программирования, а сами языки имеют множество версий, транспайлеры выполняют крайне важную работу — делают разработку удобнее. Программисты могут писать код на языке или версии языка, которая им удобна или имеет нужные функции, а транспайлеры выполнят работу по доставке этого кода до среды исполнения в нужном виде.
На данный момент реализовано множество различных транспайлеров (Babel, Vala, Typescript transpiler, Bridge и другие), каждый из них решает свою задачу по-своему, но общий принцип работы транспайлеров похож у всех.

Исходный код преобразуется в абстрактное синтаксическое дерево, далее AST трансформируется в структуру, которая соотносится с конечным кодом, и из этой структуры генерируется необходимый нам код.
Как перевести программу с одного языка программирования на другой
Догма гласит, что в вычислениях нет ничего невозможного для тех, кто умеет программировать. К сожалению, распространение языков программирования иногда является препятствием для разработки веб-сайта, программного обеспечения или приложения. Хотя логика остается прежней, форма иногда значительно меняется. Не волнуйтесь, чтобы стать мастером программирования, вам не нужно изучать все самые распространенные языки: вам просто нужно использовать конвертер языка кода .
Преобразование существующей кодовой базы в более современный или эффективный язык, такой как Java или C++, требует знаний как исходного, так и целевого языков и может быть дорогостоящим.
Преобразуйте код в другие языки программирования с помощью конвертера языка кода!
Забудьте о длительных этапах программирования, требующих перевода языка кодирования, чтобы адаптировать его к другим средам.
Если вам нужно быстро преобразовать фрагменты кода с одного языка программирования на другой — сервис Code Language Converter вам в помощь.
1. На сайте выбираем язык программирования уже существующего фрагмента и язык, в который нужно перевести код.
2. Вводим в поле фрагмент кода.
3. Нажимаем «Try sample code!».
4. Через несколько секунд получаем автоматический перевод кода на нужный язык — его можно использовать.
5. Поздравляю, вы великолепны!
Онлайн-конвертер языка кода использует искусственный интеллект для быстрого преобразования фрагментов кода с одного языка программирования на другой за считанные секунды.
Количество языков программирования, поддерживаемых инструментом, просто впечатляет! Разумеется, Language Code Converter переводит наиболее распространенные языки программирования (Phyton, C++, JavaScript, PHP, JAVA, C# и т. д.). Как и следовало ожидать, такой удобный инструмент редко бывает бесплатным. Таким образом, Langage Code Converter работает на основе кредитов, а это означает, что цена, которую необходимо заплатить, пропорциональна использованию вами конвертера. Также обратите внимание, что вы получаете 100 кредитов после регистрации, что позволяет вам протестировать его бесплатно.
Также имейте в виду, что искусственный интеллект, каким бы развитым он ни был, не застрахован от ошибок преобразования.
Трансляторы
Так как текст записанной на Паскале программы не понятен компьютеру, то требуется перевести его на машинный язык. Такой перевод программы с языка программирования на язык машинных кодов называется трансляцией (translation — перевод), а выполняется он специальными программами — трансляторами.
Существует три вида трансляторов: интерпретаторы, компиляторы и ассемблеры.
Интерпретатором называется транслятор, производящий пооператорную (покомандную) обработку и выполнение исходной программы.
Компилятор преобразует (транслирует) всю программу в модуль на машинном языке, после этого программа записывается в память компьютера и лишь потом исполняется.
Ассемблеры переводят программу, записанную на языке ассемблера (автокода), в программу на машинном языке.
Любой транслятор решает следующие основные задачи:
• анализирует транслируемую программу, в частности определяет, содержит ли она синтаксические ошибки;
• генерирует выходную программу (ее часто называют объектной или рабочей) на языке команд ЭВМ (в некоторых случаях транслятор генерирует выходную программу на промежуточном языке, например, на языке ассемблера);
• распределяет память для выходной программы (в простейшем случае это заключается в назначении каждому фрагменту программы, переменным, константам, массивам и другим объектам своих адресов участков памяти).
Введение в .Net и c Sharp
Программист пишет программу на языке, понятном программисту, а компьютер исполняет только программы, написанные на языке машинных кодов. Совокупность средств написания, редактирования и преобразования программы в машинные коды и ее исполнения называют средой разработки.
Среда разработки содержит:
Текстовый редактор для ввода и корректировки текста программы
Компилятор для перевода программы на язык машинных команд
Средства отладки и запуска программы на исполнение
Общие библиотеки с многократно используемыми программными элементами
Справочную систему и др.
Платформа .NET («дот нет»), разработанная компанией Microsoft, включает не только среду разработки для нескольких языков программирования, называемую Visual Studio .NET, но множество других средств, таких как средства поддержки баз данных, электронной почты и др.
Важнейшими задачами при разработке современных программных средств являются:
Переносимость-возможность исполнения на разных типах компьютерах
Безопасность – невозможность несанкционированных действий
Надежность – безотказность работы в заданных условиях
Использование готовых компонентов для ускорения разработки
Межъязыковое взаимодействие – применение нескольких языков программирования.
Все эти задачи решают в рамках платформы .NET. Для обеспечения переносимости компиляторы платформы переводят программу не в машинный код, а в промежуточный язык MSIL (Microsoft Intermediate Language) или просто в IL. IL не содержит команд, зависящих от операционной системы или типа компьютера. Программу на IL исполняет среда выполнения CLR (Common Language Runtime), которая уже специфична для каждого типа компьютера. Перевод IL-программы в машинные коды конкретного компьютера выполняет JIT (Just In Time) –компилятор.
Схема выполнения программы на платформе .NET приведена на рис.1.
Компилятор создает сборку программы – файл с расширение .exe или .dll, который содержит IL-код. Выполнение программы организует среда CRL, которая следит за допустимостью операций, выполняет распределение и очистку памяти и обрабатывает ошибки исполнения. Это обеспечивает безопасность и надежность программ.
Платой за эти достоинства является снижение быстродействия программ и необходимость установки на компьютере .NET для исполнения готовых программ.
Итак, .NET – это платформа программирования.
C# (Си-Шарп) — это один из языков программирования платформы .NET. Он входит в Visual Studio — Visual Studio.NET (Версии 2008, 2010, 2012). Кроме C# в Visual Studio.NET входят Visual Basic.NET и Visual C++. Одна из причин разработки нового языка компанией Microsoft — это создание компонентно-ориентированного языка для платформы .NET Framework.

Рис.1 Схема выполнения программы в .NET
.NET Framework состоит из двух частей:
Во-первых, она включает огромную библиотеку классов, которые можно вызывать из программ на C#. Классов очень много (порядка несколько тысяч). Это избавляет от необходимости писать все самостоятельно. Поэтому программирование на С# заключается в написании собственного кода, который при необходимости вызывает классы, хранящиеся в .NET Framework.
Во-вторых, в ее состав входит среда выполнения .NET Runtime, управляющая запуском и работой готовых программ.
Платформа .NET является открытой средой – сторонние разработчики создали для .NET десятки компиляторов для языков Ada, COBOL, Fortran, Lisp, Oberon, Perl, Python и др.
Платформа .NET активно развивается – выпускаются все новые версии этой платформы. С помощью меню Project – Properties выясните версию используемой платформы .NET.

Теоретически программа для среды .NET может выполняться под любой операционной системой, в которой .NET установлена. Но на практике единственная официальная платформа для этого — это операционная система Windows. Однако существуют неофициальные реализации .NET для Unix-подобных ОС Linux, Mac OS X и других (Mono — проект системы .NET Framework на базе свободного программного обеспечения).