Example #1
0
/*
 * Run the given brainfuck string.
 *
 * @param code The brainfuck string to run.
 * @return EXIT_SUCCESS if no errors are encountered, otherwise EXIT_FAILURE.
 */
int run_string(char *code) {
	BrainfuckState *state = brainfuck_state();
	BrainfuckExecutionContext *context = brainfuck_context(BRAINFUCK_TAPE_SIZE);
	BrainfuckInstruction *instruction = brainfuck_parse_string(code);
 	brainfuck_add(state, instruction);
 	brainfuck_execute(state->root, context);
	brainfuck_destroy_context(context);
 	brainfuck_destroy_state(state);
 	return EXIT_SUCCESS;
}
Example #2
0
/*
 * Run the brainfuck interpreter in interactive mode.
 */
void run_interactive_console() {
	printf("brainfuck %s (%s, %s)\n", BRAINFUCK_VERSION, __DATE__, __TIME__);
	BrainfuckState *state = brainfuck_state();
	BrainfuckExecutionContext *context = brainfuck_context(BRAINFUCK_TAPE_SIZE);
	BrainfuckInstruction *instruction;
	
	printf(">> ");
	while(1) {
		fflush(stdout);
		instruction = brainfuck_parse_stream_until(stdin, '\n');
		brainfuck_add(state, instruction);
		brainfuck_execute(instruction, context);
		printf("\n>> ");
	}
}
Example #3
0
/*
 * Runs the given brainfuck file.
 *
 * @param file The brainfuck file to run.
 * @return EXIT_SUCCESS if no errors are encountered, otherwise EXIT_FAILURE.
 */
int run_file(FILE *file) {
	BrainfuckState *state = brainfuck_state();
	BrainfuckExecutionContext *context = brainfuck_context(BRAINFUCK_TAPE_SIZE);
	if (file == NULL) {
		brainfuck_destroy_context(context);
		brainfuck_destroy_state(state);
		return EXIT_FAILURE;
	}
	brainfuck_add(state, brainfuck_parse_stream(file));
	brainfuck_execute(state->root, context);
	brainfuck_destroy_context(context);
	brainfuck_destroy_state(state);
	fclose(file);
	return EXIT_SUCCESS;
}
Example #4
0
/**
 * Executes the given linked list containing instructions.
 *
 * @param root The start of the linked list of instructions you want
 * 	to execute.
 * @param context The context of this execution that contains the tape and
 *	other execution related variables.
 */
void brainfuck_execute(BrainfuckInstruction *root, BrainfuckExecutionContext *context) {
	if (root == NULL || context == NULL)
		return;
	BrainfuckInstruction *instruction = root;
	int index;
	while (instruction != NULL && instruction->type != BRAINFUCK_TOKEN_LOOP_END) {
		switch (instruction->type) {
		case BRAINFUCK_TOKEN_PLUS:
			context->tape[context->tape_index] += instruction->difference;
			break;
		case BRAINFUCK_TOKEN_MINUS:
			context->tape[context->tape_index] -= instruction->difference;
			break;
		case BRAINFUCK_TOKEN_NEXT:
			if ((unsigned long) instruction->difference >= INT_MAX - context->tape_size || 
					(unsigned long) context->tape_index + instruction->difference >= context->tape_size) {
				fprintf(stderr, "error: tape memory out of bounds (overrun)\nexceeded the tape size of %zd cells\n", context->tape_size);
				exit(EXIT_FAILURE);
			}
			context->tape_index += instruction->difference;
			break;
		case BRAINFUCK_TOKEN_PREVIOUS:
			if ((unsigned long) instruction->difference >= INT_MAX - context->tape_size || 
					context->tape_index - instruction->difference < 0) {
				fprintf(stderr, "error: tape memory out of bounds (underrun)\nundershot the tape size of %zd cells\n", context->tape_size);
				exit(EXIT_FAILURE);
			}
			context->tape_index -= instruction->difference;
			break;
		case BRAINFUCK_TOKEN_OUTPUT:
			for (index = 0; index < instruction->difference; index++)
				context->output_handler(context->tape[context->tape_index]);
			break;
		case BRAINFUCK_TOKEN_INPUT:
			for (index = 0; index < instruction->difference; index++)
				context->tape[context->tape_index] = context->input_handler();
			break;
		case BRAINFUCK_TOKEN_LOOP_START:
			while(context->tape[context->tape_index])
				brainfuck_execute(instruction->loop, context);
			break;
		case BRAINFUCK_TOKEN_BREAK: {
			int low  = context->tape_index - 10;
			if (low < 0) low = 0;
			int high = low + 21;
			if (high >= (int) context->tape_size) 
				high = context->tape_size-1;
			for (index = low; index < high; index++)
				printf("%i\t", index);
			printf("\n");
			for (index = low; index < high; index++)
				printf("%d\t", context->tape[index]);
			printf("\n");
			for (index = low; index < high; index++)
				if (index == context->tape_index)
					printf("^\t");
			else
				printf(" \t");
			printf("\n");
 		 	break;
		}
		default:
			return;
		}
		instruction = instruction->next;

		if (context->shouldStop == 1) {
			instruction = NULL;
			return;
		}
	} 
}