Título: [Aporte] Interpretador de Brainfuck Commandline
Publicado por: Meine programmen en 10 Enero 2015, 16:24 pm
Hace algo de tiempo se me ocurrio, y lo hice, y bueno, en un intento por procrastinar un poco, he decidido subirlo. Probablemente no sea del todo eficiente, y tenga bastante fallos, me encantaría que le echarais un vistazo a ver que os parece. Para usarlo, el código en brainfuck tiene que estar escrito en un archivo de texto plano. Simplemente lo arrastras al ejecutable o pones en la cmd braincmduck "archivo.txt" "archivo2.txt" "archivo3.txt" Los irá ejecutando uno después de otro. MODIFICACIÓN: El código que puse a la primera era una versión antigua, ya lo he cambiado. También, cuando quereis introducir un valor 0, teneis que presionar la tecla de backspace. Esto lo hice porque era la unica tecla inutil, de esta manera puedes introducir saltos de linea también. #include<stdio.h> #include<conio.h> #include"espacio.h" #include"funciones.h"
int main (int argc, char **argv) { int num_arg = argc; //Bucle, no sale hasta que ha realizado el proceso con todos los argumentos while (num_arg > 1) { //Crea las variables necesarias¡ int tamanyo = 0; //Pide el tamaño del array a crear if (tamanyo_array(argv[num_arg - 1], tamanyo)) return 1; //Crea el array del tamaño necesario char ordenes[tamanyo]; //Rellena el array con las ordenes; ordenes_array(argv[num_arg - 1], ordenes); //Crea el puntero espacio* espacio_actual = new espacio; //Ejecuta las ordenes ejecutar(espacio_actual, ordenes, 0, tamanyo-1, tamanyo, true); //Reduce en uno el numero de argumentos num_arg--; printf("\n"); } return 0; }
espacio.h: //Fichero de la clase espacio //Definicion y funciones
#include<stdio.h> #include<conio.h>
class espacio{ public: //Constructores espacio() : anterior(NULL), contenido(0), siguiente(NULL) {} espacio(espacio* anterior, espacio* siguiente) : anterior(anterior), contenido(0), siguiente(siguiente) { if (anterior != NULL) anterior->cambiar_sig(this); if (siguiente != NULL) siguiente->cambiar_ant(this); } //Funciones int suma (void); int resta (void); int mostrar (void); int entrada (void); int punt_siguiente (espacio* &espacio_actual); int cambiar_sig (espacio* nuevo_siguiente); int punt_anterior (espacio* &espacio_actual); int cambiar_ant (espacio* nuevo_anterior); int retornar (void); private: //Variables espacio* anterior; int contenido; espacio* siguiente; };
int espacio::suma (void) { //Suma 1 al contenido this->contenido++; return 0; }
int espacio::resta (void) { //Resta 1 al contenido this->contenido--; return 0; }
int espacio::mostrar (void) { //Muestra el caracter ASCII del contenido printf("%c", contenido); return 0; }
int espacio::entrada (void) { //El primer caracter pulsado se convierte en el valor de contenido //Si este es 13, se convierte en 0 //De lo contrario, se muestra el caracter pulsado this->contenido = getch(); if (this->contenido == 8) this->contenido = 0; else if (this->contenido == 13) printf("\n"); else printf("%c", this->contenido); return 0; }
int espacio::punt_siguiente (espacio* &espacio_actual) { //Si no hay un siguiente, lo crea if (this->siguiente == NULL) espacio_actual = new espacio(this, NULL); //Si hay un siguiente, iguala el puntero a su direccion de memoria else espacio_actual = this->siguiente; return 0; }
int espacio::cambiar_sig (espacio* nuevo_siguiente) { this->siguiente = nuevo_siguiente; return 0; }
int espacio::punt_anterior (espacio* &espacio_actual) { //Si no hay un anterior, lo crea if (this->anterior == NULL) espacio_actual = new espacio(NULL, this); //Si hay un anterior, iguala el puntero a su direccion de memoria else espacio_actual = this->anterior; return 0; }
int espacio::cambiar_ant (espacio* nuevo_anterior) { this->anterior = nuevo_anterior; return 0; }
int espacio::retornar (void) { return this->contenido; }
funciones.h: //Fichero de funciones
int ejecutar (espacio* &espacio_actual,char ordenes[], int pos_inicial, int pos_final, int tamanyo, bool var_ejecutar) { //Comprueba si se ha de ejecutar if (!var_ejecutar) return 0; //Crea la variable que dirá la posición en el string int pos_actual = pos_inicial; //Crea el contador de caracteres [ int contador = 0; //Crea una int auxiliar int pos_auxiliar; //No deja el bucle, hasta que al llegar a la posición final, o hemos acabado el string o el actual es = 0 while (pos_actual != pos_final+1 || (espacio_actual->retornar() && (pos_actual != tamanyo || ordenes[pos_actual-1] == ']'))) { //Si la posicion anterior era la final, y aun así se continua el string, se vuelve a la posicion de inicio if (pos_actual > pos_final) pos_actual = pos_inicial; //Lee las acciones y las ejecuta if (ordenes[pos_actual] == '+') espacio_actual->suma(); if (ordenes[pos_actual] == '-') espacio_actual->resta(); if (ordenes[pos_actual] == '.') espacio_actual->mostrar(); if (ordenes[pos_actual] == ',') espacio_actual->entrada(); if (ordenes[pos_actual] == '>') espacio_actual->punt_siguiente(espacio_actual); if (ordenes[pos_actual] == '<') espacio_actual->punt_anterior(espacio_actual); if (ordenes[pos_actual] == '[') { //Comprueba si el bucle se ha de ejecutar o saltar if (!espacio_actual->retornar()) var_ejecutar = false; //Guarda la localizacion del comienzo pos_auxiliar = pos_actual + 1; //Localiza desde donde hasta donde llega el bucle while (contador != -1) { pos_actual++; if (ordenes[pos_actual] == '[') contador++; if (ordenes[pos_actual] == ']') contador--; } //Se resetea el contador contador = 0; //Ejecuta el bucle ejecutar(espacio_actual, ordenes, pos_auxiliar, pos_actual, tamanyo, var_ejecutar); //Resetea la variable ejecutar var_ejecutar = true; } //Se aumenta en uno la posicion actual pos_actual++; } return 0; }
int tamanyo_array (char nombre[], int &tamanyo) { //Abre el archivo FILE *archivo = fopen(nombre, "rt"); //Devuelve error si no existe if (archivo == NULL) return 1; //Recorre el texto buscando los caracteres + - . , < > [ y ] char instruccion = fgetc(archivo); while (instruccion != -1) { if ((instruccion == '+') || (instruccion == '-') || (instruccion == '.') || (instruccion == ',') || (instruccion == '>') || (instruccion == '<') || (instruccion == '[') || (instruccion == ']')) tamanyo++; instruccion = fgetc(archivo); } //Cierra el archivo fclose(archivo); return 0; }
int ordenes_array (char nombre[], char ordenes[]) { //Crea las variables necesarias int contador = 0; //Abre el archivo FILE *archivo = fopen(nombre, "rt"); //Recorre el texto buscando los caracteres + - . , < > [ y ] char instruccion = fgetc(archivo); while (instruccion != -1) { if ((instruccion == '+') || (instruccion == '-') || (instruccion == '.') || (instruccion == ',') || (instruccion == '>') || (instruccion == '<') || (instruccion == '[') || (instruccion == ']')) { ordenes[contador] = instruccion; contador++; } instruccion = fgetc(archivo); } //Cierra el archivo fclose(archivo); return 0; }
|