Оберон — мова програмування високого рівня, розроблена Ніклаусом Віртом. Для виконання програм цією мовою приназначена однойменна операційна система (автори Н. Вірт і Юрг Гуткнехт (Jurg Gutknecht)).

Системи й середовища

Програми, що написані мовою програмування Оберон, вимагають певної підтримки під час виконання — їм необхідний динамічний завантажувач і централізовано виконуваний автоматичний збирач сміття. Для цього програмам, що написані мовою Оберон, потрібне спеціальне операційне середовище. Звичайним способом його реалізації є додавання в систему набору бібліотек, що реалізують необхідні компоненти. Загалом кажучи, операційному середовищу зовсім не обов'язково потрібна окрема операційна система: воно само по собі може являти собою операційну систему. Такими є системи Native Oberon для первісного Оберона й Bluebottle для Active Oberon. У цей час існують компілятори Оберона в байт-код Віртуальної Java-машини і CLI для віртуальної машини .NET.

Операційними системами й середовищами для виконання програм на мовах родини Оберон, що розвилися з первісної системи Оберон, є ETH Oberon, BlackBox Component Builder, WinOberon, Bluebottle тощо.

На базі Оберона були розроблені проекти Оберон-0, Оберон-X та інші. Простота Оберона й наявність вихідних текстів оригінальної реалізації дозволяють легко адаптувати його для спеціальних класів завдань. Але всі ці Оберони дуже близькі між собою, оскільки й первісний Оберон дуже простий.

Історія мови

Основою для Оберона послужила мова Модула-2, що виросла з Паскаля, (за словами Вірта, спочатку систему хотіли писати безпосередньо на Модулі, але прийшли до висновку про необхідність її доробки й скорочення, що й привело до появи Оберона). Метою проекту (Project Oberon) Ніклауса Вірта і Юрга Гуткнехта в 1986–1989 рокахN. Wirth and J. Gutknecht. Project Oberon. Addison-Wesley, 1992 було створення з нуля доступної для розгляду й надійної операційної системи для однокористувальницької робочої станції.

Для реалізації цього проекту в 1988 році Ніклаусом Віртом була спроектована мова програмування високого рівня загального призначення, також названа Обероном.N. Wirth. The Programming Language Oberon. Software — Practice and Experience, Vol.18, No.7, p.671-690

У 1989 році в ETH була випущена перша реалізація мови Оберон для процесорів родини NS32000. Вона була створена як компонент операційного середовища Оберон. Цей компілятор вимагає менше 50 Кбайт пам'яті, складається з 6 модулів загальним обсягом близько 4000 рядків і сам себе компілює за 15 секунд на комп'ютері із процесором NS32532 (тактова частота — 25 МГц).

Мова Оберон

Нововведення

Мова зберегла основні риси синтаксису Модули й була об'єктним розширенням. Це дозволило відмовитися від механізму варіантних записів Модули, що є відступом від первісної строгої статичної типізації, що дало можливість запровадити механізм автоматичного керування пам'яттю — збирання сміття: з мови виключена можливість звільнення динамічно виділеної пам'яті за допомогою особливого оператора, а замість нього саме середовище виконання містить модуль, що повертає невикористовувану пам'ять системі. Автоматичне керування пам'яттю є засобом підвищення надійності програм із динамічними структурами даних, тому що виключає людські помилки, властиві, наприклад, таким мовам, як С/C++.

Спрощення синтаксису

Щоб досягти максимальної надійності та продуктивності трансляції, було здійснено значне спрощення мови за рахунок відмови від засобів, які було визнано непотрібними (виходячи з досвіду розробки, реалізації та експлуатації інших мов), або ускладнювали компілятор без належного виправдання з погляду продуктивності, або були занадто складними, аби передати в зовнішні бібліотеки, чи погано поєднувалися з механізмами модульності й автоматичного керування пам'яттю: записи з варіантами, перечислимі типи, типи-діапазони, множини загального виду, беззнаковий цілий тип, локальні модулі, модулі визначень, списки експорту, оператор for, колишній варіант оператора with, особливий синтаксис визначення головної програми. Рудиментарні засоби підтримки паралельного програмування, що були в Модулі-2, не ввійшли до мови, оскільки вона призначалася для однокористувацької операційної системи. З метою спрощення відмовилися від обробки винятків.

