Oberon-2 es una extensión del lenguaje de programación Oberon original que agrega reflejos limitados y facilidades de programación orientadas a objetos , arreglos abiertos como tipos de base de puntero, exportación de campo de solo lectura y reintroduce el bucle de Modula-2 .FOR
Paradigmas | Imperativo , estructurado , modular , orientado a objetos |
---|---|
Familia | Wirth Oberon |
Diseñada por | Niklaus Wirth Hanspeter Mössenböck |
Desarrollador | ETH Zúrich |
Apareció por primera vez | 1991 |
Disciplina de mecanografía | Fuerte , híbrido ( estático y dinámico ) |
Alcance | Léxico |
Plataforma | Ceres ( NS32032 ), IA-32 , x86-64 |
SO | Windows , Linux , Solaris , macOS |
Sitio web | www |
Influenciado por | |
Oberon , Modula-2 , Objeto Oberon | |
Influenciado | |
Oberon-07 , Zonnon , Oberon activo , Componente Pascal , Go , Nim |
Fue desarrollado en 1991 en ETH Zurich por Niklaus Wirth y Hanspeter Mössenböck , que ahora se encuentra en el Institut für Systemsoftware (SSW) de la Universidad de Linz , Austria. Oberon-2 es un superconjunto de Oberon, es totalmente compatible con él y fue un rediseño de Object Oberon .
Oberon-2 heredó la reflexión limitada y la herencia única ("extensión de tipo") sin las interfaces o mixins de Oberon, pero agregó métodos virtuales eficientes ("procedimientos de tipo enlazado"). Las llamadas a métodos se resolvieron en tiempo de ejecución utilizando tablas de métodos virtuales de estilo C ++ .
En comparación con los lenguajes totalmente orientados a objetos como Smalltalk , en Oberon-2, los tipos y clases de datos básicos no son objetos , muchas operaciones no son métodos, no hay paso de mensajes (se puede emular de alguna manera mediante reflexión y mediante la extensión del mensaje, como se demostró en ETH Oberon), y el polimorfismo se limita a subclases de una clase común (no se escribe pato como en Python , [1] y no es posible definir interfaces como en Java ). Oberon-2 no admite la encapsulación a nivel de objeto o clase, pero los módulos se pueden usar para este propósito.
La reflexión en Oberon-2 no usa metaobjetos , sino que simplemente lee descriptores de tipo compilados en los binarios ejecutables y expuestos en los módulos que definen los tipos y / o procedimientos. Si el formato de estas estructuras se expone a nivel de lenguaje (como es el caso de ETH Oberon, por ejemplo), la reflexión podría implementarse a nivel de biblioteca . Por lo tanto, podría implementarse casi en su totalidad a nivel de biblioteca, sin cambiar el código de idioma. De hecho, ETH Oberon hace un uso extensivo de las habilidades de reflexión a nivel de lenguaje y de biblioteca.
Oberon-2 proporciona soporte de tiempo de ejecución integrado para la recolección de basura similar a Java y realiza comprobaciones de índices de matriz y límites, etc., que eliminan los posibles problemas de sobrescritura de límites de matriz y pila y problemas de administración de memoria manual inherentes a C y C ++. La compilación separada utilizando archivos de símbolos y espacios de nombres a través de la arquitectura del módulo garantiza reconstrucciones rápidas, ya que solo es necesario volver a compilar los módulos con interfaces modificadas.
El componente de lenguaje Pascal [2] es un refinamiento (un superconjunto) de Oberon-2.
Código de ejemplo
El siguiente código de Oberon-2 implementaría una clase de lista mínima :
Listas de MÓDULO ; (*** declara constantes, tipos y variables globales ***) TYPE List * = PUNTERO A ListNode ; ListNode = RECORD valor : INTEGER ; siguiente : Lista ; FIN ; (*** declarar procedimientos ***) PROCEDIMIENTO ( l : Lista ) Agregar * ( v : INTEGER ); COMIENZO SI l = NULO ENTONCES NUEVO ( l ); (* crear instancia de registro *) l . valor : = v ELSE l . siguiente . Agregar ( v ) (* llamada recursiva a .add (n) *) END END Agregar ; PROCEDIMIENTO ( l : Lista ) Obtener * () : INTEGER ; VAR v : INTEGER ; BEGIN IF l = NIL THEN RETURN 0 (* .get () siempre debe devolver un INTEGER *) ELSE v : = l . valor ; (* esta línea se bloqueará si l es NIL *) l : = l . siguiente ; RETURN v END END Obtener ; Listas FINALES .
Extensiones de Oberon-2 a Oberon [3]
Procedimientos ligados al tipo
Los procedimientos se pueden vincular a un tipo de registro (o puntero). Son equivalentes a los métodos de instancia en terminología orientada a objetos.
Exportación de solo lectura
El uso de variables exportadas y campos de registro se puede restringir al acceso de solo lectura. Esto se muestra con una bandera de visibilidad "-".
Matrices abiertas
Las matrices abiertas que antes solo podían declararse como tipos de parámetros formales ahora pueden declararse como tipos base de puntero.
FOR declaración
La FOR
declaración de Pascal y Modula-2 no se implementó en Oberon. Se reintroduce en Oberon-2.
Comprobación del tipo de tiempo de ejecución
Oberon-2 proporciona varios mecanismos para verificar el tipo dinámico de un objeto. Por ejemplo, cuando un objeto Bird puede ser instanciado a un Duck o un Cuckoo, Oberon-2 permite al programador responder al tipo real del objeto en tiempo de ejecución.
El primer enfoque, el más convencional, es confiar en el sistema de encuadernación de tipos . El segundo enfoque es utilizar la WITH
declaración , que permite verificar directamente el subtipo dinámico de una variable. En ambos casos, una vez que se ha identificado el subtipo, el programador puede hacer uso de cualquier procedimiento o variable ligado al tipo que sea apropiado para el subtipo. A continuación se muestran ejemplos de estos enfoques.
Tenga en cuenta que la forma de WITH
declaración utilizada en Oberon-2 no está relacionada con la declaración WITH de Pascal y Modula-2. Este método de abreviar el acceso a los campos de registro no está implementado en Oberon o Oberon-2.
Tipo de encuadernación
MÓDULO Aves ; TYPE Bird * = GRABAR sonido * : ARRAY 10 OF Char ; FIN ; FIN Pájaros . MÓDULO Patos ; IMPORTACIÓN de aves ; TIPO Pato * = REGISTRO ( Pájaros . Pájaro ) FIN ; PROCEDIMIENTO SetSound * ( VAR bird : Duck ); COMIENZO pájaro . sonido : = "¡Cuac!" END SetSound ; FIN Patos . MÓDULO Cucos ; IMPORTACIÓN de aves ; TIPO Cuco * = REGISTRO ( Pájaros . Pájaro ) FIN ; PROCEDIMIENTO SetSound * ( VAR bird : Cuckoo ); COMIENZO pájaro . sonido : = "¡Cuco!" END SetSound ; FIN Cucos .
WITH
declaración
Prueba de MODULO ; IMPORTACIÓN fuera , pájaros , cucos , patos ; TIPO SomeBird * = REGISTRO ( Birds . Bird ) FIN ; VAR sb : SomeBird ; c : Cucos . cuco ; d : patos . pato ; PROCEDIMIENTO SetSound * ( VAR bird : Birds . Bird ); EMPEZAR CON PÁJARO : Cucos . Cuco HACER pájaro . sonido : = "¡Cuco!" | pájaro : patos . Pato HACER pájaro . sonido : = "¡Cuac!" ELSE pájaro . sonido : = "¡Tweet!" END END SetSound ; PROCEDIMIENTO MakeSound * ( VAR b : Birds . Bird ); COMIENZO Fuera . Ln ; Fuera . Cuerda ( b . Sonido ); Fuera . Ln END MakeSound ; COMENZAR SetSound ( c ); SetSound ( d ); SetSound ( sb ); MakeSound ( c ); MakeSound ( d ); MakeSound ( sb ) END Test .
POINTER
MÓDULO PointerBirds ; IMPORT hacia fuera ; TYPE BirdRec * = GRABAR sonido * : ARRAY 10 OF Char ; FIN ; DuckRec * = RECORD ( BirdRec ) FIN ; CuckooRec * = RECORD ( BirdRec ) FIN ; Bird = PUNTERO A BirdRec ; Cuckoo = PUNTERO A CuckooRec ; Duck = PUNTERO A DuckRec ; VAR pb : pájaro ; pc : Cuco ; pd : pato ; PROCEDIMIENTO SetDuckSound * ( pájaro : pato ); COMIENZO pájaro . sonido : = "¡Cuac!" END SetDuckSound ; PROCEDIMIENTO SetCuckooSound * ( pájaro : Cuco ); COMIENZO pájaro . sonido : = "¡Cuco!" END SetCuckooSound ; PROCEDIMIENTO SetSound * ( pájaro : pájaro ); EMPEZAR CON pájaro : Cuco DO SetCuckooSound ( pájaro ) | pájaro : Pato HACER SetDuckSound ( pájaro ) ELSE pájaro . sonido : = "¡Tweet!" END END SetSound ; COMENZAR NUEVO ( pc ); NUEVO ( pd ); SetCuckooSound ( pc ); SetDuckSound ( pd ); Fuera . Ln ; Fuera . String ( pc ^ . Sonido ); Fuera . Ln ; Fuera . Ln ; Fuera . String ( pd ^ . Sonido ); Fuera . Ln ; SetSound ( pc ); SetSound ( pd ); Fuera . Ln ; Fuera . String ( pc ^ . Sonido ); Fuera . Ln ; Fuera . Ln ; Fuera . String ( pd ^ . Sonido ); Fuera . Ln ; (* -------------------------------------- *) (* Pasar tipo dinámico al procedimiento * ) pb : = pd ; SetDuckSound ( pb ( pato )); Fuera . Ln ; Fuera . String ( pb ^ . Sonido ); Fuera . Ln ; pb : = pc ; SetCuckooSound ( pb ( cuco )); Fuera . Ln ; Fuera . String ( pb ^ . Sonido ); Fuera . Ln ; (* -------------------------------------- *) SetSound ( pb ); Fuera . Ln ; Fuera . String ( pb ^ . Sonido ); Fuera . Ln ; pb : = pd ; SetSound ( pb ); Fuera . Ln ; Fuera . String ( pb ^ . Sonido ); Fuera . Ln ; (* -------------------------------------- *) NUEVO ( pb ); SetSound ( pb ); Fuera . Ln ; Fuera . String ( pb ^ . Sonido ); Fuera . Ln END PointerBirds .
IS
operador
Un tercer enfoque es posible utilizando el IS
operador . Este es un operador de relación con la misma precedencia que igual ( =
), mayor ( >
), etc. pero que prueba el tipo dinámico. Sin embargo, a diferencia de los otros dos enfoques, no permite al programador acceder al subtipo que se ha detectado.
Sintaxis
El desarrollo de la familia de lenguajes ALGOL → Pascal → Modula-2 → Oberon → Component Pascal está marcado por una reducción en la complejidad de la sintaxis del lenguaje . Se describe todo el lenguaje Oberon-2 ( Mössenböck & Wirth, marzo de 1995 ) utilizando sólo 33 producciones gramaticales en la forma extendida Backus-Naur , como se muestra a continuación.
Módulo = ID DE MÓDULO ";" [ 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 "=" Tipo . VarDecl = IdentList ":" Tipo . ProcDecl = PROCEDIMIENTO [ Receptor ] IdentDef [ FormalPars ] ";" DeclSeq [ BEGIN StatementSeq ] END ident . ForwardDecl = PROCEDIMIENTO "^" [ Receptor ] IdentDef [ FormalPars ]. FormalPars = "(" [ FPSection { ";" FPSection }] ")" [ ":" Qualident ]. FPSection = [ VAR ] ident { "," ident } ":" Tipo . Receptor = "(" [ VAR ] ident ":" ident ")" . Tipo = Qualident | ARRAY [ ConstExpr { "," ConstExpr }] OF Type | RECORD [ "(" Qualident ")" ] FieldList { ";" FieldList } END | PUNTERO A Tipo | PROCEDIMIENTO [ FormalPars ]. FieldList = [ IdentList ":" Tipo ]. StatementSeq = Statement { ";" Declaración }. Declaración = [ Designador ": =" Expr | Designador [ "(" [ ExprList ] ")" ] | IF Expr THEN StatementSeq { ELSIF Expr THEN StatementSeq } [ ELSE StatementSeq ] END | CASE Expr OF Case { "|" Case } [ ELSE StatementSeq ] END | MIENTRAS Expr DO StatementSeq END | REPETIR StatementSeq HASTA Expr | FOR ident ": =" Expr TO Expr [ BY ConstExpr ] DO StatementSeq END | LOOP StatementSeq END | CON Guard DO StatementSeq { "|" Guard DO StatementSeq } [ ELSE StatementSeq ] END | SALIR | VUELTA [ Expr ] ]. Case = [ CaseLabels { "," CaseLabels } ":" StatementSeq ]. CaseLabels = ConstExpr [ ".." ConstExpr ]. Guard = Qualident ":" Qualident . ConstExpr = Expr . Expr = SimpleExpr [ Relación SimpleExpr ]. SimpleExpr = [ "+" | "-" ] Término { AddOp Term }. Término = Factor { MulOp Factor }. Factor = Designador [ "(" [ ExprList ] ")" ] | numero | personaje | cadena | NIL | Establecer | "(" Expr ")" | Factor "~" . Set = "{" [ Elemento { "," Elemento }] "}" . Elemento = Expr [ ".." Expr ]. Relación = "=" | "#" | "<" | "<=" | ">" | "> =" | IN | ES . AddOp = "+" | "-" | O . MulOp = "*" | "/" | DIV | MOD | "&" . Designator = Qualident { "." ident | "[" ExprList "]" | "^" | "(" Qualident ")" }. ExprList = Expr { "," Expr }. IdentList = IdentDef { "," IdentDef }. Qualident = [ ident "." ] ident . IdentDef = ident [ "*" | "-" ].
Implementaciones
Los compiladores de Oberon-2 mantenidos por ETH incluyen versiones para Windows , Linux , Solaris , macOS .
El compilador Oxford Oberon-2 se compila en código de máquina nativo y puede usar un JIT en Windows, Linux y Mac OS X. Mike Spivey lo crea / mantiene y usa la máquina virtual Keiko .
Hay un escáner Oberon-2 Lex y un analizador Yacc de Stephen J. Bevan de la Universidad de Manchester, Reino Unido, basado en el de la referencia de Mössenböck y Wirth. Está en la versión 1.4.
Existe una versión llamada Native Oberon que incluye un sistema operativo y puede arrancar directamente en hardware de clase de PC.
En ETHZ también se ha desarrollado una implementación .NET de Oberon con la adición de algunas extensiones menores relacionadas con .NET.
Programmer's Open Workbench (POW!) [4] es un entorno de desarrollo integrado muy simple, que se proporciona con editor, enlazador y compilador Oberon-2. Esto se compila en ejecutables de Windows . Se proporciona el código fuente completo ; el compilador está escrito en Oberon-2.
El compilador Java to Oberon (JOB) fue escrito en la Universidad de Vologda en Rusia. Produce código objeto en forma de archivos de clase Java (código de bytes ). Se proporcionan algunas clases específicas de JOB que son compatibles con Java, pero que utilizan una jerarquía de componentes más parecida a la de Oberon.
El compilador Optimizing Oberon-2 compila en C, utilizando la cadena de herramientas GNU Compiler Collection (GCC) para la generación de programas.
Oberon Script es un compilador que traduce el lenguaje completo de Oberon a JavaScript . El compilador está escrito en JavaScript y, por lo tanto, se puede llamar desde páginas web para procesar scripts escritos en Oberon.
XDS Modula2 / Oberon2 es un sistema de desarrollo de Excelsior LLC, Novosibirsk, Rusia. Contiene un compilador de optimización para Intel Pentium, o traductor "via-C" para el desarrollo de software multiplataforma . Disponible para Windows y Linux. El compilador está escrito en Oberon-2 y se compila solo.
Oberon Revival es un proyecto para llevar Oberon 2 y Component Pascal ( BlackBox Component Builder ) a Linux y Win32. El puerto Linux de BlackBox no estaba disponible antes y originalmente se ejecutaba solo en Microsoft Windows.
XOberon es un sistema operativo en tiempo real para PowerPC , escrito en Oberon-2.
Ver también
- A2 (sistema operativo)
- Oberon (sistema operativo)
- Oberon (lenguaje de programación)
Referencias
- ^ "Lectura relacionada" . Dr. Dobb's .
- ^ Pfister, Cuno (2001). "Novedades en Component Pascal (cambios de Oberon-2 a CP)" (PDF) . Microsistemas de Oberon . Archivado desde el original (PDF) el 15 de mayo de 2011 . Consultado el 10 de enero de 2007 .
- ^ Diferencias entre Oberon y Oberon-2, Mössenböck y Wirth (1993)
- ^ Collingbourne, H. (febrero de 2000). "Lo que hizo a continuación el inventor de Pascal". PC Plus . No. 160.
Evolución de Oberon y Oberon-2
- " Árbol genealógico de lenguas de Oberon " mantenido en ETHZ
- "Segunda Conferencia Internacional Modula-2", septiembre de 1991.
Documentos detallados
- De Modula a Oberon Wirth (1990)
- Programación en Oberon: un derivado de la programación en Modula-2 Wirth (1982)
- El lenguaje de programación Oberon Wirth (1990)
- Informe Oberon 2
- El lenguaje de programación Oberon-2 H. Mössenböck, N. Wirth, Institut für Computersysteme, ETH Zurich , enero de 1992 y Programación estructurada (1991) 12 (4): 179-195.
Libros
- Varias referencias, incluidas las versiones electrónicas en línea
- Programación orientada a objetos en Oberon-2 Hanspeter Mössenböck (1994). (Disponible en la Universidad Johannes Kepler como PDF con el amable permiso de Springer-Verlag)
- Patrones de diseño en Oberon-2 y Component Pascal
- Proyecto Oberon. El diseño de un sistema operativo y un compilador Niklaus Wirth & Jürg Gutknecht (2005)
- Proyecto Oberon. El diseño de un sistema operativo y un compilador Niklaus Wirth & Jürg Gutknecht (2013)
enlaces externos
- Sitio web oficial , ETH Zürich
- Página de referencia de Oberon en ETH Zürich
- Oberon en SSW, Linz
- Tutorial de Pow (en rumano), por Dan Popa
- ftp://ftp.inf.ethz.ch/pub/Oberon/
- El modelo de reflexión de Oberon-2 y sus aplicaciones