Charm es un lenguaje de programación desarrollado a principios de la década de 1990, con similitudes a los lenguajes RTL/2 , Pascal y C, además de poseer algunas características propias. El lenguaje Charm se define mediante una gramática libre de contexto que puede ser procesada por un analizador sintáctico descendente recursivo, tal como se describe en libros fundamentales sobre diseño de compiladores . [ 1 ] [ 2 ]
Se puso a disposición un conjunto de herramientas Charm que incluía un compilador, un ensamblador y un enlazador para la plataforma RISC OS de Acorn . [ 3 ] Posteriormente , Charm, adaptado para plataformas RISC OS, fue reseñado en la revista Archive. [ 4 ]
Charm se describe con más detalle en el libro electrónico Programming in Charm on the Raspberry Pi . [ 5 ]
Gramática
La definición de la gramática Charm en forma Backus-Naur, junto con ejemplos descriptivos de construcciones Charm, se define en la página del lenguaje Charm . [ 6 ]
El lenguaje está estructurado en bloques, y cada bloque se introduce mediante una palabra clave que describe la operación que se realiza en él, por ejemplo, ` for` , ` while` , ` repeat` ( iteración ), `case` , `if` ( selección ). Cada bloque está delimitado por `<p>` y `<span>`. Además, las líneas de código dentro de un bloque suelen tener sangría para mayor claridad, aunque esto no es obligatorio ya que se ignoran los espacios en blanco.{}
Cada texto que cumple con las normas gramaticales representa una colección de código ejecutable y datos asociados que pueden ser utilizados por un conjunto de herramientas Charm como un componente al ensamblar un programa que puede ejecutarse bajo un sistema operativo, utilizando los servicios que proporciona para realizar tareas útiles como el procesamiento de datos o la interacción con los usuarios a través de una interfaz gráfica de usuario (GUI).
Tipos de datos
Charm es un lenguaje fuertemente tipado, pero permite algunas conversiones implícitas entre tipos numéricos y de punto flotante. Se admiten los siguientes tipos básicos de variables:
- int – números enteros
- char – personajes
- booleano – valores booleanos ( verdadero o falso )
- números reales – números de punto flotante
Los agregados de datos del mismo tipo pueden declararse e inicializarse estáticamente mediante la palabra clave `array` , y pueden ser multidimensionales. Los agregados de diferentes tipos pueden declararse mediante la palabra clave `record` , y dicha declaración puede definir una unión de campos de registro que se superponen en términos de asignación de almacenamiento. Los módulos también pueden agregar una combinación de miembros de datos estáticos y dinámicos. Las instancias de registros y módulos (solo contenido dinámico) pueden instanciarse en la pila o en el montón mediante el operador `new` . Los módulos también pueden definir un constructor `~new` para inicializar datos dinámicos y el correspondiente deconstructor `~delete` para liberar recursos de forma similar al lenguaje C++.
Referencias
Los datos o procedimientos dentro del ámbito de un módulo pueden hacerse globales para la aplicación final mediante la palabra clave `export` . Si un módulo desea hacer referencia a un procedimiento o datos de otro módulo Charm, lo hace mediante la palabra clave `import` . Los módulos pueden contener variables miembro basadas en instancias, accesibles a través de procedimientos declarados con la palabra clave `dynamic` mediante el primer parámetro implícito `this` .
Se pueden hacer referencias a construcciones y procedimientos de datos utilizando la palabra clave `ref` . Estas referencias se pueden eliminar utilizando la palabra clave `val` . Al usar variables de referencia, se dispone de operadores de comparación para comprobar si dos variables de referencia se refieren al mismo elemento de datos ( ) o si los datos a los que apuntan son los mismos ( ). :=: =
Ejemplo
El programa clásico original "Hola mundo" escrito en Charm es:
ext proc write_string (ref array char); módulo hola; ent proc start (); escribir_cadena ("Hola mundo"); fin_procedimiento; fin_módulo; y la versión más reciente equivalente tras los cambios sintácticos evolutivos del lenguaje es:
importar lib.Out; módulo Hola { exportar proc ~start () { Out.vdu.str ("Hola mundo"). nl(); } } Juego de herramientas
Se espera que las implementaciones del conjunto de herramientas proporcionen un compilador y un ensamblador para generar archivos objeto a partir del código fuente de Charm y del código fuente del ensamblador, que luego se pueden enlazar junto con los archivos de biblioteca y de soporte en tiempo de ejecución para generar un programa ejecutable.
En el momento de redactar este texto, solo está disponible para su descarga gratuita una única instalación del conjunto de herramientas Charm. Las herramientas están escritas en el lenguaje Charm y su código fuente se distribuye bajo la Licencia Pública General de GNU . Se ejecutan en PC con RISC OS y plataformas con procesadores ARM (como la Raspberry Pi ), así como en emuladores de RISC OS alojados en plataformas Windows o Linux (como RPCEmu ). Se admite la generación de código para operaciones de coma flotante de doble precisión asistidas por hardware en plataformas basadas en chips ARM compatibles con la arquitectura de coprocesador VFP versión 2 .
Compilador
El compilador Charm es un compilador recursivo descendente de una sola pasada que analiza el código fuente de Charm para generar cuádruplas de la forma result := lhs op rhs en un lenguaje intermedio que admite operaciones aritméticas, lógicas y de flujo de control. Los datos se almacenan en variables temporales que se asignan a registros y ubicaciones de memoria en la parte posterior del compilador. Actualmente existen dos partes posteriores: una que genera lenguaje ensamblador Motorola 68000 y otra que genera arquitectura ARM . [ 7 ]
La salida cuádruple del ejemplo "hola mundo" es:
parámetro l1$ llamar write_string[proc (ref array char) void]
y la salida del ensamblador es:
cadena "hola" xdef _start alinear _start xref _write_string stmfd sp ! ,{ rp } adr r0 , _l1$ bl _write_string ldmfd sp ! ,{ pc } dirección alinear _l1$ cadena "Hola mundo" direct endEn versiones más recientes de Charm, los I/Oprocedimientos se han dividido en sus propios módulos In y Out . Otros procedimientos de la biblioteca estándar se organizan en un conjunto de registros con referencias a procedimientos como campos. Como parte de esta reorganización, el write_stringmétodo ahora se invoca a través del módulo de la biblioteca de tiempo de ejecución Outmediante una referencia de miembro estático .vducomo procedimiento, stres decir, en el ejemplo hello world anterior write_string ("Hello world")se convierte en Out.vdu.str ("Hello world").
Ensamblador
El ensamblador acepta mnemónicos de instrucciones, declaraciones de datos y directivas, y construye un archivo objeto que contiene información fácilmente comprensible para la CPU del procesador de destino, en particular instrucciones de código codificadas en binario.
Enlazador
Uno y solo uno de los módulos Charm vinculados para formar un programa ejecutable debe contener un procedimiento que coincida con una de las siguientes firmas:
exportar proc ~start () export proc ~start (int argc, ref array ref array char argv)
Esto es análogo a la función principal en los lenguajes C y Javaargc . Aquí contiene el número de parámetros pasados en la línea de comandos y argvcontiene una referencia a una matriz de argc + 1cadenas (una cadena por parámetro posicional en orden y un carácter de terminación nil).
Además, los módulos pueden contener opcionalmente procedimientos estáticos de inicio y apagado que se invocan durante el inicio y el apagado del programa y que coinciden con las firmas:
export proc ~startup () export proc ~shutdown ()
El enlazador añade la información de cabecera necesaria que requiere el sistema operativo para ejecutar el programa y garantiza que se ejecute el código de soporte del ensamblador de la biblioteca de tiempo de ejecución, que configura el entorno de tiempo de ejecución (punteros de datos y de pila) y transfiere el control al procedimiento de inicio de la aplicación.
Opcionalmente, se genera un archivo de mapa que muestra los nombres de todos los módulos vinculados para formar el programa, junto con datos globales y referencias de código, que pueden ser utilizados por depuradores y analizadores de rendimiento.
Referencias
- ^ ISBN D-201-10073-8 Aho, Principios de diseño de compiladores de Ullman
- ↑ ISBN D-201-10194-7 Aho, Sethi, Ullman Compiladores: Principios, técnicas y herramientas
- ↑ Wade, Stephen (junio de 1996). " ¿ Amuleto o baratija?" . Acorn User . págs. 50–51 . Recuperado el 28 de agosto de 2021 .
- ↑ Wraith, Gavin (enero de 2012). "El lenguaje Charm: una reseña" . Archivo . Vol. 23, n.º 4, pág. 13. Consultado el 28 de agosto de 2021 .
- ↑ Junio de 2013 Libro electrónico Kindle Programación de encantos en la Raspberry Pi
- ↑ Charm RISC OS, página de idioma
- ↑ ISBN 0-9512579-0-0Programación en lenguaje ensamblador ARM de Peter Cockerell
Enlaces externos
- Encanto para RISC OS
- Emulador de PC RISC
- Centro de información de ARM
- Lenguajes de programación
- Herramientas de programación RISC OS