#include "interpreter.h" #include "program.h" #include #include #include #include #include static void loop_end(Program* program) { uint32_t count = 1; Symbol s; while (true) { program_next(program, &s); if (s == StartLoop) { count++; } else if (s == EndLoop) { count--; } else if (s == Eof) { return; } if (count == 0) return; } } static void loop_start(Program* program) { uint32_t count = 1; Symbol s; program_last(program, &s); while (true) { program_last(program, &s); if (s == StartLoop) { count--; } else if (s == EndLoop) { count++; } else if (s == Eof) { return; } if (count == 0) { return; }; } } static void recurse_program(Program* program, Tape* tape) { Symbol s; next: program_next(program, &s); // printf("["); // for(uint32_t i = 0; i < tape->len; i++) { // printf("0x%02x ", tape->data[i]); // } // printf("\b]\n "); // for(uint32_t i = 0; i < tape->len; i++) { // if (i == tape->index) { // printf(" ^ "); // } else { // printf(" "); // } // } // printf(" \ + tape->indexn"); switch (s) { case MoveLeft: tape_left(tape); break; case MoveRight: tape_right(tape); break; case Increment: tape_set(tape, tape_get(tape) + 1); break; case Decrement: tape_set(tape, tape_get(tape) - 1); break; case StartLoop: if (tape_get(tape) == 0) loop_end(program); break; case EndLoop: if (tape_get(tape) != 0) loop_start(program); break; case PutChar: { printf("%c", tape_get(tape)); break; } case GetChar: { uint8_t c = (uint8_t) getchar(); tape_set(tape, c); break; } case Allocate: { uint8_t len = tape_get(tape); Tape* new = malloc(sizeof(Tape)); tape_init(len, new); void* ptr = (void*) tape_ptr(tape); memcpy(ptr, &new, sizeof(Tape*)); break; } case Free: { Tape* old; void* ptr = (void*) tape_ptr(tape); memcpy(&old, ptr, sizeof(Tape*)); memset(ptr, 0, sizeof(Tape*)); tape_free(tape); free(old); break; } case EnterTape: { Tape* cur; void* ptr = (void*) tape_ptr(tape); memcpy(&cur, ptr, sizeof(Tape*)); recurse_program(program, cur); break; } case GetString: { uint8_t len = tape_get(tape); void* ptr = (void*) tape_ptr(tape); fgets(ptr, len, stdin); break; } case PutString: { char* ptr = (char*) tape_ptr(tape); printf("%s", ptr); break; } case Clear: printf("\033c"); break; case LeaveTape: case Eof: return; } goto next; } void run_program(Program* program) { Tape tape; tape_init(sizeof(void*), &tape); recurse_program(program, &tape); tape_free(&tape); }