#include "program.h" #include #include #include #include #include static FILE* f; static uint32_t count; static char next_char() { char c; if (fread(&c, 1, 1, f) != 1) { return EOF; } else { count++; return c; } } static Symbol next_symbol() { char c = next_char(); retest: switch (c) { case '<': return MoveLeft; case '>': return MoveRight; case '+': return Increment; case '-': return Decrement; case '[': return StartLoop; case ']': return EndLoop; case '.': return PutChar; case ',': return GetChar; case '*': return Allocate; case '!': return Free; case '(': return EnterTape; case ')': return LeaveTape; case '`': return PutString; case '~': return GetString; case '%': return Clear; case '\n': case '\t': case ' ': while(c = next_char(), c == '\n' || c == '\t' || c == ' '); goto retest; case '/': while(c = next_char(), c != '\n' && c != EOF); goto retest; case EOF: return Eof; default: c = next_char(); goto retest; } } void program_init(char* file_path, Program* program) { f = fopen (file_path, "r"); if (f == NULL) { printf("error: failed to open %s (%s)\n", file_path, strerror(errno)); exit(EXIT_FAILURE); } uint32_t capacity = 8; count = 0; program->data = malloc(capacity * sizeof(Symbol)); program->len = 0; program->index = 0; Symbol s; while(true) { s = next_symbol(); if (program->len == capacity) { capacity *= 2; program->data = realloc(program->data, capacity * sizeof(Symbol)); } program->data[program->len] = s; program->len++; if (s == Eof) break; } fclose(f); } void program_peek(Program* program, Symbol* symbol) { *symbol = program->data[program->index]; } void program_next(Program* program, Symbol* symbol) { if (program->index >= program->len) { *symbol = Eof; return; } program_peek(program, symbol); program->index++; } void program_last(Program* program, Symbol* symbol) { if (program->index < 1) { *symbol = Eof; return; } program->index--; program_peek(program, symbol); } void program_free(Program* program) { free(program->data); } void tape_init(uint32_t len, Tape* tape) { tape->len = len; tape->data = malloc(len); tape->index = 0; memset(tape->data, 0, len); } void tape_left(Tape* tape) { if (tape->index == 0) { tape->index = tape->len - 1; } else { tape->index--; } } void tape_right(Tape* tape) { tape->index++; tape->index %= tape->len; } uint8_t tape_get(Tape* tape) { return tape->data[tape->index]; } void tape_set(Tape* tape, uint8_t value) { tape->data[tape->index] = value; } uint8_t* tape_ptr(Tape* tape) { return tape->data + tape->index; } void tape_free(Tape* tape) { free(tape->data); }