diff --git a/README.md b/README.md index 0798a52..961ac84 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ ## О языке Yoptava — это первый в мире язык программирования на русском языке, транслируемый в Java с помощью Runtime компилятора. Yoptava позволяет выбрать определённую лексику для программирования, например: -- [ruptava](https://github.com/Lime-blur/yoptava/blob/main/example/ruptava/Load.ruptava) — классический язык программирования Java на русском языке -- [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/goptava/Load.goptava) — язык программирования Java для гопников и реальных пацанов, основанный на [YoptaScript](http://yopta.space/) -- [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/leptava/Load.leptava) — язык программирования Java использующий старославянскую лексику +- [ruptava](https://github.com/Lime-blur/yoptava/blob/main/example/ruptava) — классический язык программирования Java на русском языке +- [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/goptava) — язык программирования Java для гопников и реальных пацанов, основанный на [YoptaScript](http://yopta.space/) +- [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/leptava) — язык программирования Java использующий старославянскую лексику ## Разработка @@ -64,7 +64,10 @@ public class Main { } ``` -4. Приступайте к написанию русскоязычного Java кода в файле `Load.goptava`, предварительно положив его в папку `goptava` в корне вашего проекта! Примеры реализации: [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_goptava), [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_leptava), [ruptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_ruptava). +4. Приступайте к написанию русскоязычного Java кода в файле `Авторитет.goptava`, предварительно положив его в папку `goptava` в корне вашего проекта! Примеры реализации: + - Goptava: [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/goptava), [example_goptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_goptava) + - Leptava: [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/leptava), [example_leptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_leptava) + - Ruptava: [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/ruptava), [example_leptava](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_ruptava) ## Добавление собственного словаря @@ -142,15 +145,15 @@ public class Main { } ``` -5. После этого можно приступать к написанию кода на вашем языке программирования в файле `Load.myptava`, предварительно положив его в папку `myptava` в корне вашего проекта! Пример реализации: [custom](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_custom). +5. После этого можно приступать к написанию кода на вашем языке программирования в файле `Load.myptava`, предварительно положив его в папку `myptava` в корне вашего проекта! Пример реализации: [myptava](https://github.com/Lime-blur/yoptava/blob/main/example/myptava), [example_custom](https://github.com/Lime-blur/yoptava/blob/main/example/src/main/java/ru/limedev/example/example_custom). ## Проблемы -- Yoptava поддерживает только компиляцию класса `Load`. Очень **приветствуется** доработка языка под компиляцию дерева `.goptava`, `.ruptava`, `.leptava` файлов -- Также **приветствуется** упрощение парсинга файлов в классе [YoptavaParser](https://github.com/Lime-blur/yoptava/blob/main/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java) +- **Приветствуется** упрощение парсинга файлов в классе [YoptavaParser](https://github.com/Lime-blur/yoptava/blob/main/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java) +- **Очень приветствуется** дополнение словарей `goptava`, `ruptava` и `leptava` ## Добавление подсветки синтаксиса Если вы пользуетесь Intellij Idea, вы можете добавить подсветку синтаксиса `.goptava`, `.ruptava`, `.leptava` файлов используя следующие файлы: [Ruptava.txt](https://github.com/Lime-blur/yoptava/blob/main/intellij_settings/editor_filetypes/Ruptava.txt), [Goptava.txt](https://github.com/Lime-blur/yoptava/blob/main/intellij_settings/editor_filetypes/Goptava.txt), [Leptava.txt](https://github.com/Lime-blur/yoptava/blob/main/intellij_settings/editor_filetypes/Leptava.txt). ## Примеры -В файлах [ruptava](https://github.com/Lime-blur/yoptava/blob/main/example/ruptava/Load.ruptava), [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/goptava/Load.goptava) и [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/leptava/Load.leptava) присутствуют примеры использования массивов, мап, циклов, switch-оператора, а также реализации методов. **Приветствуется** дополнение примеров. +В [ruptava](https://github.com/Lime-blur/yoptava/blob/main/example/ruptava), [goptava](https://github.com/Lime-blur/yoptava/blob/main/example/goptava) и [leptava](https://github.com/Lime-blur/yoptava/blob/main/example/leptava) присутствуют примеры использования массивов, мап, циклов, switch-оператора, а также реализации пакетов, классов и методов. diff --git a/example/goptava/Load.goptava b/example/goptava/Load.goptava deleted file mode 100644 index 27e7832..0000000 --- a/example/goptava/Load.goptava +++ /dev/null @@ -1,130 +0,0 @@ -спиздить java.util.КомпахаНаПомойке; -спиздить java.util.Компаха; -спиздить java.util.ШняжныйТубзик; -спиздить java.util.Тубзик; - -ёбанный клёво Load { - - мой попонятиям бачок Компаха<Район> кореши = захуярить КомпахаНаПомойке<Район>() { - { - заебошить("ебанный клёво 1"); - заебошить("ебанный клёво 2"); - заебошить("ебанный клёво 3"); - заебошить("ебанный клёво 4"); - заебошить("ебанный клёво 5"); - } - }; - - мой попонятиям бачок хуйня[][] камераИзХуйни = { - {0, 1, 2, 3, 4}, - {1, 2, 3, 4, 5}, - {2, 3, 4, 5, 6}, - {3, 4, 5, 6, 7} - }; - - мой попонятиям бачок Тубзик<Район, Пацан> записьКтоЕстьКореш = захуярить ШняжныйТубзик<>(); - - попонятиям { - заполнитьКтоЕстьКореш(); - } - - /** - * Типа метод "main" в java. - */ - ёбанный попонятиям беспонтовый load() { - наПечатьКорешей(); - наПечатьКамеруИзХуйни(); - наПечатьКвартируСтукача(); - наПечатьКтоЕстьКореш(); - } - - /** - * Печатает список из корешей с отмычками Goptava. - */ - мой попонятиям беспонтовый наПечатьКорешей() { - го (Район кореш : кореши) { - Система.дверь.строкуНаПечать(кореш); - } - } - - /** - * Печатает камеру из хуйни. - */ - мой попонятиям беспонтовый наПечатьКамеруИзХуйни() { - системноСтрокуНаПечать(""); - го (хуйня i = 0; i < камераИзХуйни.писькомер; i++) { - го (хуйня j = 0; j < камераИзХуйни[i].писькомер; j++) { - системноНаПечать(камераИзХуйни[i][j] + " "); - } - Система.дверь.наПечать("\n"); - } - } - - /** - * Печатает квартиру стукача по падику. - */ - мой попонятиям беспонтовый наПечатьКвартируСтукача() { - Компаха<Район> падик = вычислитьКвартируСтукача(3); - Система.дверь.строкуНаПечать("\nБлижайший падик:"); - го (Район вещь : падик) { - системноСтрокуНаПечать(вещь); - } - } - - /** - * Вычисляет квартиру стукача по падику. - */ - мой попонятиям Компаха<Район> вычислитьКвартируСтукача(хуйня падик) { - Компаха<Район> квартира = захуярить КомпахаНаПомойке<>(); - естьчо (падик) { - аеслинайду 1: квартира.заебошить("Лавэ"); - харэ; - аеслинайду 2: - аеслинайду 4: квартира.заебошить("Семка"); - харэ; - аеслинайду 3: квартира.заебошить("Лавэ"); - квартира.заебошить("Семка"); - квартира.заебошить("Петух"); - харэ; - аеслинайду 5: - аеслинайду 6: квартира.заебошить("Бычки"); - квартира.заебошить("Кент"); - харэ; - аеслинайду 7: - аеслинайду 8: квартира.заебошить("Общак"); - квартира.заебошить("Кент"); - квартира.заебошить("Петух"); - харэ; - апохуй: - харэ; - } - отвечаю квартира; - } - - /** - * Узнаём кто есть мой кореш. - */ - мой попонятиям беспонтовый заполнитьКтоЕстьКореш() { - записьКтоЕстьКореш.насрать("Жэка", трулио); - записьКтоЕстьКореш.насрать("Димас", нетрулио); - записьКтоЕстьКореш.насрать("Лёня", трулио); - записьКтоЕстьКореш.насрать("Петро", нетрулио); - записьКтоЕстьКореш.насрать("Саня", трулио); - записьКтоЕстьКореш.насрать("Артём", трулио); - записьКтоЕстьКореш.насрать("Лёха", нетрулио); - } - - /** - * На печать кто есть мой кореш. - */ - мой попонятиям беспонтовый наПечатьКтоЕстьКореш() { - системноСтрокуНаПечать("\nКореши, не кореши:"); - го (Тубзик.КучаГовна<Район, Пацан> запись : записьКтоЕстьКореш.насранаяКучаГовна()) { - вилкойвглаз (запись.вычислитьГовно() == чотко) { - Система.дверь.строкуНаПечать(запись.вычислитьКучу() + " уважуха!"); - } иливжопураз { - Система.папандос.строкуНаПечать(запись.вычислитьКучу() + " канай отсюда!"); - } - } - } -} diff --git "a/example/goptava/model/base/\320\221\320\260\321\202\321\217\320\234\320\276\320\264\320\265\320\273\321\214.goptava" "b/example/goptava/model/base/\320\221\320\260\321\202\321\217\320\234\320\276\320\264\320\265\320\273\321\214.goptava" new file mode 100644 index 0000000..17951cb --- /dev/null +++ "b/example/goptava/model/base/\320\221\320\260\321\202\321\217\320\234\320\276\320\264\320\265\320\273\321\214.goptava" @@ -0,0 +1,8 @@ +клеёнка model.base; + +ёбанный хуёво БатяМодель { + + Район вычислитьИмя(); + + Район вычислитьХуйЗнаетЧто(); +} \ No newline at end of file diff --git "a/example/goptava/model/\320\241\321\202\321\203\320\272\320\260\321\207.goptava" "b/example/goptava/model/\320\241\321\202\321\203\320\272\320\260\321\207.goptava" new file mode 100644 index 0000000..fc4d8e1 --- /dev/null +++ "b/example/goptava/model/\320\241\321\202\321\203\320\272\320\260\321\207.goptava" @@ -0,0 +1,29 @@ +клеёнка model; + +спиздить model.base.БатяМодель; + +ёбанный бачок клёво Стукач силикон БатяМодель { + + мой бачок Район имяСтукача; + мой бачок Район чоБыСпиздить; + + ёбанный Стукач(Район имяСтукача, Район чоБыСпиздить) { + тырыпыры.имяСтукача = имяСтукача; + тырыпыры.чоБыСпиздить = чоБыСпиздить; + } + + @Перебить + ёбанный Район вычислитьИмя() { + отвечаю тырыпыры.имяСтукача; + } + + @Перебить + ёбанный Район вычислитьХуйЗнаетЧто() { + отвечаю тырыпыры.чоБыСпиздить; + } + + @Перебить + ёбанный Район поПацански() { + отвечаю "Слышь, " + имяСтукача + ", " + чоБыСпиздить + " есть? А если найду?"; + } +} \ No newline at end of file diff --git "a/example/goptava/model/\320\247\320\270\320\272\320\260.goptava" "b/example/goptava/model/\320\247\320\270\320\272\320\260.goptava" new file mode 100644 index 0000000..bf68391 --- /dev/null +++ "b/example/goptava/model/\320\247\320\270\320\272\320\260.goptava" @@ -0,0 +1,29 @@ +клеёнка model; + +спиздить model.base.БатяМодель; + +ёбанный бачок клёво Чика силикон БатяМодель { + + мой бачок Район имяЧики; + мой бачок Район чоБыГлянуть; + + ёбанный Чика(Район имяЧики, Район чоБыГлянуть) { + тырыпыры.имяЧики = имяЧики; + тырыпыры.чоБыГлянуть = чоБыГлянуть; + } + + @Перебить + ёбанный Район вычислитьИмя() { + отвечаю тырыпыры.имяЧики; + } + + @Перебить + ёбанный Район вычислитьХуйЗнаетЧто() { + отвечаю тырыпыры.чоБыГлянуть; + } + + @Перебить + ёбанный Район поПацански() { + отвечаю "Ля какая " + имяЧики + ", " + чоБыГлянуть + " покажешь?"; + } +} \ No newline at end of file diff --git "a/example/goptava/\320\220\320\262\321\202\320\276\321\200\320\270\321\202\320\265\321\202.goptava" "b/example/goptava/\320\220\320\262\321\202\320\276\321\200\320\270\321\202\320\265\321\202.goptava" new file mode 100644 index 0000000..8ff5050 --- /dev/null +++ "b/example/goptava/\320\220\320\262\321\202\320\276\321\200\320\270\321\202\320\265\321\202.goptava" @@ -0,0 +1,133 @@ +спиздить java.util.КомпахаНаПомойке; +спиздить java.util.Компаха; +спиздить java.util.ШняжныйТубзик; +спиздить java.util.Тубзик; + +спиздить model.Стукач; +спиздить model.Чика; + +ёбанный клёво Авторитет { + + мой попонятиям бачок Компаха<Район> кореши = захуярить КомпахаНаПомойке<Район>() { + { + заебошить("ебанный клёво 1"); + заебошить("ебанный клёво 2"); + заебошить("ебанный клёво 3"); + заебошить("ебанный клёво 4"); + заебошить("ебанный клёво 5"); + } + }; + + мой попонятиям бачок хуйня[][] камераИзХуйни = { + {0, 1, 2, 3, 4}, + {1, 2, 3, 4, 5}, + {2, 3, 4, 5, 6}, + {3, 4, 5, 6, 7} + }; + + мой попонятиям бачок Тубзик<Чика, Пацан> списокХорошихЧик = захуярить ШняжныйТубзик<>(); + + попонятиям { + заполнитьСписокЧик(); + } + + /** + * Типа метод "main" в java. + */ + ёбанный попонятиям беспонтовый кукуЁпта() { + наПечатьКорешей(); + наПечатьКамеруИзХуйни(); + наПечатьСходкуСтукача(); + наПечатьСписокХорошихЧик(); + } + + /** + * Печатает список из корешей с отмычками Goptava. + */ + мой попонятиям беспонтовый наПечатьКорешей() { + го (Район кореш : кореши) { + Система.дверь.строкуНаПечать(кореш); + } + } + + /** + * Печатает камеру из хуйни. + */ + мой попонятиям беспонтовый наПечатьКамеруИзХуйни() { + системноСтрокуНаПечать(""); + го (хуйня i = 0; i < камераИзХуйни.писькомер; i++) { + го (хуйня j = 0; j < камераИзХуйни[i].писькомер; j++) { + системноНаПечать(камераИзХуйни[i][j] + " "); + } + Система.дверь.наПечать("\n"); + } + } + + /** + * Печатает сходку стукача по падику. + */ + мой попонятиям беспонтовый наПечатьСходкуСтукача() { + Компаха<Стукач> падик = вычислитьСходкуСтукача(3); + Система.дверь.строкуНаПечать("\nЧистим сходку стукача:"); + го (Стукач стукач : падик) { + системноСтрокуНаПечать(стукач.поПацански()); + } + } + + /** + * Вычисляет сходку стукача по падику. + */ + мой попонятиям Компаха<Стукач> вычислитьСходкуСтукача(хуйня падик) { + Компаха<Стукач> сходка = захуярить КомпахаНаПомойке<>(); + естьчо (падик) { + аеслинайду 1: сходка.заебошить(захуярить Стукач("Пидор", "Лавэ")); + харэ; + аеслинайду 2: + аеслинайду 4: сходка.заебошить(захуярить Стукач("Петух", "Семки")); + харэ; + аеслинайду 3: сходка.заебошить(захуярить Стукач("Поцык, поцык", "Лавэ")); + сходка.заебошить(захуярить Стукач("Ля какая цыпа", "Семки")); + сходка.заебошить(захуярить Стукач("Ботан", "Хабар")); + харэ; + аеслинайду 5: + аеслинайду 6: сходка.заебошить(захуярить Стукач("Ботан", "Бычки")); + сходка.заебошить(захуярить Стукач("Кент", "Семки")); + харэ; + аеслинайду 7: + аеслинайду 8: сходка.заебошить(захуярить Стукач("Пиздюк", "Лавэ")); + сходка.заебошить(захуярить Стукач("Кент", "Лавэээ")); + сходка.заебошить(захуярить Стукач("Петух", "Семки")); + харэ; + апохуй: + харэ; + } + отвечаю сходка; + } + + /** + * Узнаём хороших чик. + */ + мой попонятиям беспонтовый заполнитьСписокЧик() { + списокХорошихЧик.насрать(захуярить Чика("Машка", "Сиськи"), трулио); + списокХорошихЧик.насрать(захуярить Чика("Ленка", "Сиськи и жопу"), нетрулио); + списокХорошихЧик.насрать(захуярить Чика("Дашка", "Жопу"), трулио); + списокХорошихЧик.насрать(захуярить Чика("Наташка", "Сисек нет, но всё равно"), нетрулио); + списокХорошихЧик.насрать(захуярить Чика("Ольга", "Глаза"), трулио); + списокХорошихЧик.насрать(захуярить Чика("Вероника", "Айфон"), трулио); + списокХорошихЧик.насрать(захуярить Чика("Ирка", "Сиськи"), нетрулио); + } + + /** + * На печать хороших чик. + */ + мой попонятиям беспонтовый наПечатьСписокХорошихЧик() { + системноСтрокуНаПечать("\nКароче:"); + го (Тубзик.КучаГовна<Чика, Пацан> запись : списокХорошихЧик.насранаяКучаГовна()) { + вилкойвглаз (запись.вычислитьГовно() == чотко) { + Система.дверь.строкуНаПечать(запись.вычислитьКучу().поПацански() + " Клёво! Слыш, ты это, может сходим куда-нибудь?"); + } иливжопураз { + Система.папандос.строкуНаПечать(запись.вычислитьКучу().поПацански() + " Нет? Да и хуй с ней!"); + } + } + } +} diff --git "a/example/leptava/model/base/\320\221\320\260\321\207\320\272\320\276\320\234\320\276\320\264\320\265\320\273\321\214.leptava" "b/example/leptava/model/base/\320\221\320\260\321\207\320\272\320\276\320\234\320\276\320\264\320\265\320\273\321\214.leptava" new file mode 100644 index 0000000..53970eb --- /dev/null +++ "b/example/leptava/model/base/\320\221\320\260\321\207\320\272\320\276\320\234\320\276\320\264\320\265\320\273\321\214.leptava" @@ -0,0 +1,8 @@ +кулёкъ model.base; + +польный здатель БачкоМодель { + + Береста поятиПрозвание(); + + Береста поятиВъторПрозвание(); +} \ No newline at end of file diff --git "a/example/leptava/model/\320\224\321\200\321\203\320\266\320\270\320\275\320\275\320\270\320\272\320\250\320\265\320\273\320\276\320\274.leptava" "b/example/leptava/model/\320\224\321\200\321\203\320\266\320\270\320\275\320\275\320\270\320\272\320\250\320\265\320\273\320\276\320\274.leptava" new file mode 100644 index 0000000..59aa1fb --- /dev/null +++ "b/example/leptava/model/\320\224\321\200\321\203\320\266\320\270\320\275\320\275\320\270\320\272\320\250\320\265\320\273\320\276\320\274.leptava" @@ -0,0 +1,29 @@ +кулёкъ model; + +въсхытити model.base.БачкоМодель; + +польный заговенный видъ ДружинникШелом зракъ БачкоМодель { + + омженный заговенный Береста дружинник; + омженный заговенный Береста шелом; + + польный ДружинникШелом(Береста дружинник, Береста шелом) { + овый.дружинник = дружинник; + овый.шелом = шелом; + } + + @Переопределити + польный Береста поятиПрозвание() { + подати овый.дружинник; + } + + @Переопределити + польный Береста поятиВъторПрозвание() { + подати овый.шелом; + } + + @Переопределити + польный Береста кБересте() { + подати дружинник + " носитъ " + шелом; + } +} \ No newline at end of file diff --git "a/example/leptava/model/\320\232\320\260\320\273\321\203\320\263\320\265\321\200\320\256\320\266\320\270\320\272.leptava" "b/example/leptava/model/\320\232\320\260\320\273\321\203\320\263\320\265\321\200\320\256\320\266\320\270\320\272.leptava" new file mode 100644 index 0000000..294e233 --- /dev/null +++ "b/example/leptava/model/\320\232\320\260\320\273\321\203\320\263\320\265\321\200\320\256\320\266\320\270\320\272.leptava" @@ -0,0 +1,29 @@ +кулёкъ model; + +въсхытити model.base.БачкоМодель; + +польный заговенный видъ КалугерЮжик зракъ БачкоМодель { + + омженный заговенный Береста калугер; + омженный заговенный Береста южик; + + польный КалугерЮжик(Береста калугер, Береста южик) { + овый.калугер = калугер; + овый.южик = южик; + } + + @Переопределити + польный Береста поятиПрозвание() { + подати овый.калугер; + } + + @Переопределити + польный Береста поятиВъторПрозвание() { + подати овый.южик; + } + + @Переопределити + польный Береста кБересте() { + подати калугер + " имаетъ южика " + южик; + } +} \ No newline at end of file diff --git a/example/leptava/Load.leptava "b/example/leptava/\320\230\321\201\321\202\320\276\320\265.leptava" similarity index 50% rename from example/leptava/Load.leptava rename to "example/leptava/\320\230\321\201\321\202\320\276\320\265.leptava" index d37cb6f..8fb58e4 100644 --- a/example/leptava/Load.leptava +++ "b/example/leptava/\320\230\321\201\321\202\320\276\320\265.leptava" @@ -3,7 +3,10 @@ въсхытити java.util.РудныйРеестръ; въсхытити java.util.Реестръ; -польный видъ Load { +въсхытити model.КалугерЮжик; +въсхытити model.ДружинникШелом; + +польный видъ Истое { омжённый неумытный заговенный Противень<Береста> ключьныеГлаголы = създати РядПротивеня<Береста>() { { @@ -22,16 +25,16 @@ {3, 4, 5, 6, 7} }; - омжённый неумытный заговенный Реестръ<Береста, Прелестный> реестрДружины = създати РудныйРеестръ<>(); + омжённый неумытный заговенный Реестръ<ДружинникШелом, Прелестный> реестрДружины = създати РудныйРеестръ<>(); неумытный { заполнитиРеестрДружины(); } /** - * Альтернатива методу "main" в java. + * Альтернатива метода "main" в java. */ - польный неумытный заточный load() { + польный неумытный заточный истое() { распечататиПротивеньИзБересты(); распечататиМрежу(); распечататиКалугеров(); @@ -64,36 +67,36 @@ * Печатаетъ рядъ калугеровъ града. */ омжённый неумытный заточный распечататиКалугеров() { - Противень<Береста> калугеры = поятиКалугеров(3); + Противень<КалугерЮжик> калугеры = поятиКалугеров(3); распечататиСистемойБересту("\nРядъ калугеров града 3:"); - деля (Береста калугер : калугеры) { - Система.застава.распечататиБересту(калугер); + деля (КалугерЮжик калугер : калугеры) { + Система.застава.распечататиБересту(калугер.кБересте()); } } /** * Определяетъ калугеров по личьбе града. */ - омжённый неумытный Противень<Береста> поятиКалугеров(личьба личьбаГрада) { - Противень<Береста> калугеры = създати РядПротивеня<>(); + омжённый неумытный Противень<КалугерЮжик> поятиКалугеров(личьба личьбаГрада) { + Противень<КалугерЮжик> калугеры = създати РядПротивеня<>(); внегда (личьбаГрада) { - убо 1: калугеры.бавить("Богомил"); + убо 1: калугеры.бавить(създати КалугерЮжик("Богомил", "Всесвет")); охабить; убо 2: - убо 4: калугеры.бавить("Вышеслав"); + убо 4: калугеры.бавить(създати КалугерЮжик("Вышеслав", "Борислав")); охабить; - убо 3: калугеры.бавить("Драгомир"); - калугеры.бавить("Завид"); - калугеры.бавить("Изяслав"); + убо 3: калугеры.бавить(създати КалугерЮжик("Драгомир", "Горецвет")); + калугеры.бавить(създати КалугерЮжик("Завид", "Гойник")); + калугеры.бавить(създати КалугерЮжик("Изяслав", "Далибор")); охабить; убо 5: - убо 6: калугеры.бавить("Любиград"); - калугеры.бавить("Пересвет"); + убо 6: калугеры.бавить(създати КалугерЮжик("Любиград", "Жировит")); + калугеры.бавить(създати КалугерЮжик("Пересвет", "Златомир")); охабить; убо 7: - убо 8: калугеры.бавить("Стоян"); - калугеры.бавить("Чеслав"); - калугеры.бавить("Ясномысл"); + убо 8: калугеры.бавить(създати КалугерЮжик("Стоян", "Клонимир")); + калугеры.бавить(създати КалугерЮжик("Чеслав", "Людевит")); + калугеры.бавить(създати КалугерЮжик("Ясномысл", "Малобуд")); охабить; беспроторица: охабить; @@ -105,15 +108,15 @@ * Заполняетъ реестръ дружины. */ омжённый неумытный заточный заполнитиРеестрДружины() { - реестрДружины.положити("Боян", реснота); - реестрДружины.положити("Веселин", лесть); - реестрДружины.положити("Всесвет", реснота); - реестрДружины.положити("Драган", лесть); - реестрДружины.положити("Збигнев", реснота); - реестрДружины.положити("Лютой", реснота); - реестрДружины.положити("Мстивой", лесть); - реестрДружины.положити("Невзор", реснота); - реестрДружины.положити("Радовлад", лесть); + реестрДружины.положити(създати ДружинникШелом("Боян", "Шелом Всеволодовича"), реснота); + реестрДружины.положити(създати ДружинникШелом("Веселин", "Вендельский шелом"), лесть); + реестрДружины.положити(създати ДружинникШелом("Всесвет", "Шелом Всеволодовича"), реснота); + реестрДружины.положити(създати ДружинникШелом("Драган", "Вендельский шелом"), лесть); + реестрДружины.положити(създати ДружинникШелом("Збигнев", "Шелом Всеволодовича"), реснота); + реестрДружины.положити(създати ДружинникШелом("Лютой", "Шелом Всеволодовича"), реснота); + реестрДружины.положити(създати ДружинникШелом("Мстивой", "Вендельский шелом"), лесть); + реестрДружины.положити(създати ДружинникШелом("Невзор", "Шелом из Никольского"), реснота); + реестрДружины.положити(създати ДружинникШелом("Радовлад", "Вендельский шелом"), лесть); } /** @@ -121,11 +124,11 @@ */ омжённый неумытный заточный проверитиРеестрДружины() { распечататиСистемойБересту("\nРеестръ дружины:"); - деля (Реестръ.СрокРеестра<Береста, Прелестный> срокРеестра : реестрДружины.съвъкупностьСроковРеестра()) { + деля (Реестръ.СрокРеестра<ДружинникШелом, Прелестный> срокРеестра : реестрДружины.съвъкупностьСроковРеестра()) { аще (срокРеестра.поятиЗнакъ() == реснота) { - Система.застава.распечататиБересту(срокРеестра.поятиКлючь() + " въ реестре!"); + Система.застава.распечататиБересту(срокРеестра.поятиКлючь().кБересте() + " и въ реестре!"); } або { - Система.залазъ.распечататиБересту(срокРеестра.поятиКлючь() + " не въ реестре!"); + Система.залазъ.распечататиБересту(срокРеестра.поятиКлючь().кБересте() + " и не въ реестре!"); } } } diff --git a/example/pom.xml b/example/pom.xml index 52d27a5..ea46dda 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -31,7 +31,7 @@ com.github.Lime-blur yoptava - 2.0 + 2.1 \ No newline at end of file diff --git "a/example/ruptava/model/base/\320\221\320\260\320\267\320\276\320\262\320\260\321\217\320\234\320\276\320\264\320\265\320\273\321\214.ruptava" "b/example/ruptava/model/base/\320\221\320\260\320\267\320\276\320\262\320\260\321\217\320\234\320\276\320\264\320\265\320\273\321\214.ruptava" new file mode 100644 index 0000000..a69bbd0 --- /dev/null +++ "b/example/ruptava/model/base/\320\221\320\260\320\267\320\276\320\262\320\260\321\217\320\234\320\276\320\264\320\265\320\273\321\214.ruptava" @@ -0,0 +1,8 @@ +пакет model.base; + +публичный интерфейс БазоваяМодель { + + Строка получитьНазвание(); + + Строка получитьВтороеНазвание(); +} \ No newline at end of file diff --git "a/example/ruptava/model/\320\230\320\274\321\217\320\244\320\260\320\274\320\270\320\273\320\270\321\217.ruptava" "b/example/ruptava/model/\320\230\320\274\321\217\320\244\320\260\320\274\320\270\320\273\320\270\321\217.ruptava" new file mode 100644 index 0000000..689e280 --- /dev/null +++ "b/example/ruptava/model/\320\230\320\274\321\217\320\244\320\260\320\274\320\270\320\273\320\270\321\217.ruptava" @@ -0,0 +1,29 @@ +пакет model; + +импортировать model.base.БазоваяМодель; + +публичный конечный класс ИмяФамилия реализует БазоваяМодель { + + приватный конечный Строка имя; + приватный конечный Строка фамилия; + + публичный ИмяФамилия(Строка имя, Строка фамилия) { + этот.имя = имя; + этот.фамилия = фамилия; + } + + @Переопределить + публичный Строка получитьНазвание() { + вернуть этот.имя; + } + + @Переопределить + публичный Строка получитьВтороеНазвание() { + вернуть этот.фамилия; + } + + @Переопределить + публичный Строка кСтроке() { + вернуть имя + " " + фамилия; + } +} \ No newline at end of file diff --git "a/example/ruptava/model/\320\245\320\270\320\274\320\270\321\207\320\265\321\201\320\272\320\270\320\271\320\255\320\273\320\265\320\274\320\265\320\275\321\202.ruptava" "b/example/ruptava/model/\320\245\320\270\320\274\320\270\321\207\320\265\321\201\320\272\320\270\320\271\320\255\320\273\320\265\320\274\320\265\320\275\321\202.ruptava" new file mode 100644 index 0000000..4e9e198 --- /dev/null +++ "b/example/ruptava/model/\320\245\320\270\320\274\320\270\321\207\320\265\321\201\320\272\320\270\320\271\320\255\320\273\320\265\320\274\320\265\320\275\321\202.ruptava" @@ -0,0 +1,29 @@ +пакет model; + +импортировать model.base.БазоваяМодель; + +публичный конечный класс ХимическийЭлемент реализует БазоваяМодель { + + приватный конечный Строка название; + приватный конечный Строка символЭлемента; + + публичный ХимическийЭлемент(Строка название, Строка символЭлемента) { + этот.название = название; + этот.символЭлемента = символЭлемента; + } + + @Переопределить + публичный Строка получитьНазвание() { + вернуть этот.название; + } + + @Переопределить + публичный Строка получитьВтороеНазвание() { + вернуть этот.символЭлемента; + } + + @Переопределить + публичный Строка кСтроке() { + вернуть название + " (" + символЭлемента + ")"; + } +} \ No newline at end of file diff --git a/example/ruptava/Load.ruptava "b/example/ruptava/\320\223\320\273\320\260\320\262\320\275\321\213\320\271.ruptava" similarity index 56% rename from example/ruptava/Load.ruptava rename to "example/ruptava/\320\223\320\273\320\260\320\262\320\275\321\213\320\271.ruptava" index ed504d7..e6354d3 100644 --- a/example/ruptava/Load.ruptava +++ "b/example/ruptava/\320\223\320\273\320\260\320\262\320\275\321\213\320\271.ruptava" @@ -3,7 +3,10 @@ импортировать java.util.ХэшКарта; импортировать java.util.Карта; -публичный класс Load { +импортировать model.ИмяФамилия; +импортировать model.ХимическийЭлемент; + +публичный класс Главный { приватный статический конечный Список<Строка> ключевыеСтроки = новый СписокМассива<Строка>() { { @@ -22,16 +25,16 @@ {3, 4, 5, 6, 7} }; - приватный статический конечный Карта<Строка, Логический> журнал = новый ХэшКарта<>(); + приватный статический конечный Карта<ИмяФамилия, Логический> журнал = новый ХэшКарта<>(); статический { заполнитьЖурнал(); } /** - * Альтернатива методу "main" в java. + * Альтернатива метода "main" в java. */ - публичный статический пустой load() { + публичный статический пустой главный() { распечататьСтроки(); распечататьМатрицу(); распечататьАтмосферуПланеты(); @@ -64,36 +67,36 @@ * Печатает атмосферу планеты Земля. */ приватный статический пустой распечататьАтмосферуПланеты() { - Список<Строка> атмосфера = получитьАтмосферуПланеты(3); + Список<ХимическийЭлемент> атмосфера = получитьАтмосферуПланеты(3); системноРаспечататьСтроку("\nАтмосфера планеты \"Земля\" состоит из:"); - для (Строка компонент : атмосфера) { - Система.вывод.распечататьСтроку(компонент); + для (ХимическийЭлемент химическийЭлемент : атмосфера) { + Система.вывод.распечататьСтроку(химическийЭлемент.кСтроке()); } } /** * Определяет атмосферу планеты по значению номерОтСолнца. */ - приватный статический Список<Строка> получитьАтмосферуПланеты(целый номерОтСолнца) { - Список<Строка> результат = новый СписокМассива<>(); + приватный статический Список<ХимическийЭлемент> получитьАтмосферуПланеты(целый номерОтСолнца) { + Список<ХимическийЭлемент> результат = новый СписокМассива<>(); когда (номерОтСолнца) { - случай 1: результат.добавить("Нет атмосферы"); + случай 1: результат.добавить(новый ХимическийЭлемент("Нет атмосферы", "?")); прервать; случай 2: - случай 4: результат.добавить("Углекислый газ"); + случай 4: результат.добавить(новый ХимическийЭлемент("Углекислый газ", "CO2")); прервать; - случай 3: результат.добавить("Углекислый газ"); - результат.добавить("Азот"); - результат.добавить("Кислород"); + случай 3: результат.добавить(новый ХимическийЭлемент("Углекислый газ", "CO2")); + результат.добавить(новый ХимическийЭлемент("Азот", "N2")); + результат.добавить(новый ХимическийЭлемент("Кислород", "O2")); прервать; случай 5: - случай 6: результат.добавить("Водород"); - результат.добавить("Гелий"); + случай 6: результат.добавить(новый ХимическийЭлемент("Водород", "H2")); + результат.добавить(новый ХимическийЭлемент("Гелий", "He")); прервать; случай 7: - случай 8: результат.добавить("Метан"); - результат.добавить("Водород"); - результат.добавить("Гелий"); + случай 8: результат.добавить(новый ХимическийЭлемент("Метан", "CH4")); + результат.добавить(новый ХимическийЭлемент("Водород", "H2")); + результат.добавить(новый ХимическийЭлемент("Гелий", "He")); прервать; стандартный: прервать; @@ -105,15 +108,15 @@ * Заполняет журнал посещаемости учащихся. */ приватный статический пустой заполнитьЖурнал() { - журнал.положить("Ваня", правда); - журнал.положить("Женя", ложь); - журнал.положить("Дима", правда); - журнал.положить("Петя", ложь); - журнал.положить("Коля", правда); - журнал.положить("Лена", правда); - журнал.положить("Катя", ложь); - журнал.положить("Таня", правда); - журнал.положить("Галя", ложь); + журнал.положить(новый ИмяФамилия("Ваня", "Карпов"), правда); + журнал.положить(новый ИмяФамилия("Женя", "Власов"), ложь); + журнал.положить(новый ИмяФамилия("Дима", "Сафонов"), правда); + журнал.положить(новый ИмяФамилия("Петя", "Шаров"), ложь); + журнал.положить(новый ИмяФамилия("Коля", "Щукин"), правда); + журнал.положить(новый ИмяФамилия("Лена", "Якушева"), правда); + журнал.положить(новый ИмяФамилия("Катя", "Шашкова"), ложь); + журнал.положить(новый ИмяФамилия("Таня", "Рожкова"), правда); + журнал.положить(новый ИмяФамилия("Галя", "Селезнёва"), ложь); } /** @@ -121,11 +124,11 @@ */ приватный статический пустой проверитьПосещаемость() { системноРаспечататьСтроку("\nПроверяем посещаемость:"); - для (Карта.Запись<Строка, Логический> запись : журнал.наборЗаписей()) { + для (Карта.Запись<ИмяФамилия, Логический> запись : журнал.наборЗаписей()) { если (запись.получитьЗначение() == правда) { - Система.вывод.распечататьСтроку(запись.получитьКлюч() + " здесь, молодец!"); + Система.вывод.распечататьСтроку(запись.получитьКлюч().кСтроке() + " здесь, молодец!"); } иначе { - Система.ошибка.распечататьСтроку(запись.получитьКлюч() + " отсутствует, плохо!"); + Система.ошибка.распечататьСтроку(запись.получитьКлюч().кСтроке() + " отсутствует, плохо!"); } } } diff --git a/intellij_settings/editor_filetypes/Goptava.txt b/intellij_settings/editor_filetypes/Goptava.txt index a41cf3b..2b83b73 100644 --- a/intellij_settings/editor_filetypes/Goptava.txt +++ b/intellij_settings/editor_filetypes/Goptava.txt @@ -89,6 +89,7 @@ Support paired parens: ✓ Support string escapes: ✓ порожняк -- Keywords 2 -- +@Перебить -- Keywords 3 -- системноНаПечать diff --git a/intellij_settings/editor_filetypes/Leptava.txt b/intellij_settings/editor_filetypes/Leptava.txt index 4881b67..c693c92 100644 --- a/intellij_settings/editor_filetypes/Leptava.txt +++ b/intellij_settings/editor_filetypes/Leptava.txt @@ -68,6 +68,7 @@ Support paired parens: ✓ Support string escapes: ✓ ничтожевелие -- Keywords 2 -- +@Переопределити -- Keywords 3 -- распечататиСистемой diff --git a/intellij_settings/editor_filetypes/Ruptava.txt b/intellij_settings/editor_filetypes/Ruptava.txt index a6a9780..b10ae98 100644 --- a/intellij_settings/editor_filetypes/Ruptava.txt +++ b/intellij_settings/editor_filetypes/Ruptava.txt @@ -67,6 +67,7 @@ Support paired parens: ✓ Support string escapes: ✓ нулевой -- Keywords 2 -- +@Переопределить -- Keywords 3 -- системноРаспечатать diff --git a/pom.xml b/pom.xml index 693a61d..0cbcdc9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,11 +21,6 @@ - - com.itranswarp - compiler - 1.0 - org.jetbrains annotations diff --git a/src/main/java/ru/limedev/yoptava/Yoptava.java b/src/main/java/ru/limedev/yoptava/Yoptava.java index 5b1c2d8..e5d5982 100644 --- a/src/main/java/ru/limedev/yoptava/Yoptava.java +++ b/src/main/java/ru/limedev/yoptava/Yoptava.java @@ -1,8 +1,8 @@ package ru.limedev.yoptava; -import com.itranswarp.compiler.JavaStringCompiler; import ru.limedev.yoptava.cache.CacheUtils; -import ru.limedev.yoptava.core.StringUtils; +import ru.limedev.yoptava.compiler.RuntimeCompiler; +import ru.limedev.yoptava.compiler.exception.CompilationException; import ru.limedev.yoptava.files.FileUtils; import ru.limedev.yoptava.files.YoptavaFileUtils; import ru.limedev.yoptava.settings.GoptavaSettings; @@ -13,14 +13,9 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; public final class Yoptava { - private static final Map contents = new HashMap<>(); - private static final Map> compileResults = new HashMap<>(); - /** * Initializes Goptava classes with default settings. */ @@ -49,12 +44,12 @@ public static void initRuptava() { * Initializes Yoptava classes with {@link YoptavaSettings}. */ public static void init(YoptavaSettings settings) { - JavaStringCompiler compiler = new JavaStringCompiler(); + RuntimeCompiler compiler = new RuntimeCompiler(); try { prepareCache(settings); - loadClasses(settings); + convertClasses(settings); compileClasses(compiler); - loadClasses(compiler, settings); + runMainClass(compiler, settings); } catch (Exception e) { e.printStackTrace(); } @@ -62,7 +57,7 @@ public static void init(YoptavaSettings settings) { } private static void prepareCache(YoptavaSettings settings) throws IOException { - CacheUtils.refreshCacheDirectory(); + CacheUtils.refreshCache(); YoptavaFileUtils.createSourcesInCacheDirectory(settings); String sourcesDirectory = YoptavaFileUtils.getSourcesDirectory(settings); for (String file : FileUtils.listShortFilesPath(sourcesDirectory, settings)) { @@ -71,40 +66,31 @@ private static void prepareCache(YoptavaSettings settings) throws IOException { } private static void clearCache() { - CacheUtils.clearCacheDirectory(); + CacheUtils.clearCache(); } - private static void loadClasses(YoptavaSettings settings) throws IOException { + private static void convertClasses(YoptavaSettings settings) throws IOException { String sourcesDirectory = YoptavaFileUtils.getSourcesDirectory(settings); - for (String file : FileUtils.listShortFilesPath(sourcesDirectory, settings)) { - String javaFile = YoptavaFileUtils.getCachedYoptavaName(file, settings); - contents.put( - javaFile, YoptavaFileUtils.readYoptavaFromCache(javaFile, settings) - ); + for (String file : FileUtils.listFilesPath(sourcesDirectory)) { + String javaFile = YoptavaFileUtils.getCachedYoptavaShortPath(file, settings); + YoptavaFileUtils.convertCachedYoptava(javaFile, settings); } } - private static void compileClasses(JavaStringCompiler compiler) throws IOException { - for (Map.Entry entry : contents.entrySet()) { - compileResults.put( - entry.getKey(), - compiler.compile(entry.getKey(), entry.getValue()) - ); - } + private static void compileClasses(RuntimeCompiler compiler) throws CompilationException { + compiler.setClassesDir(CacheUtils.CLASSES_DIRECTORY); + compiler.setSourceDir(CacheUtils.getCacheDirectory()); + compiler.compile(); + compiler.loadClassesFromCompiledDirectory(); } - private static void loadClasses(JavaStringCompiler compiler, YoptavaSettings settings) throws - IOException, - ClassNotFoundException, + private static void runMainClass(RuntimeCompiler compiler, YoptavaSettings settings) throws + CompilationException, + InvocationTargetException, IllegalAccessException, - NoSuchMethodException, - InvocationTargetException { - Class mainClass = null; - for (Map.Entry> entry : compileResults.entrySet()) { - String className = entry.getKey().replace(FileUtils.JAVA_EXTENSION, StringUtils.EMPTY_STRING); - Class clazz = compiler.loadClass(className, entry.getValue()); - if (className.equals(settings.getMainClassName())) mainClass = clazz; - } + NoSuchMethodException { + String mainClassName = settings.getMainClassName(); + Class mainClass = compiler.getClassFromCompiledDirectory(mainClassName); runMainClass(mainClass, settings); } diff --git a/src/main/java/ru/limedev/yoptava/cache/CacheUtils.java b/src/main/java/ru/limedev/yoptava/cache/CacheUtils.java index 7fe0be0..1b05fb8 100644 --- a/src/main/java/ru/limedev/yoptava/cache/CacheUtils.java +++ b/src/main/java/ru/limedev/yoptava/cache/CacheUtils.java @@ -9,17 +9,41 @@ public final class CacheUtils { public static final String CACHE_DIRECTORY = ".cache"; + public static final String CLASSES_DIRECTORY = ".classes"; public static Path getCacheDirectory() { return FileUtils.getAbsolutePath(CACHE_DIRECTORY); } + public static Path getClassesDirectory() { + return FileUtils.getAbsolutePath(CLASSES_DIRECTORY); + } + public static void refreshCacheDirectory() throws IOException { clearCacheDirectory(); Files.createDirectory(getCacheDirectory()); } + public static void refreshClassesDirectory() throws IOException { + clearClassesDirectory(); + Files.createDirectory(getClassesDirectory()); + } + public static void clearCacheDirectory() { FileUtils.deleteDirectory(getCacheDirectory().toFile()); } + + public static void clearClassesDirectory() { + FileUtils.deleteDirectory(getClassesDirectory().toFile()); + } + + public static void refreshCache() throws IOException { + refreshCacheDirectory(); + refreshClassesDirectory(); + } + + public static void clearCache() { + clearCacheDirectory(); + clearClassesDirectory(); + } } diff --git a/src/main/java/ru/limedev/yoptava/compiler/RuntimeCompiler.java b/src/main/java/ru/limedev/yoptava/compiler/RuntimeCompiler.java new file mode 100644 index 0000000..a7e36d4 --- /dev/null +++ b/src/main/java/ru/limedev/yoptava/compiler/RuntimeCompiler.java @@ -0,0 +1,135 @@ +package ru.limedev.yoptava.compiler; + +import ru.limedev.yoptava.compiler.exception.CompilationException; +import ru.limedev.yoptava.files.FileUtils; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; + +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +public final class RuntimeCompiler { + + private File classesDir; + private File sourceDir; + + public void setClassesDir(Path classesDir) { + this.classesDir = classesDir.toFile(); + } + + public void setSourceDir(Path sourceDir) { + this.sourceDir = sourceDir.toFile(); + } + + public void setClassesDir(File classesDir) { + this.classesDir = classesDir; + } + + public void setSourceDir(File sourceDir) { + this.sourceDir = sourceDir; + } + + public void setClassesDir(String classesDir) { + this.classesDir = new File(classesDir); + } + + public void setSourceDir(String sourceDir) { + this.sourceDir = new File(sourceDir); + } + + public void loadClassesFromCompiledDirectory() throws CompilationException { + try { + new URLClassLoader(new URL[] { classesDir.toURI().toURL() }); + } catch (Exception e) { + throw new CompilationException(e); + } + } + + public Class getClassFromCompiledDirectory(String className) throws CompilationException { + try { + URL url = classesDir.toURI().toURL(); + URL[] urls = new URL[] { url }; + ClassLoader loader = new URLClassLoader(urls); + return loader.loadClass(className); + } catch (Exception e) { + throw new CompilationException(e); + } + } + + public void compile() throws CompilationException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + StandardJavaFileManager fileManager = getFileManager(compiler, diagnostics); + List javaObjects = getJavaObjects(fileManager); + Iterable compilationOptions = getCompilationOptions(); + CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, javaObjects); + executeCompilerTask(compilerTask, diagnostics); + } + + private StandardJavaFileManager getFileManager( + JavaCompiler compiler, + DiagnosticCollector diagnostics + ) { + return compiler.getStandardFileManager(diagnostics, Locale.getDefault(), null); + } + + private Iterable getCompilationOptions() { + String[] options = new String[] { "-d", classesDir.getAbsolutePath() }; + return Arrays.asList(options); + } + + private List getJavaObjects(StandardJavaFileManager fileManager) throws CompilationException { + List javaObjects = scanRecursivelyForJavaObjects(sourceDir, fileManager); + if (javaObjects.isEmpty()) { + throw new CompilationException("There are no source files to compile in " + sourceDir.getAbsolutePath()); + } + return javaObjects; + } + + private void executeCompilerTask( + CompilationTask compilerTask, + DiagnosticCollector diagnostics + ) throws CompilationException { + Boolean result = compilerTask.call(); + if (result == null || !result) { + for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { + System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic); + } + throw new CompilationException("Compilation failed."); + } + } + + private List scanRecursivelyForJavaObjects(File dir, StandardJavaFileManager fileManager) { + List javaObjects = new LinkedList<>(); + File[] files = dir.listFiles(); + if (files == null) return javaObjects; + for (File file : files) { + if (file.isDirectory()) { + javaObjects.addAll(scanRecursivelyForJavaObjects(file, fileManager)); + } else if (file.isFile() && FileUtils.isJavaExtension(file)) { + javaObjects.add(readJavaObject(file, fileManager)); + } + } + return javaObjects; + } + + private JavaFileObject readJavaObject(File file, StandardJavaFileManager fileManager) { + Iterable javaFileObjects = fileManager.getJavaFileObjects(file); + Iterator it = javaFileObjects.iterator(); + if (it.hasNext()) return it.next(); + throw new RuntimeException("Could not load " + file.getAbsolutePath() + " java file object."); + } +} diff --git a/src/main/java/ru/limedev/yoptava/compiler/exception/CompilationException.java b/src/main/java/ru/limedev/yoptava/compiler/exception/CompilationException.java new file mode 100644 index 0000000..6cda71e --- /dev/null +++ b/src/main/java/ru/limedev/yoptava/compiler/exception/CompilationException.java @@ -0,0 +1,12 @@ +package ru.limedev.yoptava.compiler.exception; + +public class CompilationException extends Exception { + + public CompilationException(String s) { + super(s); + } + + public CompilationException(Exception e) { + super(e); + } +} diff --git a/src/main/java/ru/limedev/yoptava/files/FileUtils.java b/src/main/java/ru/limedev/yoptava/files/FileUtils.java index 01db718..21bb11b 100644 --- a/src/main/java/ru/limedev/yoptava/files/FileUtils.java +++ b/src/main/java/ru/limedev/yoptava/files/FileUtils.java @@ -1,5 +1,8 @@ package ru.limedev.yoptava.files; +import ru.limedev.yoptava.settings.abstraction.YoptavaSettings; +import ru.limedev.yoptava.utils.StringUtils; + import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -8,14 +11,26 @@ import java.util.ArrayList; import java.util.List; -import ru.limedev.yoptava.core.StringUtils; -import ru.limedev.yoptava.settings.abstraction.YoptavaSettings; - public final class FileUtils { public static final String JAVA_EXTENSION = ".java"; public static final String fileSeparator = System.getProperty("file.separator"); + public static boolean isJavaExtension(File file) { + return isJavaExtension(file.getName()); + } + + public static boolean isJavaExtension(String fileName) { + return getExtension(fileName).equals(JAVA_EXTENSION); + } + + public static String getExtension(String fileName) { + String extension = ""; + int i = fileName.lastIndexOf('.'); + if (i > 0) extension = fileName.substring(i); + return extension.toLowerCase(); + } + public static Path getAbsolutePath(String path) { return Paths.get(path).toAbsolutePath(); } @@ -27,7 +42,7 @@ public static void renameFile(Path file, String newName) throws IOException { public static List listShortFilesPath(String directoryName, YoptavaSettings settings) { List files = new ArrayList<>(); for (String file : listFilesPath(directoryName)) { - String shortPath = StringUtils.replaceBefore(file, settings.getProjectSourcesDirectory()); + String shortPath = getShortFilePath(file, settings); files.add(shortPath); } return files; @@ -53,6 +68,10 @@ public static void deleteDirectory(File directory) { directory.delete(); } + public static String getShortFilePath(String file, YoptavaSettings settings) { + return StringUtils.replaceBefore(file, settings.getProjectSourcesDirectory()); + } + private static void listFilesPath(String directoryName, List files) { File directory = new File(directoryName); File[] fileList = directory.listFiles(); diff --git a/src/main/java/ru/limedev/yoptava/files/YoptavaFileUtils.java b/src/main/java/ru/limedev/yoptava/files/YoptavaFileUtils.java index e677608..7724686 100644 --- a/src/main/java/ru/limedev/yoptava/files/YoptavaFileUtils.java +++ b/src/main/java/ru/limedev/yoptava/files/YoptavaFileUtils.java @@ -1,31 +1,39 @@ package ru.limedev.yoptava.files; +import java.io.File; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; import ru.limedev.yoptava.cache.CacheUtils; -import ru.limedev.yoptava.core.StringUtils; +import ru.limedev.yoptava.utils.StringUtils; import ru.limedev.yoptava.parser.YoptavaParser; import ru.limedev.yoptava.settings.abstraction.YoptavaSettings; public final class YoptavaFileUtils { - public static String getCachedYoptavaName(String file, YoptavaSettings settings) { - return file.replace(settings.getLanguage().getExtension(), FileUtils.JAVA_EXTENSION); + public static String getCachedYoptavaShortPath(String file, YoptavaSettings settings) { + String shortPath = FileUtils.getShortFilePath(file, settings); + return shortPath.replace(settings.getLanguage().getExtension(), FileUtils.JAVA_EXTENSION); } - public static String readYoptavaFromCache(String javaFile, YoptavaSettings settings) throws IOException { + public static void convertCachedYoptava(String javaFile, YoptavaSettings settings) throws IOException { Path yoptavaPath = getYoptavaPathFromCache(javaFile, settings); byte[] encoded = Files.readAllBytes(yoptavaPath); String content = new String(encoded, Charset.defaultCharset()); - return YoptavaParser.parseAndConvert(content, settings); + String converted = YoptavaParser.parseAndConvert(content, settings); + Path file = Paths.get(yoptavaPath.toUri()); + Files.write(file, Collections.singleton(converted), StandardCharsets.UTF_8); } public static void putYoptavaInCache(String file, YoptavaSettings settings) throws IOException { String javaFile = getCachedYoptavaName(file, settings); Path targetPath = getYoptavaPathFromCache(file, settings); + createParentDirectories(targetPath); Path copiedPath = Files.copy(getYoptavaPath(file, settings), targetPath); FileUtils.renameFile(copiedPath, javaFile); } @@ -61,4 +69,15 @@ private static String getSourcesInCacheDirectory(YoptavaSettings settings) { if (!isSourcesDirectoryEmpty) sourcesDirectory += FileUtils.fileSeparator + settings.getSourcesDirectory(); return sourcesDirectory; } + + private static String getCachedYoptavaName(String file, YoptavaSettings settings) { + File f = new File(file); + return f.getName().replace(settings.getLanguage().getExtension(), FileUtils.JAVA_EXTENSION); + } + + private static void createParentDirectories(Path path) throws IOException { + Path parent = path.getParent(); + if (parent == null) return; + if (Files.notExists(parent)) Files.createDirectories(parent); + } } diff --git a/src/main/java/ru/limedev/yoptava/files/model/FileModel.java b/src/main/java/ru/limedev/yoptava/files/model/FileModel.java new file mode 100644 index 0000000..094a03c --- /dev/null +++ b/src/main/java/ru/limedev/yoptava/files/model/FileModel.java @@ -0,0 +1,61 @@ +package ru.limedev.yoptava.files.model; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Objects; + +public final class FileModel { + + @NotNull + String path; + @NotNull + String name; + boolean isDirectory; + + public FileModel(@NotNull String path, @NotNull String name, boolean isDirectory) { + this.path = path; + this.name = name; + this.isDirectory = isDirectory; + } + + @Override + public int hashCode() { + int result = this.path.hashCode(); + result = result * 31 + this.name.hashCode(); + result = result * 31 + Boolean.hashCode(this.isDirectory); + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FileModel)) return false; + FileModel fileModel = (FileModel) o; + return isDirectory == fileModel.isDirectory && Objects.equals(path, fileModel.path) && Objects.equals(name, fileModel.name); + } + + @NotNull + public String getPath() { + return path; + } + + @NotNull + public String getName() { + return name; + } + + public boolean isDirectory() { + return isDirectory; + } + + public static void addFileToList( + @NotNull String path, + @NotNull String name, + boolean isDirectory, + @NotNull List files + ) { + FileModel fileModel = new FileModel(path, name, isDirectory); + files.add(fileModel); + } +} diff --git a/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java b/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java index 76e120b..0e788ad 100644 --- a/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java +++ b/src/main/java/ru/limedev/yoptava/parser/YoptavaParser.java @@ -2,7 +2,7 @@ import java.util.Map; -import ru.limedev.yoptava.core.StringUtils; +import ru.limedev.yoptava.utils.StringUtils; import ru.limedev.yoptava.settings.abstraction.YoptavaSettings; public final class YoptavaParser { diff --git a/src/main/java/ru/limedev/yoptava/parser/dictionary/GoptavaDictionary.java b/src/main/java/ru/limedev/yoptava/parser/dictionary/GoptavaDictionary.java index 370e28b..af40523 100644 --- a/src/main/java/ru/limedev/yoptava/parser/dictionary/GoptavaDictionary.java +++ b/src/main/java/ru/limedev/yoptava/parser/dictionary/GoptavaDictionary.java @@ -89,6 +89,9 @@ public final class GoptavaDictionary implements Dictionary { put("нуллио", "null"); put("порожняк", "null"); + // Annotations + put("Перебить", "Override"); + // Object put("Петух", "Object"); put("вычислитьКласс", "getClass"); diff --git a/src/main/java/ru/limedev/yoptava/parser/dictionary/LeptavaDictionary.java b/src/main/java/ru/limedev/yoptava/parser/dictionary/LeptavaDictionary.java index 20d8231..68be387 100644 --- a/src/main/java/ru/limedev/yoptava/parser/dictionary/LeptavaDictionary.java +++ b/src/main/java/ru/limedev/yoptava/parser/dictionary/LeptavaDictionary.java @@ -68,6 +68,9 @@ public final class LeptavaDictionary implements Dictionary { put("лесть", "false"); put("ничтожевелие", "null"); + // Annotations + put("Переопределити", "Override"); + // Object put("Начальникъ", "Object"); put("поятиВидъ", "getClass"); diff --git a/src/main/java/ru/limedev/yoptava/parser/dictionary/RuptavaDictionary.java b/src/main/java/ru/limedev/yoptava/parser/dictionary/RuptavaDictionary.java index b127414..4c22a0f 100644 --- a/src/main/java/ru/limedev/yoptava/parser/dictionary/RuptavaDictionary.java +++ b/src/main/java/ru/limedev/yoptava/parser/dictionary/RuptavaDictionary.java @@ -67,6 +67,9 @@ public final class RuptavaDictionary implements Dictionary { put("ложь", "false"); put("нулевой", "null"); + // Annotations + put("Переопределить", "Override"); + // Object put("Объект", "Object"); put("получитьКласс", "getClass"); diff --git a/src/main/java/ru/limedev/yoptava/settings/Settings.java b/src/main/java/ru/limedev/yoptava/settings/Settings.java index 6450c93..6937e43 100644 --- a/src/main/java/ru/limedev/yoptava/settings/Settings.java +++ b/src/main/java/ru/limedev/yoptava/settings/Settings.java @@ -5,26 +5,28 @@ import ru.limedev.yoptava.settings.type.LanguageType; final class Settings { + + // Common settings static final String PROJECT_PATH = System.getProperty("user.dir") + FileUtils.fileSeparator; // Goptava default settings static final Language LANGUAGE_GOPTAVA = LanguageType.GOPTAVA.language; static final String SOURCES_DIRECTORY_GOPTAVA = "goptava"; static final String PROJECT_SOURCES_DIRECTORY_GOPTAVA = PROJECT_PATH + SOURCES_DIRECTORY_GOPTAVA + FileUtils.fileSeparator; - static final String MAIN_CLASS_NAME_GOPTAVA = "Load"; - static final String MAIN_CLASS_LOAD_METHOD_GOPTAVA = "load"; + static final String MAIN_CLASS_NAME_GOPTAVA = "Авторитет"; + static final String MAIN_CLASS_LOAD_METHOD_GOPTAVA = "кукуЁпта"; // Leptava default settings static final Language LANGUAGE_LEPTAVA = LanguageType.LEPTAVA.language; static final String SOURCES_DIRECTORY_LEPTAVA = "leptava"; static final String PROJECT_SOURCES_DIRECTORY_LEPTAVA = PROJECT_PATH + SOURCES_DIRECTORY_LEPTAVA + FileUtils.fileSeparator; - static final String MAIN_CLASS_NAME_LEPTAVA = "Load"; - static final String MAIN_CLASS_LOAD_METHOD_LEPTAVA = "load"; + static final String MAIN_CLASS_NAME_LEPTAVA = "Истое"; + static final String MAIN_CLASS_LOAD_METHOD_LEPTAVA = "истое"; // Ruptava default settings static final Language LANGUAGE_RUPTAVA = LanguageType.RUPTAVA.language; static final String SOURCES_DIRECTORY_RUPTAVA = "ruptava"; static final String PROJECT_SOURCES_DIRECTORY_RUPTAVA = PROJECT_PATH + SOURCES_DIRECTORY_RUPTAVA + FileUtils.fileSeparator; - static final String MAIN_CLASS_NAME_RUPTAVA = "Load"; - static final String MAIN_CLASS_LOAD_METHOD_RUPTAVA = "load"; + static final String MAIN_CLASS_NAME_RUPTAVA = "Главный"; + static final String MAIN_CLASS_LOAD_METHOD_RUPTAVA = "главный"; } diff --git a/src/main/java/ru/limedev/yoptava/settings/type/Language.java b/src/main/java/ru/limedev/yoptava/settings/type/Language.java index 514ba3a..98a7141 100644 --- a/src/main/java/ru/limedev/yoptava/settings/type/Language.java +++ b/src/main/java/ru/limedev/yoptava/settings/type/Language.java @@ -17,16 +17,6 @@ public Language(@NotNull String extension, @NotNull Dictionary dictionary) { this.dictionary = dictionary; } - @NotNull - public String getExtension() { - return this.extension; - } - - @NotNull - public Dictionary getDictionary() { - return this.dictionary; - } - @Override public int hashCode() { int result = this.extension.hashCode(); @@ -41,4 +31,14 @@ public boolean equals(Object o) { Language that = (Language) o; return Objects.equals(extension, that.extension) && Objects.equals(dictionary, that.dictionary); } + + @NotNull + public String getExtension() { + return this.extension; + } + + @NotNull + public Dictionary getDictionary() { + return this.dictionary; + } } \ No newline at end of file diff --git a/src/main/java/ru/limedev/yoptava/core/StringUtils.java b/src/main/java/ru/limedev/yoptava/utils/StringUtils.java similarity index 94% rename from src/main/java/ru/limedev/yoptava/core/StringUtils.java rename to src/main/java/ru/limedev/yoptava/utils/StringUtils.java index 014a007..cc7c4e3 100644 --- a/src/main/java/ru/limedev/yoptava/core/StringUtils.java +++ b/src/main/java/ru/limedev/yoptava/utils/StringUtils.java @@ -1,4 +1,4 @@ -package ru.limedev.yoptava.core; +package ru.limedev.yoptava.utils; public final class StringUtils {