Napile – идея и практика

в 13:22, , рубрики: java, kotlin, Программирование, метки: ,

Начну с того что объясню, что napile – это язык программирования, и платформа (объяснения почему ниже). Я не буду описать логику языка, а ток то как язык появился и чем он является сейчас(что бы иметь представления что это такое, это смесь явы/котлина)
Что нужно, что бы сделать свой язык программирования?

  1. Идея
  2. Компилятор
  3. Виртуальная машина и байткод (в моем случае)


Идея. Когда то лет 4 назад, я был уже знаком с языком программирования Java, и был знаком с её «граблями» — это генерик, автобоксинг, и другое. И тут у меня зародилась идея поправить эти недостатки. Первое хотелось получить тип генерика в рантайме. Второе NotNull аннотация что бы влияла на код. Третье – удаления из типов «? extends Object». Четвертое – убрать примитивы. И так далее.

Взялся смотреть Sun JDK исходники. Впечатления были ужасные, начиная от строения кода, до системы билда всего JDK. Hotspot – на мое удивления можно было сбилдить через MS Visual Studio, но Java классы, можно было изменять ток через блокнот, подключения к IDE, было невозможным. Связано это с тем что часть кода генерилась из idl файлов, часть из txt файлов(ексепшены из java.lang пакета), и оно не поддавалось ресолвингу через IDE, без лишних движений. Но все же, поставил я Sun VBox, получилось сбилдить JDK, но все же, с наступлением на грабли. Первое хотелось сделать Генерик, и тут я уперся в байткод Java, поэтому появилась мысль что это будет уже не только язык, но и платформа. Немного изменяя код javac, было решено забросить идею “base on javac”. И так я пошёл дальше искать что-то, имея на руках Nerser(декомпилятор /деассемблер с поддержкой java-napile байткода), и napile-jvm(виртуальная машина на Java, которая читает java байткод и запускает его, базово конечно)

И тут пришла идея сделать компилятор на Antlr3(4). Немного поиска по интернету, я нашёл JKit, javac(и что то ещё). Javac on Antlr – это что то, да там есть Antlr но то что они сделали это бред. JKit – интересный компилятор, старый, немного поигравшись я тоже забросил его.
Был ещё один, но я его тоже забросил (уже не помню что это было). В это время я попал на исходники Apache Harmony(R.I.P), посмотрел я структуру, систему строения, и подумал – «какая красота, это первый нормальный JDK что видел». Но пока мне не до Harmony.

Я решил написать свой компилятор на Antlr4. Для этого я даже написал antlr4idea плагин, что бы изменять лексику(хотя бы базово). После удачи и неудач, я уперся в то что мне нужна IDE(так как я люблю менять в IDE и брезгую блокнотом). Я давно уже работаю в IDEA, я решил сделать плагин, выдернул Java реализацию с IDEA CE, и начал менять. Вроде все неплохо, есть «компилятор», и есть IDE – но при изменении кода в компиляторе, приходилось менять в IDE, параллельно. И тут пришла мне идея – зачем отдельный компилятор, если можно взять текущий плагин IDEA, и прицепить генерацию байткода. Так и было сделано. Но в то время я ещё не занимался байткодом, мне пока нужно было сделать логику языка.
Спустя некоторое время, я увидел Котлин. Сначала я его проигнорировал, но взял как то послушал два доклада самого автора Котлина, и второй Светланы Исаковой – скачал исходники и увидел, компилятор и плагин, идут в одной линии, а не параллельно. Было решено взять за основу Котлин. Многие идеи сходились у мну с Котлином, некоторые нет. Начал переделывать, часть логик. Первое – убрать Java под корень. Второе — package level вынести. Спустя некоторые время, синтаксис был подобный тому что было в прев. компиляторе. Так как я не люблю некоторые вещи, и больше придерживаюсь Си названий, функции были переименованы в методы. Я много чего убрал, много чего добавил. И тут стал вопрос – зачем трайты, так как я знал что будет платформа, была дилемма. Выход из дилеммы был просто, я также не любил трайты :-D, в итоге в напильнику появилось множественное наследия. На текущий момент(14.12.2012), к классам, идут ещё traited-classes, то есть классы но без конструкторов, которые могут наследовать ток себе подобных, и могут быть наследованным любым классом. Но пока не про это. Когда я более-менее стабилизовал компилятор, пришло время подумать про байткод и его выполнения. Но что бы что то серозное менять, например С++ виртуальную машину, мне не хватит сил и времени. И тут я вспомнил про свой старый проект, napile-jvm. Но тут стала стена, java байткод, ж не годится. Недолго думая я решил, сделать свой байткод, похожим на Java. Но бинарный байткод – не годится, так как нужно будет делать тузлу, что бы менять его. Так как я любитель XML, долго думать не пришлось. И тут родился либа napile.asm. ObjectASM был толчком, но пришлось писать с нуля. Ибо скок инфы, скок нужно, просто нереально всунуть в Ява байткод. Ну и все, у нас есть ASM, VM, Compiler. Немного поигравшись, я получил долгожданный Hello World.

За все время когда я менял код, я менял синтаксис, менял логики. Так как я имел идею – сделать рантайм генерик, я его сделал. Потестил – все гуд. К генерику, прицепилось создания объекта по генерику – без проблем. И тут появились Type Parameter Constructors. Фабрики как таковые. Nullable типы были ищо в котлине, спс им. Система типов тоже повлекла за собой изменения. Были удалены out/in кейворды с генерика вообще, а кастинг переделан. List может спокойно присваиваются к List. Примитивы были удалены. Добавлены макросы, инъекции и другое.
Я старался не сильно нагружать язык но все же, бывает увлекаюсь. Это очень мелкая часть, что было добавлено и изменено. Некоторые части могут быть удалены мной, со временем, или наоборот добавлены. К тому же пример properties. Сейчас они начинают новую жизнь, ибо на начале они были практически вырезаны.

Текущее время. Начата реализация IO/Threading, но пока нету Inner&Anonym классов, немножко затягивается. Так как я не любитель кодить что-то вне IDEA, я уделяю время на cpp4idea(см. мои репы)
Много вещей игнорированы мной, так как меньше приоритетней. Так как я работаю сам, и немного болею, сложно следить за всем.

Я много чего не написал. Напишу со временем.

Дам ссылки на некоторые примеры языка:

  1. Рантайм генерик
    • Получения класса по генерику — link
    • Конструкторы в генерику — link

  2. Ленивые переменные link
  3. Метод параметр через ссылку — link – их можно юзать не ток в конструкторах
  4. Traited-classes link. На этом примере, видно что он не имеет конструктора, но реализовует методы, и имеет один абстрактный метод
  5. Краткий пример системы типов link
  6. Иньекции
    • Регулярные выражения link
    • Многострочный текст link

  7. Линковка существующего метода, как параметр к анонимному методу link
  8. Множественное наследия link

Ссылки на исходники на ГитХабе

  1. Все что касается языка — link
  2. Все что касается меня — link
  3. Ну и что осталось, промежуточные репы link

Благодарности:

  1. Команде Kotlin
  2. Команде Apache Harmony

PS. Познее я покажу — выполнения в среде IDEA, и постараюсь получше написать.

Автор: VISTALL

Источник

Поделиться

* - обязательные к заполнению поля