BrainFuck [Así se llama el lenguaje]

Para probar la habilidad, intente hacer un interprete de esta miercoles, al comienzo todo bien, viento a popa. Hasta que llegue a la implementación de los bucles.

Para ver cómo se estructura, aquí:

Pues, tuve que implementar un sistema de pilas para los bucles anidados, y mucha depuración con deepseek, aunque no haya escrito código la ia. Ya que implementaba estructuras raras.

Al final se logro sacar un pequeño interprete, luego, buscando ejemplos, encontré este que armo lo mismo, pero compilado, el mio solo interpreta.

Sus ejemplos funcionan en el mío:

Fuente del interprete BrainFuck:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

/*
 *	LEXER-INTERPETER Brain-Fuck
 *	Author: Marco
 *	License: Privative, no, MIT
 *	If you use this code, set me credits
*/

typedef struct{
	int capacity;
	int size;
	int *data;
}STACK;

void Init(STACK* stack)
{
	stack->data = (int*)malloc(2*sizeof(int));
	stack->capacity = 2;
	stack->size = 0;
}

void push(STACK *stack,int element)
{
	if(stack->capacity == stack->size){
		stack->data = (int*)realloc(stack->data,stack->capacity*2*sizeof(int));
		stack->capacity *= 2;
		*(stack->data+stack->size) = element;
		stack->size += 1;
	}else{
		*(stack->data+stack->size) = element;
		stack->size += 1;
	}
}

int pop(STACK *stack)
{
	if(stack->size <= 0) return -1;
	stack->size -= 1;
	return *(stack->data+stack->size);
}

int getLastValue(STACK *stack)
{
	if(stack->size <= 0) return -1;
	return *(stack->data+stack->size-1);
}

void FREE(STACK *stack)
{
	free(stack->data);
}

constexpr uint32_t sizeframebuffer = 1000;

bool lexer(const uint64_t addr_code,const size_t size_code,const uint64_t addr_framebuffer)
{
	const char * code_t = (char*)addr_code;
	uint8_t * framebuffer_t = (uint8_t*)addr_framebuffer;
	uint64_t cursor = 0;
	uint64_t index = 0;
	STACK stack;
	Init(&stack);
	while(index < size_code){
		if(cursor >= sizeframebuffer) return false;
		switch(code_t[index]){
			case '<': // Move cursor to left
				if(cursor > 0) cursor--;
				break;
			case '>': // Move cursor to right
				if(cursor < sizeframebuffer) cursor++;
				break;
			case '+': // Increment value
				framebuffer_t[cursor] += 1;
				break;
			case '-': // Decrement value
				framebuffer_t[cursor] -= 1;
				break;
			case ',': // Read input
				framebuffer_t[cursor] = getchar();
				break;
			case '.': // Draw symbol
				putchar(framebuffer_t[cursor]);
				break;
			case '[': // Init loop, to value 0
				if(framebuffer_t[cursor] != 0){
					push(&stack,index);
				}else if(framebuffer_t[cursor] == 0){
					int countLoop = 1;
					while(countLoop > 0){
						index++;
						if(code_t[index] == '[') countLoop += 1;
						else if(code_t[index] == ']') countLoop -= 1;
					}
				}
				break;
			case ']': // End loop
				if(framebuffer_t[cursor] == 0){
					pop(&stack);
				}else{
					int lastValue = getLastValue(&stack);
					if(lastValue != -1) index = lastValue;
				}
				break;
			default:
				break;
		}
		index++;
	}
	putchar(0x0A);
	FREE(&stack);
	return true;
}

int main(int argc,char**argv)
{
	if(argc <= 1) return -1;
	FILE *f = fopen(argv[1],"rb");
	if(!f) return -1;
	fseek(f,0,SEEK_END);
	size_t sizef = ftell(f);
	fseek(f,0,SEEK_SET);
	char *const code = (char*)malloc(sizef+1);
	fread(code,sizef,1,f);
	fclose(f);
	uint8_t *const framebuffer = (uint8_t*)calloc(sizeframebuffer,0x00);
	if(!lexer((uint64_t)code,sizef,(uint64_t)framebuffer)) return -1;
	free(code);
	free(framebuffer);
	return 0;
}

@Chad le dedico en un video:

5 Me gusta