![]() |
|
[C]Brainfuck Interpreter - Printable Version +- Sinisterly (https://sinister.ly) +-- Forum: Coding (https://sinister.ly/Forum-Coding) +--- Forum: C, C++, & Obj-C (https://sinister.ly/Forum-C-C-Obj-C) +--- Thread: [C]Brainfuck Interpreter (/Thread-C-Brainfuck-Interpreter) |
[C]Brainfuck Interpreter - Slarek - 09-13-2013 Since i'm making the Brainfuck tutorial, i decided to make an interpreter for it:Smile: Code: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEMORY_SIZE 30000
int files = 0;
char ** filelist = 0;
FILE * file = 0;
char * program = 0;
char memory[MEMORY_SIZE];
void print_guide(char * runname);
int file_is_alive(char * name);
void add_file_tolist(char * name);
int decent_character(char character);
int load_program(char * name);
int check_syntax(char * name);
void run_program(char * name);
void endfunction();
int main(int number_of_arguments, char **arguments)
{
int i;
atexit(endfunction);
if (number_of_arguments < 2) {
print_guide(arguments[0]);
return EXIT_FAILURE;
}
for (i = 1; i < number_of_arguments; ++i) {
if (file_is_alive(arguments[i])) {
add_file_tolist(arguments[i]);
}
else {
printf("Error! File %s was not found or it's unable to open!\n", arguments[i]);
print_guide(arguments[0]);
return EXIT_FAILURE;
}
}
for (i = 0; i < files; ++i) {
if (load_program(filelist[i])
&& check_syntax(filelist[i])) {
run_program(filelist[i]);
}
}
return EXIT_SUCCESS;
}
void print_guide(char * runname)
{
printf("Brainfuck-compiler 0.1\nAction: %s files\n", runname);
}
int file_is_alive(char * name)
{
file = fopen(name, "r");
if (!file) {
return 0;
}
fclose(file);
return 1;
}
void add_file_tolist(char * name)
{
/* Expand the list */
++files;
filelist = (char**)realloc(filelist, files * sizeof(char*));
if (!filelist) {
printf("Program ran out of memory when creating the file list!\n");
exit(EXIT_FAILURE);
}
/* Allocate memory and put the file name into there */
filelist[files - 1] = (char*) malloc(strlen(name) + 1);
if (!filelist[files - 1]) {
printf("Program ran out of memory when creating the file list!\n");
exit(EXIT_FAILURE);
}
strcpy(filelist[files - 1], name);
}
int decent_character(char character)
{
if (character == '<') return 1;
if (character == '>') return 1;
if (character == '+') return 1;
if (character == '-') return 1;
if (character == '.') return 1;
if (character == ',') return 1;
if (character == '[') return 1;
if (character == ']') return 1;
return 0;
}
int load_program(char * name)
{
size_t size;
int i, j;
file = fopen(name, "r");
if (!file) {
printf("Error! File '%s' couldn't be opened!\n", name);
exit(EXIT_FAILURE);
}
/* Measure the file */
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
/* Release the old code and allocate new */
if (program) {
free(program);
}
program = (char*)malloc(size + 1);
if (!program) {
printf("Error! For the program in the file '%s' was not derived memory.", name);
exit(EXIT_FAILURE);
}
/* Read the whole file */
if (fread(program, size, 1, file) != 1) {
printf("Error! File '%s' couldn't be opened!\n", name);
exit(EXIT_FAILURE);
}
program[size] = 0;
/* Delete characters which are not part of the program */
for (i = j = 0; program[i] != 0; ++i) {
if (decent_character(program[i])) {
program[j] = program[i];
++j;
}
}
program[j] = 0;
return 1;
}
int check_syntax(char * name)
{
int i, brackets;
if (!program) {
return 0;
}
/* Count that there are enough brackets for both ways */
for (i = brackets = 0; program[i] != 0; ++i) {
if (program[i] == '[') {
++brackets;
}
else if (program[i] == ']') {
--brackets;
}
}
if (brackets != 0) {
printf("There is error in the syntax of the file '%s'!\n", name);
}
return brackets == 0;
}
void run_program(char * name)
{
int position = 0, brackets;
char *pointer = memory;
if (!program) {
return;
}
printf("Run '%s'\n", name);
/* Reset the memory */
memset(memory, 0, MEMORY_SIZE);
/* In the end of the text, there is 'zeromark', repeat until that */
while (program[position] != 0) {
switch (program[position]) {
case '>':
++pointer;
break;
case '<':
--pointer;
break;
case '+':
++*pointer;
break;
case '-':
--*pointer;
break;
case '.':
putchar(*pointer);
fflush(stdout);
break;
case ',':
*pointer = getchar();
break;
case '[':
if (*pointer == 0) {
/* Get equivalent closing bracket */
brackets = 1;
while (brackets) {
++position;
if (program[position] == '[') {
++brackets;
}
else if (program[position] == ']') {
--brackets;
}
}
}
break;
case ']':
if (*pointer != 0) {
/* Get equilevant starting bracket */
brackets = 1;
while (brackets) {
--position;
if (program[position] == ']') {
++brackets;
}
else if (program[position] == '[') {
--brackets;
}
}
}
break;
}
/* To the next character in the code */
++position;
}
printf("\nThe end.\n");
}
void endfunction()
{
int i;
if (filelist) {
for (i = 0; i < files; ++i) {
if (filelist[i]) {
free(filelist[i]);
}
}
free(filelist);
}
if (program) {
free(program);
}
if (file) {
fclose(file);
}
}RE: [C]Brainfuck Interpreter - noize - 09-15-2013 If you coded this from scratch, well done. This looks like a good job to me, you even freed the allocated space in the end, which is a good habit. This code only looks bad: Code: {
if (character == '<') return 1;
if (character == '>') return 1;
if (character == '+') return 1;
if (character == '-') return 1;
if (character == '.') return 1;
if (character == ',') return 1;
if (character == '[') return 1;
if (character == ']') return 1;
return 0;
}Why not an if-or-if statement? Or even making an array with all the chars, then iterating through it with an if statement, but this thing you did hurts my stomach. RE: [C]Brainfuck Interpreter - Slarek - 09-16-2013 :Grin: i really don't know why i did that. Maybe i should change it. RE: [C]Brainfuck Interpreter - noize - 09-16-2013 (09-16-2013, 04:40 AM)Slarek Wrote: :Grin: i really don't know why i did that. Maybe i should change it. Well, it's not erroneous, of course, but I wonder what ArkPhaze would say, lol. With 8 commands, a Brainfuck interpreter is a nice and relatively simple thing to code, as you mainly have to work out the basis, and the add-commands part is far shorter. More fun and less work. RE: [C]Brainfuck Interpreter - Slarek - 09-17-2013 @noize I think i'm going to change it. I do not want to face the anger of ArkPhaze. |