Last active
July 29, 2020 14:17
-
-
Save mustooch/e09bf3960f55eae102a95871032b460b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define MEM_MAX 2024 | |
#define PROG_MAX 16384 | |
#define NAME_MAX 256 | |
void getprog(char *prg, char fname[NAME_MAX]) { | |
FILE *fp; | |
fp = fopen(fname, "r"); | |
if (fp == NULL) { | |
printf("Couldn't open file %s", fname); | |
exit(1); | |
} | |
char c; | |
int i = 0; | |
while ( (c = fgetc(fp)) != EOF ) { | |
if (c == '+' || c == '-' || c == '<' || c == '>' || c == '[' || c == ']' || c == '.' || c == ',') { | |
*(prg+i) = c; | |
i++; | |
} | |
} | |
fclose(fp); | |
} | |
void printarr(int *arr, int len) { | |
printf("\n"); | |
for (int i = 0; i < len; i++) { | |
printf("%d, ", *(arr+i)); | |
} | |
printf("\n"); | |
} | |
void eval(char **inst, int **cell) { | |
switch (**inst) { | |
case '+': { | |
(**cell)++; | |
} break; | |
case '-': { | |
(**cell)--; | |
} break; | |
case '>': { | |
(*cell)++; | |
} break; | |
case '<': { | |
(*cell)--; | |
} break; | |
case '.': { | |
printf("%c", **cell); | |
} break; | |
case ',': { | |
printf(","); | |
} break; | |
case '[': { | |
if (**cell == 0) { | |
int open = 0; | |
for (int i = 1; i < PROG_MAX; i++) { | |
if ( (*(*inst+i)) == '[' ) { | |
open++; | |
} else if ( (*(*inst+i)) == ']' ) { | |
open--; | |
if (open == -1) { | |
(*inst) += (i); | |
break; | |
} | |
} | |
} | |
} | |
} break; | |
case ']': { | |
if (**cell != 0) { | |
int closed = 0; | |
for (int i = 1; i < PROG_MAX; i++) { | |
if ( (*(*inst-i)) == ']' ) { | |
closed++; | |
} else if ( (*(*inst-i)) == '[' ) { | |
closed--; | |
if (closed == -1) { | |
(*inst) -= (i); | |
break; | |
} | |
} | |
} | |
} | |
} break; | |
default: break; | |
} | |
} | |
int main(int argc, char *argv[]) { | |
if (argc < 2) { | |
printf("Please specify the file to run\n"); | |
printf("./brainfuck FILENAME..."); | |
exit(1); | |
} | |
int mem[MEM_MAX] = {0}; | |
char prog[PROG_MAX]; | |
if ( strcmp(argv[1], "-i") == 0) { | |
memset(prog, '\0', sizeof(prog)); | |
strcpy(prog, argv[2]); | |
} else { | |
getprog(prog, argv[1]); | |
} | |
char *ip = prog; /* instruction pointer */ | |
int *mp = mem; /* memory pointer */ | |
for (;;) { | |
eval(&ip, &mp); | |
// printarr(mem, 10); | |
if ( *(++ip) == '\0') break; | |
} | |
// printarr(mem, 10); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment