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: