Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
knoode committed Jul 13, 2024
0 parents commit 79bb542
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CFLAGS=-O2 -Wall
SRC=main.c interactive.c
HEADER=interactive.h
OUT=bfuck

$(OUT): $(SRC) $(HEADER)
$(CC) $(SRC) $(CFLAGS) -o $(OUT)

19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Brainfuck Interpreter
Written in C. Nothing really interesting. Only distinct feature is interactive mode

`hw.bf` and `hw_2.bf` are hello world code examples in brainfuck.

Build:
```
make
```

Interpret file:
```
./bfuck <file>
```

Interactive mode:
```
./bfuck
```
2 changes: 2 additions & 0 deletions hw.bf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]
<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.
3 changes: 3 additions & 0 deletions hw_2.bf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++
.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.
------.--------.>+.>.
51 changes: 51 additions & 0 deletions interactive.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// interactive.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include "interactive.h"

void start_interactive()
{
char* code = NULL;
_Bool exit = false;

printf("Type 'q' to quit from interactive mode\n");

while (!exit) {
printf(">>> ");

code = read_code();
size_t code_len = strlen(code);

if (code[0] == 'q') {
exit = true;
} else {
run_code(code, code_len);
printf("\n");
}

free(code);
}
}

char* read_code()
{
char* code_buffer = NULL;
size_t buf_size;

if (getline(&code_buffer, &buf_size, stdin) == -1) {
if (feof(stdin)) {
printf("\n");
exit(EXIT_SUCCESS);
} else {
perror("Error: Cannot getline()");
exit(EXIT_FAILURE);
}
}

return code_buffer;
}

10 changes: 10 additions & 0 deletions interactive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// interative.h

#include <stdio.h>

#define CELL_COUNT 30000
#define START_BUFFER_SIZE 2048

char* read_code();
void run_code(char* code, int code_len);
void start_interactive();
98 changes: 98 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "interactive.h"

int main(int argc, char* argv[])
{
if (argc < 2) {
start_interactive();
exit(EXIT_SUCCESS);
}

char* input = argv[1];
FILE* input_file = fopen(input, "r");

if (!input_file) {
fprintf(stderr, "Error: File \"%s\" doesn't exist\n", input);
exit(EXIT_FAILURE);
}

// Get size of file
fseek(input_file, 0L, SEEK_END);
int code_len = ftell(input_file);
fseek(input_file, 0L, SEEK_SET);

char* code_buffer = malloc(code_len);

fread(code_buffer, sizeof(char), code_len, input_file);
fclose(input_file);

run_code(code_buffer, code_len);

free(code_buffer);
return 0;
}

void run_code(char* code, int code_len)
{
// Create cell array and set every cell to 0
char cells[CELL_COUNT];
memset(cells, 0, sizeof(cells));

int cell_i = 0; // current cell index
int b = 0; // bracket counter

// Start interpreting code
for (int i = 0; i < code_len; i++) {
switch (code[i]) {
case '>': cell_i++; break;
case '<': cell_i--; break;
case '+': cells[cell_i]++; break;
case '-': cells[cell_i]--; break;
case '.': putchar(cells[cell_i]); break;
case ',':
cells[cell_i] = getchar();
getchar(); // remove '\n' from stdin
break;
case '[':
if (cells[cell_i] != 0) continue;
b++;

while (b > 0) {
switch (code[i]) {
case '[': b++; break;
case ']': b--; break;
}

// In case if matching brace wasnt found and we
// got past the code_len
if (++i > code_len) {
break;
}
}
break;
case ']':
if (cells[cell_i] == 0) continue;
b++;

while (b > 0) {
switch (code[i]) {
case ']': b++; break;
case '[': b--; break;
}

if (--i < 0) {
break;
}
}
break;
default:
break;
}
}
}

0 comments on commit 79bb542

Please sign in to comment.