#include "types.h" #include #include #include #include static char next_char(FILE* file) { char c; if (fread(&c, 1, 1, file) != 1) { return EOF; } else { return c; } } static Symbol next_symbol(FILE* file) { char c = next_char(file); 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(file), c == '\n' || c == '\t' || c == ' '); goto retest; case '/': while(c = next_char(file), c != '\n' && c != EOF); goto retest; case EOF: return Eof; default: c = next_char(file); goto retest; } } void program_init(Program* program, FILE* file) { uint32_t capacity = 8; program->data = malloc(capacity * sizeof(struct instruction)); program->len = 0; program->index = 0; Stack stack; stack_init(&stack, 8); Symbol s; while(true) { s = next_symbol(file); if (program->len == capacity) { capacity *= 2; program->data = realloc(program->data, capacity * sizeof(struct instruction)); } program->data[program->len].s = s; program->data[program->len].j = 0; if (s == StartLoop) { stack_pushi(&stack, program->len); } else if (s == EndLoop) { uint32_t i = stack_popi(&stack); program->data[program->len].j = i; if (i != 0 || program->data[i].j == 0) { program->data[i].j = program->len; } } program->len++; if (s == Eof) break; } stack_free(&stack); fclose(file); } void program_get(Program* program, Symbol* symbol) { if (program->index >= program->len) { *symbol = Eof; return; } *symbol = program->data[program->index].s; } uint32_t program_get_jump(Program* program) { if (program->index >= program->len) { return 0; } return program->data[program->index].j; } void program_next(Program* program) { program->index++; } void program_seek(Program* program, uint32_t index) { program->index = index; } void program_free(Program* program) { free(program->data); }