4Head/AuthorImplementation.c

:
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define cell int16_t
#define MEM_X 100
#define MEM_Y 100
void print_2d_array(cell *array, size_t width, size_t height, size_t x, size_t y) {
 for (size_t yi = 0; yi < height; ++yi) {
 for (size_t xi = 0; xi < width; ++xi) {
 size_t i = width*yi + xi;
 if (x == xi && y == yi) {
 printf(">%2d<", array[i]);
 }
 else {
 printf(" %2d ", array[i]);
 }
 }
 printf("\n");
 }
}
void interpret_program(const char *program, size_t program_length, int enable_debug) {
 const size_t width = MEM_X, height = MEM_Y;
 cell memory[MEM_Y][MEM_X] = {0};
 size_t x = 0, y = 0;
 size_t amount = 1;
 cell hold = 0;
 size_t i = 0;
 while (i < program_length) {
#if 0
 printf("i=%3lld,x=%2lld,y=%2lld\n", i, x, y);
#endif
 switch(program[i]) {
 case '+':
 // Increment
 hold += amount;
 amount = 1;
 i++;
 break;
 case '-':
 // Decrement
 hold -= amount;
 amount = 1;
 i++;
 break;
 case '<':
 // Move left
 if (amount >= x) {
 x = 0;
 }
 else {
 x -= amount;
 }
 amount = 1;
 i++;
 break;
 case '>':
 // Move right
 if (x + amount > width-1) {
 x = width-1;
 }
 else {
 x += amount;
 }
 amount = 1;
 i++;
 break;
 case '^':
 // Move up
 if (amount >= y) {
 y = 0;
 }
 else {
 y -= amount;
 }
 amount = 1;
 i++;
 break;
 case 'v':
 // Move down
 if (y + amount > height-1) {
 y = height-1;
 }
 else {
 y += amount;
 }
 amount = 1;
 i++;
 break;
 case '@':
 // Fetch
 hold = memory[y][x];
 amount = 1;
 i++;
 break;
 case '!':
 // Store
 memory[y][x] = hold;
 amount = 1;
 i++;
 break;
 case '%':
 // Swap
 {
 cell t = memory[y][x];
 memory[y][x] = hold;
 hold = t;
 amount = 1;
 i++;
 }
 break;
 case '[':
 // Jump past matching bracket if current cell is 0
 if (hold == 0) {
 int level = 1;
 int original_i = i;
 // inefficient while loop to find the matching bracket
 while (level != 0 && i < program_length) {
 i++;
 if (program[i] == '[') {
 level++;
 }
 else if (program[i] == ']') {
 level--;
 }
 }
 if (level != 0) {
 printf("ERROR: unmatched opening bracket '[' at index %d", original_i);
 exit(1);
 }
 }
 i++;
 amount = 1;
 break;
 case ']':
 // Jump back to the matching bracket if current cell is not 0
 if (hold != 0) {
 int level = 1;
 int original_i = i;
 // inefficient while loop to find the matching bracket
 while (level != 0 && i < program_length) {
 i--;
 if (program[i] == ']') {
 level++;
 }
 else if (program[i] == '[') {
 level--;
 }
 }
 if (level != 0) {
 printf("ERROR: unmatched opening bracket ']' at index %d", original_i);
 exit(1);
 }
 }
 i++;
 amount = 1;
 break;
 case '?':
 // Get a character of input
 hold = getchar();
 i++;
 amount = 1;
 break;
 case '.':
 // Set a character of output
 putchar(hold);
 i++;
 amount = 1;
 break;
 case '#':
 // Debugger
 if (enable_debug) {
 printf("\n");
 print_2d_array((cell*) memory, width, height, x, y);
 amount = 1;
 }
 i++;
 break;
 default:
 // Try to read a number and ignore any other characters
 if (isdigit(program[i])) {
 // Start of a number, so set the amount to it
 size_t n = 0;
 while (isdigit(program[i])) {
 n = (n*10) + (program[i] - '0');
 i++;
 }
 if (n) {
 amount = n;
 }
 } else {
 // Ignore non-number
 i++;
 }
 break;
 }
 }
}
Category:Implementations