Було спрощено опис масивів (індекси масивів можуть бути тільки цілими числами і завжди починаються з нуля, подібно до мови C), обмежено використання вказівників (можуть існувати вказівники лише на записи та масиви), у списках імпорту вказується тільки імпортований модуль, а при використанні імпортованих імен потрібна обов'язкова кваліфікація (явне зазначення імені модуля-експортера). У статті «Від Модули до Оберона» Вірт докладно прокоментував причини вилучення кожного з елементів.

З міркувань «достатнього мінімуму» до мови не було включено синтаксичного поняття методів (процедур і функцій), що пов'язані з типом, тому що цей механізм у найзагальнішому вигляді можна легко змоделювати, створюючи в об'єктах («записах» у мові Оберон) поля процедурного типу й надаючи їм значення процедур, що відповідають методам. Таким чином, в Обероні мінімальними засобами підтримується об'єктно-орієнтоване програмування для спрощення й прискорення процесу трансляції коду.

Завдяки внесеним змінам, Оберон став синтаксично простішим. Опис його синтаксису вмістився на одній сторінці, повний опис мови має близько 20 сторінок, що вдвічі менше за опис Модули-2. Оберон є якщо не мінімальною, то, у будь-якому разі, однією з найменших за обсягом універсальних мов програмування високого рівня.

Синтаксис у РБНФ

Синтаксис «Оберона-2» вирізняється компактністю. Він визначений у наступних 33 реченнях РБНФ (дається за Х. Месенбек, Н. Вірт, 1996): Модуль = MODULE ідент ";" [СписокІмпорту] ПослОголош [BEGIN ПослОператорів] END ідент ".". СписокІмпорту = IMPORT [ідент ":="] ідент {"," [ідент ":="] ідент} ";". ПослОголош = { CONST {ОголошКонст ";" } | TYPE {ОголошТипу ";" } | VAR {ОголошЗмін ";" }} {ОголошПроц ";" | ВипереджОгол";"}. ОголошКонст = ІдентОзн "=" КонстВираз. ОголошТипу = ІдентОзн "=" Тип. ОголошЗмін = СписокІдент ":" Тип. ОголошПроц = PROCEDURE [Приймач] ІдентОзн [ФормальніПарам]";" ПослОголош [BEGIN ПослОператорів] END ідент. ВипереджОгол = PROCEDURE "^" [Приймач] ІдентОзн [ФормальніПарам]. ФормальніПарам = "(" [СекціяФП {";" СекціяФП}] ")" [":" УточнІдент]. СекціяФП = [VAR] ідент {"," ідент} ":" Тип. Приймач = "(" [VAR] ідент ":" ідент ")". Тип = УточнІдент | ARRAY [КонстВираз {"," КонстВираз}] OF Тип | RECORD ["("УточнІдент")"] СписокПолів {";" СписокПолів} END | POINTER TO Тип | PROCEDURE [ФормальніПарам]. СписокПолів = [СписокІдент ":" Тип]. ПослОператорів = Оператор {";" Оператор}. Оператор = [ Позначення ":=" Вираз | Позначення ["(" [СписокВиразів] ")"] | IF Вираз THEN ПослОператорів {ELSIF Вираз THEN ПослОператорів} [ELSE ПослОператорів] END | CASE Вираз OF Варіант {"|" Варіант} [ELSE ПослОператорів] END | WHILE Вираз DO ПослОператорів END | REPEAT ПослОператорів UNTIL Вираз | FOR ідент ":=" Вираз TO Вираз [BY КонстВираз] DO ПослОператорів END | LOOP ПослОператорів END | WITH Охорона DO ПослОператорів {"|" Охорона DO ПослОператорів} [ELSE ПослОператорів] END | EXIT | RETURN [Вираз] ]. Варіант = [МіткиВаріанта {"," МіткиВаріанта} ":" ПослОператорів]. МіткиВаріанта = КонстВираз [".." КонстВираз]. Охорона = УточнІдент ":" УточнІдент. КонстВираз = Вираз. Вираз = ПростийВираз [Відношення ПростийВираз]. ПростийВираз = ["+" | "-"] Доданок {ОперДодав Доданок}. Доданок = Множник {ОперМнож Множник}. Множник = Позначення ["(" [СписокВиразів] ")"] | число | символ | рядок | NIL | Множина | "(" Вираз ")" | " ~ " Множник. Множина = "{" [Елемент {"," Елемент}] "}". Елемент = Вираз [".." Вираз]. Відношення = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS. ОперДодав = "+" | "-" | OR. ОперМнож = "*" | "/" | DIV | MOD | "&". Позначення = УточнІдент {"." ідент | "[" СписокВиразів "]" | "^" | "(" УточнІдент ")"}. СписокВиразів = Вираз {"," Вираз}. СписокІдент = ІдентОзн {"," ІдентОзн}. УточнІдент = [ідент "."] ідент. ІдентОзн = ідент [ "*" | "-" ].

