Оберон-2
В этой статье есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
Парадигмы | Императивный , структурированный , модульный , объектно-ориентированный |
---|---|
Семья | Вирт Оберон |
Разработано | Никлаус Вирт Ханспетер Мессенбёк |
Разработчик | ETH Цюрих |
Впервые появился | 1991 год |
Дисциплина набора текста | Сильный , гибридный ( статический и динамический ) |
Объем | Лексический |
Платформа | Церера ( NS32032 ), IA-32 , x86-64 |
ТЫ | Windows , Linux , Солярис , MacOS |
Веб-сайт | www |
Под влиянием | |
Оберон , Модуль-2 , Объект Оберон | |
Под влиянием | |
Оберон-07 , Зоннон , Активный Оберон , Компонентный Паскаль , Го , Ним |
Оберон-2 — это расширение исходного Оберон языка программирования , которое добавляет средства ограниченного рефлексивного программирования (отражения) и объектно-ориентированного программирования , открытые массивы как базовые типы указателей, экспорт полей только для чтения и вновь вводит FOR
петля от Модулы-2 .
Он был разработан в 1991 году в ETH Zurich Никлаусом Виртом и Ханспетером Мессенбеком , которые сейчас работают в Institut für Systemsoftware (SSW) Университета Линца , Австрия. Оберон-2 — это надстройка Оберона, полностью с ним совместимая и являющаяся переработкой Объекта Оберон .
Оберон-2 унаследовал ограниченное отражение и одиночное наследование («расширение типа») без интерфейсов и примесей от Оберона, но добавил эффективные виртуальные методы («процедуры с привязкой типа»). Вызовы методов разрешались во время выполнения с использованием C++ таблиц виртуальных методов в стиле .
По сравнению с полностью объектно-ориентированными языками, такими как Smalltalk , в Обероне-2 базовые типы данных и классы не являются объектами , многие операции не являются методами, отсутствует передача сообщений (это можно в некоторой степени эмулировать посредством отражения и расширения сообщений, как показано в ETH Oberon), а полиморфизм ограничен подклассами общего класса (нет утиной типизации, как в Python , [1] и невозможно определить интерфейсы, как в Java ). Оберон-2 не поддерживает инкапсуляцию на уровне объекта или класса, но для этой цели можно использовать модули.
Отражение в Обероне-2 не использует метаобъекты , а просто считывает дескрипторы типов, скомпилированные в исполняемые двоичные файлы и представленные в модулях, определяющих типы и/или процедуры. Если формат этих структур раскрывается на уровне языка (как, например, в случае с ETH Oberon), отражение можно реализовать на уровне библиотеки . Таким образом, его можно было почти полностью реализовать на уровне библиотеки без изменения языкового кода. Действительно, ETH Oberon широко использует возможности отражения на уровне языка и библиотеки.
Оберон-2 обеспечивает встроенную поддержку сборки мусора во время выполнения , аналогичную Java, и выполняет проверки границ и индексов массива и т. д., что устраняет потенциальные проблемы перезаписи границ стека и массива, а также проблемы ручного управления памятью, присущие C и C++. Отдельная компиляция с использованием файлов символов и пространств имен через архитектуру модуля обеспечивает быструю перекомпиляцию, поскольку перекомпилировать необходимо только модули с измененными интерфейсами.
Язык Компонент Паскаль [2] является доработкой (надмножеством) Оберона-2.
Пример кода
[ редактировать ]Следующий код Оберона-2 реализует простое двоичное дерево:
MODULE Trees;
TYPE
Tree* = POINTER TO Node;
Node* = RECORD
name-: POINTER TO ARRAY OF CHAR;
left, right: Tree
END;
PROCEDURE (t: Tree) Insert* (name: ARRAY OF CHAR);
VAR p, father: Tree;
BEGIN p := t;
REPEAT father := p;
IF name = p.name^ THEN RETURN END;
IF name < p.name^ THEN p := p.left ELSE p := p.right END
UNTIL p = NIL;
NEW(p); p.left := NIL; p.right := NIL; NEW(p.name, LEN(name)+1); COPY(name, p.name^);
IF name < father.name^ THEN father.left := p ELSE father.right := p END
END Insert;
PROCEDURE (t: Tree) Search* (name: ARRAY OF CHAR): Tree;
VAR p: Tree;
BEGIN p := t;
WHILE (p # NIL) & (name # p.name^) DO
IF name < p.name^ THEN p := p.left ELSE p := p.right END
END;
RETURN p
END Search;
PROCEDURE NewTree* (): Tree;
VAR t: Tree;
BEGIN NEW(t); NEW(t.name, 1); t.name[0] := 0X; t.left := NIL; t.right := NIL; RETURN t
END NewTree;
END Trees.
Расширение Оберон-2 для Оберона [3]
[ редактировать ]Процедуры с привязкой к типу
[ редактировать ]Процедуры могут быть привязаны к типу записи (или указателя). Они эквивалентны методам экземпляра в объектно-ориентированной терминологии.
Экспорт только для чтения
[ редактировать ]Использование экспортированных переменных и полей записей можно ограничить доступом только для чтения. Это отображается флажком видимости «-».
Открытые массивы
[ редактировать ]Открытые массивы, которые раньше могли быть объявлены только как типы формальных параметров, теперь могут быть объявлены как базовые типы указателей.
ЗА заявление
[ редактировать ]The FOR
оператор Паскаля и Модулы-2 не был реализован в Обероне. Он вновь представлен в Обероне-2.
Проверка типа во время выполнения
[ редактировать ]Оберон-2 предоставляет несколько механизмов проверки динамического типа объекта. Например, если экземпляр объекта «Птица» может быть создан как «Утка» или «Кукушка», Оберон-2 позволяет программисту реагировать на фактический тип объекта во время выполнения.
Первый, наиболее традиционный подход — полагаться на систему привязки типов . Второй подход заключается в использовании WITH
оператор динамический подтип , который позволяет напрямую проверять переменной. В обоих случаях, как только подтип определен, программист может использовать любые процедуры или переменные, привязанные к типу, соответствующие подтипу. Примеры таких подходов показаны ниже.
Обратите внимание, что форма WITH
Оператор, используемый в Обероне-2, не связан с оператором With в Паскале и Модуле-2. Этот метод сокращения доступа к полям записи не реализован ни в Обероне, ни в Обероне-2.
Тип привязки
[ редактировать ] MODULE Birds;
TYPE
Bird* = RECORD
sound* : ARRAY 10 OF CHAR;
END;
END Birds.
MODULE Ducks;
IMPORT Birds;
TYPE
Duck* = RECORD (Birds.Bird) END;
PROCEDURE SetSound* (VAR bird : Duck);
BEGIN
bird.sound := "Quack!"
END SetSound;
END Ducks.
MODULE Cuckoos;
IMPORT Birds;
TYPE
Cuckoo* = RECORD (Birds.Bird) END;
PROCEDURE SetSound* (VAR bird : Cuckoo);
BEGIN
bird.sound := "Cuckoo!"
END SetSound;
END Cuckoos.
WITH
заявление
[ редактировать ] MODULE Test;
IMPORT Out, Birds, Cuckoos, Ducks;
TYPE
SomeBird* = RECORD (Birds.Bird) END;
VAR
sb : SomeBird;
c : Cuckoos.Cuckoo;
d : Ducks.Duck;
PROCEDURE SetSound* (VAR bird : Birds.Bird);
BEGIN
WITH bird : Cuckoos.Cuckoo DO
bird.sound := "Cuckoo!"
| bird : Ducks.Duck DO
bird.sound := "Quack!"
ELSE
bird.sound := "Tweet!"
END
END SetSound;
PROCEDURE MakeSound* (VAR b : Birds.Bird);
BEGIN
Out.Ln;
Out.String(b.sound);
Out.Ln
END MakeSound;
BEGIN
SetSound(c);
SetSound(d);
SetSound(sb);
MakeSound(c);
MakeSound(d);
MakeSound(sb)
END Test.
POINTER
[ редактировать ] MODULE PointerBirds;
IMPORT Out;
TYPE
BirdRec* = RECORD
sound* : ARRAY 10 OF CHAR;
END;
DuckRec* = RECORD (BirdRec) END;
CuckooRec* = RECORD (BirdRec) END;
Bird = POINTER TO BirdRec;
Cuckoo = POINTER TO CuckooRec;
Duck = POINTER TO DuckRec;
VAR
pb : Bird;
pc : Cuckoo;
pd : Duck;
PROCEDURE SetDuckSound* (bird : Duck);
BEGIN
bird.sound := "Quack!"
END SetDuckSound;
PROCEDURE SetCuckooSound* (bird : Cuckoo);
BEGIN
bird.sound := "Cuckoo!"
END SetCuckooSound;
PROCEDURE SetSound* (bird : Bird);
BEGIN
WITH bird : Cuckoo DO
SetCuckooSound(bird)
| bird : Duck DO
SetDuckSound(bird)
ELSE
bird.sound := "Tweet!"
END
END SetSound;
BEGIN
NEW(pc);
NEW(pd);
SetCuckooSound(pc);
SetDuckSound(pd);
Out.Ln; Out.String(pc^.sound); Out.Ln;
Out.Ln; Out.String(pd^.sound); Out.Ln;
SetSound(pc);
SetSound(pd);
Out.Ln; Out.String(pc^.sound); Out.Ln;
Out.Ln; Out.String(pd^.sound); Out.Ln;
(* -------------------------------------- *)
(* Pass dynamic type to procedure *)
pb := pd;
SetDuckSound(pb(Duck));
Out.Ln; Out.String(pb^.sound); Out.Ln;
pb := pc;
SetCuckooSound(pb(Cuckoo));
Out.Ln; Out.String(pb^.sound); Out.Ln;
(* -------------------------------------- *)
SetSound(pb);
Out.Ln; Out.String(pb^.sound); Out.Ln;
pb := pd;
SetSound(pb);
Out.Ln; Out.String(pb^.sound); Out.Ln;
(* -------------------------------------- *)
NEW(pb);
SetSound(pb);
Out.Ln; Out.String(pb^.sound); Out.Ln
END PointerBirds.
IS
оператор
[ редактировать ] Третий подход возможен с использованием IS
оператор . Это оператор отношения с тем же приоритетом, что и оператор равенства ( =
), больше ( >
) и т. д., но который проверяет динамический тип. Однако, в отличие от двух других подходов, он не позволяет программисту получить доступ к обнаруженному подтипу.
Синтаксис
[ редактировать ]Развитие семейства языков АЛГОЛ → Паскаль → Модула-2 → Оберон → Компонентный Паскаль отмечено уменьшением сложности синтаксиса языка . Весь язык Оберон-2 описан ( Mössenböck & Wirth, март 1995 г. ) с использованием только 33 грамматических образований в расширенной форме Бэкуса-Наура , как показано ниже.
Module = MODULE ident ";" [ImportList] DeclSeq [BEGIN StatementSeq] END ident ".".
ImportList = IMPORT [ident ":="] ident {"," [ident ":="] ident} ";".
DeclSeq = { CONST {ConstDecl ";" } | TYPE {TypeDecl ";"} | VAR {VarDecl ";"}} {ProcDecl ";" | ForwardDecl ";"}.
ConstDecl = IdentDef "=" ConstExpr.
TypeDecl = IdentDef "=" Type.
VarDecl = IdentList ":" Type.
ProcDecl = PROCEDURE [Receiver] IdentDef [FormalPars] ";" DeclSeq [BEGIN StatementSeq] END ident.
ForwardDecl = PROCEDURE "^" [Receiver] IdentDef [FormalPars].
FormalPars = "(" [FPSection {";" FPSection}] ")" [":" Qualident].
FPSection = [VAR] ident {"," ident} ":" Type.
Receiver = "(" [VAR] ident ":" ident ")".
Type = Qualident
| ARRAY [ConstExpr {"," ConstExpr}] OF Type
| RECORD ["("Qualident")"] FieldList {";" FieldList} END
| POINTER TO Type
| PROCEDURE [FormalPars].
FieldList = [IdentList ":" Type].
StatementSeq = Statement {";" Statement}.
Statement = [ Designator ":=" Expr
| Designator ["(" [ExprList] ")"]
| IF Expr THEN StatementSeq {ELSIF Expr THEN StatementSeq} [ELSE StatementSeq] END
| CASE Expr OF Case {"|" Case} [ELSE StatementSeq] END
| WHILE Expr DO StatementSeq END
| REPEAT StatementSeq UNTIL Expr
| FOR ident ":=" Expr TO Expr [BY ConstExpr] DO StatementSeq END
| LOOP StatementSeq END
| WITH Guard DO StatementSeq {"|" Guard DO StatementSeq} [ELSE StatementSeq] END
| EXIT
| RETURN [Expr]
].
Case = [CaseLabels {"," CaseLabels} ":" StatementSeq].
CaseLabels = ConstExpr [".." ConstExpr].
Guard = Qualident ":" Qualident.
ConstExpr = Expr.
Expr = SimpleExpr [Relation SimpleExpr].
SimpleExpr = ["+" | "-"] Term {AddOp Term}.
Term = Factor {MulOp Factor}.
Factor = Designator ["(" [ExprList] ")"] | number | character | string | NIL | Set | "(" Expr ")" | "~" Factor.
Set = "{" [Element {"," Element}] "}".
Element = Expr [".." Expr].
Relation = "=" | "#" | "<" | "<=" | ">" | ">=" | IN | IS.
AddOp = "+" | "-" | OR.
MulOp = "*" | "/" | DIV | MOD | "&".
Designator = Qualident {"." ident | "[" ExprList "]" | "^" | "(" Qualident ")"}.
ExprList = Expr {"," Expr}.
IdentList = IdentDef {"," IdentDef}.
Qualident = [ident "."] ident.
IdentDef = ident ["*" | "-"].
Реализации
[ редактировать ]Компиляторы Oberon-2, поддерживаемые ETH, включают версии для Windows , Linux , Solaris , macOS .
Компилятор Oxford Oberon-2 компилируется в собственный машинный код и может использовать JIT-компилятор в Windows, Linux и macOS. Он создан и поддерживается Майком Спиви и использует виртуальную машину Keiko. [4] [5]
Существует сканер Oberon-2 Lex и Yacc, парсер разработанный Стивеном Дж. Беваном из Манчестерского университета, Великобритания, на основе сканера, приведенного в справочнике Мессенбека и Вирта. Это версия 1.4.
Существует версия под названием Native Oberon , которая включает в себя операционную систему и может напрямую загружаться на оборудование класса ПК.
В ETHZ была разработана реализация Оберона на .NET с добавлением некоторых незначительных расширений, связанных с .NET.
Открытый верстак программиста (POW!) [6] — это очень простая интегрированная среда разработки , снабженная редактором, компоновщиком и компилятором Oberon-2. Это компилируется в исполняемые файлы Windows . Полный исходный код предоставляется; компилятор написан на Обероне-2.
Компилятор Java для Оберона (JOB) был написан в Вологодском университете в России. Он создает объектный код в виде файлов классов Java ( байт-код ). Предоставляются некоторые классы, специфичные для JOB, которые совместимы с Java, но используют иерархию компонентов, более похожую на Oberon.
Оптимизирующий компилятор Oberon-2 компилируется в C, используя набор инструментов GNU Compiler Collection (GCC) для генерации программ.
Oberon Script — это компилятор, полностью переводящий язык Oberon в JavaScript . Компилятор написан на JavaScript, поэтому его можно вызывать с веб-страниц для обработки сценариев, написанных на Обероне.
XDS Modula2/Oberon2 — система разработки ООО «Эксельсиор», Новосибирск, Россия. Он содержит оптимизирующий компилятор для Intel Pentium или транслятор «через C» для кроссплатформенной разработки программного обеспечения. Доступно для Windows и Linux. Компилятор написан на Обероне-2 и компилируется сам.
Oberon Revival — это проект по внедрению Oberon 2 и Component Pascal ( BlackBox Component Builder ) в Linux и Win32. Порт BlackBox для Linux раньше был недоступен, и изначально он работал только на Microsoft Windows.
XOberon — операционная система реального времени для PowerPC , написанная на Oberon-2.
Портативный компилятор Оберон-2 (OP2) был разработан для переноса системы Оберон на коммерчески доступные платформы. [7]
Байт-код Кейко
[ редактировать ]Оберон-2 может атаковать виртуальную машину Кейко. [8] [9] Например, как и некоторые другие компиляторы языков (см. O-code , p-code и т. д.), Компилятор Oxford Oberon-2 сначала компилирует в промежуточный байт-код (байт-код Keiko), который можно интерпретировать с помощью интерпретатора байт-кода или использовать компиляцию «точно в срок» .
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «Сопутствующее чтение» . Доктор Добб .
- ^ Пфистер, Куно (2001). «Что нового в Component Pascal (изменения с Oberon-2 на CP)» (PDF) . Микросистемы Оберон . Архивировано из оригинала (PDF) 15 мая 2011 года . Проверено 10 января 2007 г.
- ^ Различия между Обероном и Обероном-2, Мессенбеком и Виртом (1993)
- ^ Спайви, Майкл (2014). Спецификация Кейко . Уголок Спайви (Отчет). Ориэл-колледж Оксфордского университета. Архивировано из оригинала 4 марта 2016 года . Проверено 9 июля 2023 г.
- ^ Спайви, Майкл (30 сентября 2020 г.). Обзор дизайна OBC: Абстрактная машина Кейко . Уголок Спайви (Отчет). Ориэл-колледж Оксфордского университета . Проверено 9 июля 2023 г.
Компилятор Oxford Oberon-2 преобразует исходные программы в код для абстрактной машины на основе стека. ... машина Кейко.
- ^ Коллингборн, Х. (февраль 2000 г.). «Что изобретатель Паскаля сделал дальше». ПК Плюс . № 160.
- ^ Крелье, Режис (1994). Отдельная компиляция и расширение модулей (PhD). ETH Цюрих. дои : 10.3929/ethz-a-000945227 . hdl : 20.500.11850/141604 . Проверено 18 ноября 2018 г.
- ^ Доктор Майкл Спайви. «Спецификация Кейко» .
- ^ Доктор Майкл Спайви. «Обзор дизайна OBC: Абстрактная машина Кейко» . цитировать: «Компилятор Oxford Oberon-2 транслирует исходные программы в код для абстрактной машины на основе стека... машины Кейко»
Дальнейшее чтение
[ редактировать ]- « Древо генеалогии языка Оберон » хранится в ETHZ.
- «Вторая международная конференция по Модуле-2», сентябрь 1991 г.
- От Модулы до Оберона Вирта (1990)
- Программирование на Обероне - производное от программирования на Модуле-2 Вирта (1982)
- Язык программирования Оберон Вирт (1990)
- Отчет Оберона 2
- Язык программирования Оберон-2 Х. Мессенбёк, Н. Вирт, Институт компьютерных систем, ETH Цюрих , январь 1992 г. и Структурное программирование (1991) 12(4): 179-195.
- Различные ссылки, включая электронные онлайн-версии.
- Объектно-ориентированное программирование в Обероне-2 Ханспетер Мессенбёк (1994). (Доступно в Университете Иоганна Кеплера в формате PDF с дружеского разрешения Springer-Verlag)
- Шаблоны проектирования в Оберон-2 и Компонентном Паскале
- Проект Оберон. Проектирование операционной системы и компилятора Никлаус Вирт и Юрг Гуткнехт (2005)
- Проект Оберон. Проектирование операционной системы и компилятора Никлаус Вирт и Юрг Гуткнехт (2013)