11

Quiero escribir mi propio lenguaje de programación como una extensión del lenguaje de programación c. Todo el lenguaje de programación que estoy inventando son simplemente shorthands que se traducen en código c válido. Por ejemplo:extendiendo el lenguaje de programación c con gcc

namespace TcpConnection { 
    void* connect(char *addr) 
} 

se traduciría en:

void* TcpConnection_connect(char *addr) 

Todo lo que se hace es un simple reemplazo de nombre. Este es solo un ejemplo de una extensión que deseo proporcionar. Otra extensión simple sería la sobrecarga de función (esto concatenaría al final del nombre de función los tipos de sus argumentos.

En cualquier caso, el resultado es un código C perfectamente válido. ¿Hay alguna manera de hacerlo sin entrar en código gcc?

Respuesta

13

Puede escribir un preprocesador que analice su lenguaje y lo compile en C, que luego se pasará a gcc. Así es como funcionaron las primeras implementaciones de C++. Sin embargo, es posible que prefiera hackear el clang de LLVM, que está diseñado para admitir varios lenguajes de la familia C y, como parte de LLVM, también está diseñado para ser más modular y más fácil de extender.

2

Para creación de prototipos, tal vez solo vaya con un preprocesador escrito en el idioma de su elección (C, Perl, Python ...) y luego compilarlo en sus reglas de Makefile. Solo para obtener una forma fácil y económica de probarlo ...

Utilice una extensión de archivo diferente, y cambie .foo a .c.

0

Usted podría hackear algo encima de http://cil.sourceforge.net/

Clang es otra opción, pero no es la herramienta más útil de reescritura del código, y la modificación de su interfaz de programa de análisis no es tan fácil.

1

Hice algo similar para incrustar un lenguaje ensamblador para un formato de bytecode personalizado, usando algo de macro magia C99 y Perl.

Las macros

#define x3_pragma_(...) _Pragma(#__VA_ARGS__) 
#define x3_asm(...) ((const struct x3instruction []){ \ 
    x3_pragma_(X3 ASM __VA_ARGS__) \ 
}) 

transformar

x3_asm(exit = find val(0)) 

en

((const struct x3instruction []){ 
#pragma X3 ASM exit = find val(0) 
}) 

que consigue canaliza a través de un script en Perl para conseguir

((const struct x3instruction []){ 
{ { { X3_OPFINDVAL, { .as_uint = (0) } }, { X3_OPEXIT, { 0 } } } }, 
}) 

Una invocación muestra de gcc y Perl se vería así:

gcc -E foo.c | perl x3pp.pl | gcc -o foo.o -x c - 

Es más complicado que stricly necesario, pero he encontrado que es beneficioso que el preprocesador de C se ejecuta antes de que mi preprocesador costumbre, y también me gusta que mediante el uso pragmas, la fuente se mantiene legal C.

Cuestiones relacionadas