Основні елементи

Програма на Обероні являє собою набір модулів. У загальному виді модуль має вигляд: MODULE Ім'я; IMPORT СписокІмпорту; Означення; BEGIN Оператори END Ім'я.

Список імпорту визначає, з яких модулів будуть імпортовані зовнішні імена. Визначення включають визначення типів, процедур, функцій, змінних, констант. При цьому визначення імен, позначених зірочкою, експортуються даним модулем, тобто будуть видні іншим модулям, що імпортують даний. В Обероні-2 допустимо також позначати імена знаком мінус, у цьому випадку вони експортуються в режимі «тільки для читання».

Тіло модуля виконується при його завантаженні. У Компонентному Паскалі всередині тіла модуля (у розділі BEGIN..END) появилася можливість додати секцію CLOSE: BEGIN Оператори CLOSE Оператори END Ім'я.

Тут оператори, розташовані між BEGIN і CLOSE, виконуються при завантаженні модуля, а оператори, розташовані між CLOSE і END — при вивантаженні його з пам'яті. Таке розширення було признане корисним для компонентних програм, які завантажують і вивантажують модулі динамічно.

Створювані програмістом типи даних обмежені наступним набором: типи-масиви ARRAY, типи-запису RECORD, процедурні типи PROCEDURE, типи-вказівники POINTER. Вказівник може вказувати тільки на масив або запис.

Синтаксис внутрішньої частини програми досить традиційний і простий. Мова підтримує традиційний набір конструкцій: умовний оператор IF, оператор вибору CASE, цикли (з передумовою — WHILE, з постумовою REPEAT..UNTIL, безумовний — LOOP, з лічильником — FOR). Подібно до Модули-2, великі й малі літери в ідентифікаторах різняться, усі зарезервовані слова пишуться великими літерами. Усі мовні конструкції, крім циклу REPEAT..UNTIL закінчуються ключовим словом END і допускають розташування усередині декількох операторів без використання складеного оператора BEGIN..END. Природно, як і в Модулі-2, немає безумовних переходів.

Парадигма об'єктно-орієнтованого програмування підтримується механізмом розширених записів (у мові немає окремого ключового слова для опису класів, таких, як «class» або «object», прийнято, що звичайного поняття «тип запис» цілком достатньо). По суті, кожний тип запис — це опис класу, а поля запису — це дані-члени класу.

У вихідному Обероні методів (процедур і функцій, пов'язаних із класом) немає взагалі. Механізм методів може бути використаний шляхом оголошення в записі полів процедурного типу, яким при створенні екземпляра класу надаються значення конкретних процедур. Виклик таких процедур провадиться традиційним способом звертання до поля запису, за умовчанням процедура не знає про екземпляр класу, для якого вона була викликана (немає механізму, аналогічного this в C++ або Java, або Self в Object Pascal), і якщо такі дані їй необхідні, то посилання на екземпляр повинне бути передане явно (наприклад, через параметр). Відсутність явно описуваних методів була однією із властивостей вихідного Оберона, що викликала критику призвичаєних до традиційних гібридних мов програмістів. З іншого боку, пропонований Обероном механізм дозволяє реалізувати все, що реалізовано традиційними засобами мов із методами, і, навіть більше того, — в Обероні кожен екземпляр класу може мати власний варіант методу (значення поля процедурного типу), тоді як при описі методів як частин класу всі екземпляри працюють з одним варіантом методу. В Обероні-2 методи були все-таки введені. Методи описуються окремо від типу запис, із зазначенням типу, з яким вони пов'язані.