11

Я хочу написать свой собственный язык программирования как расширение языка программирования c. Весь язык программирования, который я изобретаю, - это просто короткие слова, которые переводят на действительный код. Например:расширение языка программирования c с помощью gcc

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

бы перевести:

void* TcpConnection_connect(char *addr) 

Все, что делается это просто замена имя. Это только один пример расширения, которое я хочу предоставить. Другим простым расширением была бы перегрузка функций (это соединило бы к концу имени функции типы своих аргументов.

В любом случае, результат вполне допустимый C-код. Есть ли способ сделать это, не вдаваясь в gcc-код?

ответ

13

Вы можете написать препроцессор, который анализирует ваш язык и скомпилирует его на C, который затем передается в gcc. Вот как работали ранние реализации C++. Однако вы можете предпочесть взломать clang LLVM, который предназначен для поддержки нескольких языков C-семейства и, как часть LLVM, также разработан, чтобы быть более модульным и легче распространяться.

2

Для прототипирования, возможно, просто перейдите к препроцессору написанный на выбранном вами языке (C, Perl, Python ...), а затем создайте его в своих правилах Makefile. Просто, чтобы получить простой, недорогой способ попробовать все это ...

Используйте другое расширение файла и поменяйте .foo на .c.

0

Вы могли взломать что-то на вершине http://cil.sourceforge.net/

Clang является еще одним вариантом, но это не самый полезный инструмент кода перезаписи и изменения его синтаксического анализатора фронтэнда не так просто.

1

Я сделал что-то подобное, чтобы встроить язык ассемблера для пользовательского формата байт-кода, используя некоторые макросы макросов C99 и Perl.

Макросы

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

преобразование

x3_asm(exit = find val(0)) 

в

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

, который получает по конвейеру через скрипт на Perl, чтобы получить

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

Образец призывание НКУ и Perl будет выглядеть следующим образом:

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

Это гораздо сложнее, чем stricly необходимо, но я нашел, что это выгодно, что препроцессор работает до моего пользовательского препроцессора, и мне также понравилось, что с помощью прагмы, источник остается легальным C.

Смежные вопросы