Skip to content

Instantly share code, notes, and snippets.

@smvd
Last active May 25, 2021 08:26
Show Gist options
  • Save smvd/0da12353c63b2cb3f68de08368103714 to your computer and use it in GitHub Desktop.
Save smvd/0da12353c63b2cb3f68de08368103714 to your computer and use it in GitHub Desktop.
A brainfuck implementation
/*
> : Move the pointer forward 1 slot
< : Move the pointer back 1 slot
+ : Add 1 to the current memory slot
- : Subtract 1 from the current memory slot
. : Print the ASCII character in the current memory slot
? : Print the number stored in the current memory slot
, : Save the ASCII character taken from the keyboard in the current memory slot
[ : Test if the current slot is not 0, otherwise enter the loop
] : Test if the current slot is 0, otherwise exit the loop
~ : End the program
*/
/*
Github: https://gist.github.com/smvd/0da12353c63b2cb3f68de08368103714
Licens: www.unlicense.org
Youtube: www.rebrand.ly/eclips-coding
Build command: gcc main.c -o ECBF.exe -Wall -Werror -W -s
*/
#include <stdio.h> // IO header (STANDARD)
#include <string.h> // String header (STANDARD)
#include <stdlib.h>
#include <conio.h> // Special IO header (MINGW)
#define MEM_SIZE 30000 // Set the memory size to 30000 (the official specification)
#define CODE_SIZE 10000 // Set the code size to 10000 (just what i found complete overkill)
#define TRUE 1 // Set true to 1 (wich c handles as true)
#define FALSE 0 // Set false to 0 (wich c handles as false)
int mem[3000] = {0}; // Make the memory as all 0
int *ptr = &mem[0]; // Make a reference to the memorys first slot
char code[CODE_SIZE]; // Make the code storage
char *c = &code[0]; // Make a reference to the code
char *lastBracket = &code[0]; // Make a reference to the code to hold the location of the last occurance of [
char *temp = &code[0]; // Make a reference to the code to be used for temporary pointing
void ExecuteCode() // Function to run the loaded code
{
while (TRUE) // Loop untill told to stop
{
if (*c == '\0') // End of code
{
break; // Leave loop
}
if (*c == '~') // Exit character
{
break; // Leave loop
}
if (*c == '#') // Debug character
{
printf("<DEBUG>\n");
for (int i = 0; i < MEM_SIZE; i++) // Loop over each slot in memory
{
if (mem[i] != 0)
{
printf(" [ %d : %d ]\n", i, mem[i]);
}
}
printf("</DEBUG>\n");
}
if (*c == '>') // Forwards character
{
ptr++; // Shift the pointer forward 1 slot
}
if (*c == '<') // Backwards character
{
ptr--; // Shift the pointer back 1 slot
}
if (*c == '+') // Addition character
{
++*ptr;
if (*ptr == 256)
{
*ptr = 0;
}
}
if (*c == '-') // Subtraction character
{
--*ptr;
if (*ptr == -1)
{
*ptr = 255;
}
}
if (*c == '.') // Print character
{
putchar(*ptr); // Treat the int as raw ASCII and throw it at the screen
}
if (*c == '?') // Print number
{
printf("%d", *ptr);
}
if (*c == ',') // Read character
{
*ptr = getch(); // This is not here to stay as its using a old MS-DOS header
}
if (*c == '[') // Start loop
{
if (*ptr == 0)
{
temp = c +1; // Copy the next characters reference to temp
int brackets = 0; // Make a variable to hold the layers of depth
while (TRUE) // Loop untill broken
{
if (*temp == '[') // If the character is [
{
brackets++;
}
if (*temp == ']' && brackets == 0) // If the character is ] and we have 0 layers of depth
{
c = temp +1; // Copy the location of temp to be the main location
break; // Leave the loop
}
if (*temp == ']') // If the character is ]
{
brackets--;
}
temp++; // Move the temp pointer forward
}
}
lastBracket = c; // Store the location of the last bracket
}
if (*c == ']') // End loop
{
if (*ptr != 0) // If the current slot isnt 0
{
c = lastBracket; // Jump to the last bracket
}
}
c++; // Move the code pointer forward
}
}
void ImportCode(char file[]) // Function to read the code from a given file
{
FILE *fp; // Reference to the file
char ch; // The currently read character
int i = CODE_SIZE; // The maximum ammount of code to read
fp = fopen(file, "r"); // Read the file
if (fp == NULL) // If the read failed
{
printf("%s does not exist.\n", file);
exit(1); // Exit the program with an error code
}
while ((ch = fgetc(fp)) != EOF) // Loop over each character untill the end of the file
{
if (i == 0) // If we are going to have a buffer overflow (why its important: https://www.youtube.com/watch?v=1S0aBV-Waeo )
{
printf("%s is too large.\n", file);
exit(1); // Exit the program with an error code
}
if(strchr("><+-.?,~[]#", ch)) // If its a valid character
{
code[strlen(code)] = ch; // Add the character to the code
code[strlen(code)] = '\0'; // Add the end of string character
i++; // Add 1 to the buffer overflow test variable
}
}
printf("%s\n", code); // Write the code out
fclose(fp); // Untie the file pointer (why its important: https://www.youtube.com/watch?v=6SA6S9Ca5-U )
}
int main(int argc, char ** argv) // Main entry point
{
if (argc != 2) // If there are too little arguments
{
printf("Invalid arguments.\n");
exit(1); // Exit with an error code
}
ImportCode(argv[1]); // Read the file
ExecuteCode(); // Execute the code
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment