Skip to main content
deleted 116 characters in body
Source Link

My goal was to keep it as simple and short as possible.I have yet to implement some sort of error handling for unmatched brackets in the source but can't figure out how.

My goal was to keep it as simple and short as possible.I have yet to implement some sort of error handling for unmatched brackets in the source but can't figure out how.

My goal was to keep it as simple and short as possible.

added 25 characters in body
Source Link
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#define MIN_MEMORY_SIZE 30000

typedef struct
{
    uint8_t *memory;
    size_t pointer;
} BrainfuckState;

static void init(BrainfuckState *bf, size_t size)
{
    assert(size <= MIN_MEMORY_SIZE);
    bf->memory = calloc(size, 1);
    assert(!(bf == NULL));
    bf->pointer = 0;
}

static void deinit(BrainfuckState *bf)
{
    free(bf->memory);
    bf->pointer = 0;
}

static void interpret(BrainfuckState *bf, const char* source, size_t sourceSize)
{
    size_t unmatchedBracketCount = 0;

    for (size_t i = 0; i < sourceSize; i++)
    {
        switch (source[i])
        {
            case '.':
                printf("%c", bf->memory[bf->pointer]);
                break;

            case ',':
                scanf("%c", &(bf->memory[bf->pointer]));
                break;

            case '+':
                bf->memory[bf->pointer]++;
                break;

            case '-':
                bf->memory[bf->pointer]--;
                break;

            case '>':
                bf->pointer++;
                break;

            case '<':
                bf->pointer--;
                break;

            case '[':
                if (bf->memory[bf->pointer] == 0)
                {
                    unmatchedBracketCount++;
                    while (source[i] != ']' || unmatchedBracketCount)
                    {
                        i++;
                        
                        if (source[i] == '[')
                            unmatchedBracketCount++;
                        else if (source[i] == ']')
                            unmatchedBracketCount--;
                    }
                }
                break;

            case ']':
                if (bf->memory[bf->pointer])
                {
                    unmatchedBracketCount++;
                    while (source[i] != '[' || unmatchedBracketCount)
                    {
                        i--;
                        
                        if (source[i] == ']')
                            unmatchedBracketCount++;
                        else if (source[i] == '[')
                            unmatchedBracketCount--;
                    }
                }
                break;
        }

    }
}

int main(int argc, char** argv)
{
    if (argc < 2)
        fprintf(stderr, "Pass a filename as a command line arguement.\n");
    else
    {
        FILE *fp = fopen(argv[1], "r");
        assert(fp);

        fseek(fp, 0, SEEK_END);
        size_t sourceSize = ftell(fp);
        char *source = malloc(sourceSize);
        assert(source);
        rewind(fp);
    
        for (size_t i = 0; i < sourceSize; i++)
            source[i] = fgetc(fp);

        fclose(fp);

        BrainfuckState bf;
        init(&bf, MIN_MEMORY_SIZE);
        interpret(&bf, source, sourceSize);
        deinit(&bf);

        free(source);
    }

    return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#define MIN_MEMORY_SIZE 30000

typedef struct
{
    uint8_t *memory;
    size_t pointer;
} BrainfuckState;

static void init(BrainfuckState *bf, size_t size)
{
    assert(size <= MIN_MEMORY_SIZE);
    bf->memory = calloc(size, 1);
    assert(!(bf == NULL));
    bf->pointer = 0;
}

static void deinit(BrainfuckState *bf)
{
    free(bf->memory);
    bf->pointer = 0;
}

static void interpret(BrainfuckState *bf, const char* source, size_t sourceSize)
{
    size_t unmatchedBracketCount = 0;

    for (size_t i = 0; i < sourceSize; i++)
    {
        switch (source[i])
        {
            case '.':
                printf("%c", bf->memory[bf->pointer]);
                break;

            case ',':
                scanf("%c", &(bf->memory[bf->pointer]));
                break;

            case '+':
                bf->memory[bf->pointer]++;
                break;

            case '-':
                bf->memory[bf->pointer]--;
                break;

            case '>':
                bf->pointer++;
                break;

            case '<':
                bf->pointer--;
                break;

            case '[':
                if (bf->memory[bf->pointer] == 0)
                {
                    unmatchedBracketCount++;
                    while (source[i] != ']' || unmatchedBracketCount)
                    {
                        i++;
                        
                        if (source[i] == '[')
                            unmatchedBracketCount++;
                        else if (source[i] == ']')
                            unmatchedBracketCount--;
                    }
                }
                break;

            case ']':
                if (bf->memory[bf->pointer])
                {
                    unmatchedBracketCount++;
                    while (source[i] != '[' || unmatchedBracketCount)
                    {
                        i--;
                        
                        if (source[i] == ']')
                            unmatchedBracketCount++;
                        else if (source[i] == '[')
                            unmatchedBracketCount--;
                    }
                }
                break;
        }

    }
}

int main(int argc, char** argv)
{
    if (argc < 2)
        fprintf(stderr, "Pass a filename as a command line arguement.\n");
    else
    {
        FILE *fp = fopen(argv[1], "r");
        assert(fp);

        fseek(fp, 0, SEEK_END);
        size_t sourceSize = ftell(fp);
        char *source = malloc(sourceSize);
        rewind(fp);
    
        for (size_t i = 0; i < sourceSize; i++)
            source[i] = fgetc(fp);

        fclose(fp);

        BrainfuckState bf;
        init(&bf, MIN_MEMORY_SIZE);
        interpret(&bf, source, sourceSize);
        deinit(&bf);

        free(source);
    }

    return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#define MIN_MEMORY_SIZE 30000

typedef struct
{
    uint8_t *memory;
    size_t pointer;
} BrainfuckState;

static void init(BrainfuckState *bf, size_t size)
{
    assert(size <= MIN_MEMORY_SIZE);
    bf->memory = calloc(size, 1);
    assert(!(bf == NULL));
    bf->pointer = 0;
}

static void deinit(BrainfuckState *bf)
{
    free(bf->memory);
    bf->pointer = 0;
}

static void interpret(BrainfuckState *bf, const char* source, size_t sourceSize)
{
    size_t unmatchedBracketCount = 0;

    for (size_t i = 0; i < sourceSize; i++)
    {
        switch (source[i])
        {
            case '.':
                printf("%c", bf->memory[bf->pointer]);
                break;

            case ',':
                scanf("%c", &(bf->memory[bf->pointer]));
                break;

            case '+':
                bf->memory[bf->pointer]++;
                break;

            case '-':
                bf->memory[bf->pointer]--;
                break;

            case '>':
                bf->pointer++;
                break;

            case '<':
                bf->pointer--;
                break;

            case '[':
                if (bf->memory[bf->pointer] == 0)
                {
                    unmatchedBracketCount++;
                    while (source[i] != ']' || unmatchedBracketCount)
                    {
                        i++;
                        
                        if (source[i] == '[')
                            unmatchedBracketCount++;
                        else if (source[i] == ']')
                            unmatchedBracketCount--;
                    }
                }
                break;

            case ']':
                if (bf->memory[bf->pointer])
                {
                    unmatchedBracketCount++;
                    while (source[i] != '[' || unmatchedBracketCount)
                    {
                        i--;
                        
                        if (source[i] == ']')
                            unmatchedBracketCount++;
                        else if (source[i] == '[')
                            unmatchedBracketCount--;
                    }
                }
                break;
        }

    }
}

int main(int argc, char** argv)
{
    if (argc < 2)
        fprintf(stderr, "Pass a filename as a command line arguement.\n");
    else
    {
        FILE *fp = fopen(argv[1], "r");
        assert(fp);

        fseek(fp, 0, SEEK_END);
        size_t sourceSize = ftell(fp);
        char *source = malloc(sourceSize);
        assert(source);
        rewind(fp);
    
        for (size_t i = 0; i < sourceSize; i++)
            source[i] = fgetc(fp);

        fclose(fp);

        BrainfuckState bf;
        init(&bf, MIN_MEMORY_SIZE);
        interpret(&bf, source, sourceSize);
        deinit(&bf);

        free(source);
    }

    return EXIT_SUCCESS;
}
Source Link

Simple Brainfuck interpreter in C with support for nested subroutines

Wrote a simple brainfuck interpreter that supports nested subroutines ([ ] commands).

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#define MIN_MEMORY_SIZE 30000

typedef struct
{
    uint8_t *memory;
    size_t pointer;
} BrainfuckState;

static void init(BrainfuckState *bf, size_t size)
{
    assert(size <= MIN_MEMORY_SIZE);
    bf->memory = calloc(size, 1);
    assert(!(bf == NULL));
    bf->pointer = 0;
}

static void deinit(BrainfuckState *bf)
{
    free(bf->memory);
    bf->pointer = 0;
}

static void interpret(BrainfuckState *bf, const char* source, size_t sourceSize)
{
    size_t unmatchedBracketCount = 0;

    for (size_t i = 0; i < sourceSize; i++)
    {
        switch (source[i])
        {
            case '.':
                printf("%c", bf->memory[bf->pointer]);
                break;

            case ',':
                scanf("%c", &(bf->memory[bf->pointer]));
                break;

            case '+':
                bf->memory[bf->pointer]++;
                break;

            case '-':
                bf->memory[bf->pointer]--;
                break;

            case '>':
                bf->pointer++;
                break;

            case '<':
                bf->pointer--;
                break;

            case '[':
                if (bf->memory[bf->pointer] == 0)
                {
                    unmatchedBracketCount++;
                    while (source[i] != ']' || unmatchedBracketCount)
                    {
                        i++;
                        
                        if (source[i] == '[')
                            unmatchedBracketCount++;
                        else if (source[i] == ']')
                            unmatchedBracketCount--;
                    }
                }
                break;

            case ']':
                if (bf->memory[bf->pointer])
                {
                    unmatchedBracketCount++;
                    while (source[i] != '[' || unmatchedBracketCount)
                    {
                        i--;
                        
                        if (source[i] == ']')
                            unmatchedBracketCount++;
                        else if (source[i] == '[')
                            unmatchedBracketCount--;
                    }
                }
                break;
        }

    }
}

int main(int argc, char** argv)
{
    if (argc < 2)
        fprintf(stderr, "Pass a filename as a command line arguement.\n");
    else
    {
        FILE *fp = fopen(argv[1], "r");
        assert(fp);

        fseek(fp, 0, SEEK_END);
        size_t sourceSize = ftell(fp);
        char *source = malloc(sourceSize);
        rewind(fp);
    
        for (size_t i = 0; i < sourceSize; i++)
            source[i] = fgetc(fp);

        fclose(fp);

        BrainfuckState bf;
        init(&bf, MIN_MEMORY_SIZE);
        interpret(&bf, source, sourceSize);
        deinit(&bf);

        free(source);
    }

    return EXIT_SUCCESS;
}

My goal was to keep it as simple and short as possible.I have yet to implement some sort of error handling for unmatched brackets in the source but can't figure out how.