Initial Commit
This commit is contained in:
28
src/file.c
Normal file
28
src/file.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "file.h"
|
||||
|
||||
char* read_file(char* filename) {
|
||||
FILE* fptr = fopen(filename, "r");
|
||||
if (fptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get length
|
||||
fseek(fptr, 0L, SEEK_END);
|
||||
long file_size = ftell(fptr);
|
||||
rewind(fptr);
|
||||
|
||||
// Allocate buffer
|
||||
char* buffer = malloc(file_size+1);
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read file
|
||||
size_t read = fread(buffer, sizeof(char), file_size, fptr);
|
||||
if (read != file_size) return NULL;
|
||||
|
||||
buffer[file_size] = '\0';
|
||||
fclose(fptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
4
src/file.h
Normal file
4
src/file.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char* read_file(char* filename);
|
||||
99
src/main.c
Normal file
99
src/main.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "struct.h"
|
||||
#include "file.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <filename> <input>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* code = read_file(argv[1]);
|
||||
if (code == NULL) {
|
||||
fprintf(stderr, "Cannot open file \"%s\"\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
char* input = argv[2];
|
||||
int inputidx = 0;
|
||||
|
||||
Celltape cells = {
|
||||
.cells = calloc(30000, sizeof(bitarr)),
|
||||
.ptr = 0
|
||||
};
|
||||
|
||||
int scope = 0;
|
||||
int max_scope = 0; // Highest ever reached scope
|
||||
int* loop_start = malloc(0);
|
||||
|
||||
PartialByte to_print = {
|
||||
.data = 0,
|
||||
.idx = 0
|
||||
};
|
||||
|
||||
bool ignore = false;
|
||||
|
||||
for (int idx = 0; code[idx] != '\0'; idx++) {
|
||||
if (ignore) {
|
||||
if (code[idx] == ']') {
|
||||
ignore = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
switch (code[idx]) {
|
||||
case '+':
|
||||
case '-':
|
||||
flip_bit(&(cells.cells), cells.ptr);
|
||||
break;
|
||||
|
||||
case '>':
|
||||
cells.ptr += 1;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
cells.ptr -= 1;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
if (!get_bit(cells.cells, cells.ptr)) {
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
scope += 1;
|
||||
if (scope > max_scope) {
|
||||
max_scope += scope;
|
||||
loop_start = realloc(loop_start, scope);
|
||||
}
|
||||
loop_start[scope-1] = idx;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (get_bit(cells.cells, cells.ptr)) {
|
||||
idx = loop_start[scope-1];
|
||||
} else {
|
||||
scope -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '.':
|
||||
case ';':
|
||||
append_bit(&to_print, get_bit(cells.cells, cells.ptr));
|
||||
if (to_print.idx == 8) {
|
||||
to_print.idx = 0;
|
||||
printf("%c", to_print.data);
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if ((input[inputidx/8] & (1 << (inputidx % 8))) >> (inputidx % 8)) {
|
||||
one_bit(&cells.cells, cells.ptr);
|
||||
} else {
|
||||
zero_bit(&cells.cells, cells.ptr);
|
||||
}
|
||||
inputidx += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/struct.c
Normal file
22
src/struct.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "struct.h"
|
||||
|
||||
void flip_bit(bitarr** cells, int idx) {
|
||||
(*cells)[idx / 8] ^= (bitarr)(0x80 >> (idx % 8));
|
||||
}
|
||||
|
||||
int get_bit(bitarr* cells, int ptr) {
|
||||
return ((cells[ptr/8]) & (128 >> (ptr % 8))) >> 7;
|
||||
}
|
||||
|
||||
void append_bit(PartialByte* byte, int bit) {
|
||||
(*byte).data |= bit << ((*byte).idx);
|
||||
(*byte).idx += 1;
|
||||
}
|
||||
|
||||
void zero_bit(bitarr** cells, int idx) {
|
||||
(*cells)[idx / 8] &= 255 ^ (128 >> idx);
|
||||
}
|
||||
|
||||
void one_bit(bitarr** cells, int idx) {
|
||||
(*cells)[idx / 8] |= (128 >> idx);
|
||||
}
|
||||
19
src/struct.h
Normal file
19
src/struct.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#define bitarr unsigned char
|
||||
#define u64 uint64_t
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
bitarr data;
|
||||
bitarr idx;
|
||||
} PartialByte;
|
||||
|
||||
typedef struct {
|
||||
bitarr* cells;
|
||||
int ptr;
|
||||
} Celltape;
|
||||
|
||||
void flip_bit(bitarr** cells, int idx);
|
||||
int get_bit(bitarr* cells, int ptr);
|
||||
void append_bit(PartialByte* byte, int bit);
|
||||
void zero_bit(bitarr** cells, int idx);
|
||||
void one_bit(bitarr** cells, int idx);
|
||||
1
tests/aaaaaa.bf
Normal file
1
tests/aaaaaa.bf
Normal file
@@ -0,0 +1 @@
|
||||
+>+>+>+>+>+>+>+<<<<<<<,;,;,;,;,;,;,;,;
|
||||
Reference in New Issue
Block a user