Самый известный эзотерический язык программирования — brainfuck, не смотря на внешнюю сложность есть простым. Благодаря этому есть много интерпретаторов этого языка. У всех интерпретаторов (И не только Brainfuck) есть один недостаток — программа работает слишком медленно а компиляторы не есть кросс платформенными. В статье рассказывается о том, как сделать компилятор Brainfuck, который будет кросс платформенным и программы, скомпилированные им будут быстро выполнятся.
Код на Brainfuck транслируется в программу на языке C, которая в свою очередь компилируется в бинарный код целевой платформы и выполняется со скоростью приложения, написанного на C. Для трансляции с Brainfuck на C использовалась таблица эквивалентов команд Brainfuck на C. После трансляции программа на C компилируется gcc с включенными оптимизациями.
Brainfuck — Википедия
Страница на google code
Код на Brainfuck транслируется в программу на языке C, которая в свою очередь компилируется в бинарный код целевой платформы и выполняется со скоростью приложения, написанного на C. Для трансляции с Brainfuck на C использовалась таблица эквивалентов команд Brainfuck на C. После трансляции программа на C компилируется gcc с включенными оптимизациями.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
if(argc==1) //если не указан файл с исходником
{
puts("bfc: no input files"); //выводим текст с сообщением про это
return 0; //и завершаем программу
}
char* filename = argv[1]; // имя файла с исходником
FILE* f = fopen(filename,"r"); // открываем файл с исходником
char program[42000]; //массив, у котором хранится программа
fgets(program,42000,f); //считываем программу у массив
FILE* fc= fopen("bfc.tmp.c","w"); //временный файл с исходником на C
fputs("int main(){char* p;char s[1000];p=s;",fc); //записываем у файл с исходником на C начало
for(int i=0;i<strlen(program);i++) //foreach по массиву с программой
{
if(program[i]=='>') fputs("++p;",fc); //конвертируется программа с bf на C по таблице с википедии
else if(program[i]=='<') fputs("--p;",fc);
else if(program[i]=='+') fputs("++(*p);",fc);
else if(program[i]=='-') fputs("--(*p);",fc);
else if(program[i]=='.') fputs("putchar(*p);",fc);
else if(program[i]==',') fputs("*p=getchar();",fc);
else if(program[i]=='[') fputs("while(*p){",fc);
else if(program[i]==']') fputs("}",fc);
else //если попадается неизвестный символ
{
puts("unknown character"); //выводим соответствующее сообщение
putchar(program[i]);
puts("\n");
}
}
fputs("}",fc); //записываем у файл с исходником на C конец
fclose(fc); //закрываем файлы
fclose(f);
system("gcc -O2 -march=native bfc.tmp.c "); //компиляция программы с оптимизацией
//под процессор установленный в системе
system("del bfc.tmp.c"); //удаление временного файла у windows
system("rm bfc.tmp.c"); //и у linux
return 0; //КонецѢ
}
Brainfuck — Википедия
Страница на google code