Pull to refresh

Компилятор brainfuck с оптимизацией и кроссплатформенностю

Самый известный эзотерический язык программирования — brainfuck, не смотря на внешнюю сложность есть простым. Благодаря этому есть много интерпретаторов этого языка. У всех интерпретаторов (И не только Brainfuck) есть один недостаток — программа работает слишком медленно а компиляторы не есть кросс платформенными. В статье рассказывается о том, как сделать компилятор Brainfuck, который будет кросс платформенным и программы, скомпилированные им будут быстро выполнятся.

Код на 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
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.