Просмотр исходного кода

Add files via upload

actually works now.

some files crash the flipper.
no defence against infinite loops.
inputs not implemented.
J 3 лет назад
Родитель
Сommit
0d8ed608a9
8 измененных файлов с 233 добавлено и 40 удалено
  1. 1 1
      application.fam
  2. 10 12
      brainfuck.c
  3. 7 6
      brainfuck_i.h
  4. 1 1
      scenes/brainfuck_scene_exec.c
  5. 2 2
      scenes/brainfuck_scene_file_create.c
  6. 17 14
      views/bf_dev_env.c
  7. 191 3
      worker.c
  8. 4 1
      worker.h

+ 1 - 1
application.fam

@@ -7,7 +7,7 @@ App(
         "storage",
         "gui",
     ],
-    stack_size=4 * 1024,
+    stack_size=8 * 1024,
     fap_icon="bfico.png",
     fap_category="Misc",
     fap_icon_assets="icons",

+ 10 - 12
brainfuck.c

@@ -23,7 +23,6 @@ BFApp* brainfuck_alloc() {
     BFApp* brainfuck = malloc(sizeof(BFApp));
 
     brainfuck->dataSize = 0;
-    brainfuck->bfStack = 0;
     brainfuck->view_dispatcher = view_dispatcher_alloc();
     brainfuck->scene_manager = scene_manager_alloc(&brainfuck_scene_handlers, brainfuck);
     view_dispatcher_enable_queue(brainfuck->view_dispatcher);
@@ -50,19 +49,17 @@ BFApp* brainfuck_alloc() {
     brainfuck->text_input = text_input_alloc();
     view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewTextInput, text_input_get_view(brainfuck->text_input));
 
+    // Textbox
+    brainfuck->text_box = text_box_alloc();
+    view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewTextBox, text_box_get_view(brainfuck->text_box)); 
+    brainfuck->text_box_store = furi_string_alloc();
+
     // Dev environment
     brainfuck->BF_dev_env = bf_dev_env_alloc(brainfuck);
     view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewDev, bf_dev_env_get_view(brainfuck->BF_dev_env));
 
-    // Exec environment
-    brainfuck->BF_exec_env = bf_exec_env_alloc(brainfuck);
-    view_dispatcher_add_view(brainfuck->view_dispatcher, brainfuckViewExec, bf_exec_env_get_view(brainfuck->BF_exec_env));
-
     // File path
     brainfuck->BF_file_path = furi_string_alloc();
-    
-    // Worker
-    initWorker();
 
     return brainfuck;
 }
@@ -82,14 +79,15 @@ void brainfuck_free(BFApp* brainfuck) {
     view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewTextInput);
     text_input_free(brainfuck->text_input);
 
+    // TextBox
+    view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewTextBox);
+    text_box_free(brainfuck->text_box);
+    furi_string_free(brainfuck->text_box_store);
+
     //dev env
     view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewDev);
     bf_dev_env_free(brainfuck->BF_dev_env);
 
-    //exec env
-    view_dispatcher_remove_view(brainfuck->view_dispatcher, brainfuckViewExec);
-    bf_exec_env_free(brainfuck->BF_exec_env);
-
     // View Dispatcher
     view_dispatcher_free(brainfuck->view_dispatcher);
 

+ 7 - 6
brainfuck_i.h

@@ -2,7 +2,7 @@
 
 typedef struct BFDevEnv BFDevEnv;
 typedef struct BFExecEnv BFExecEnv;
-typedef unsigned char rByte;
+typedef unsigned char byte;
 
 #include "brainfuck.h"
 #include "worker.h"
@@ -18,6 +18,7 @@ typedef unsigned char rByte;
 #include <gui/modules/loading.h>
 #include <gui/modules/text_input.h>
 #include <gui/modules/widget.h>
+#include <gui/modules/text_box.h>
 
 #include <dialogs/dialogs.h>
 #include <input/input.h>
@@ -25,7 +26,6 @@ typedef unsigned char rByte;
 #include "scenes/brainfuck_scene.h"
 
 #include "views/bf_dev_env.h"
-#include "views/bf_exec_env.h"
 
 #include <storage/storage.h>
 #include <lib/toolbox/path.h>
@@ -36,7 +36,7 @@ typedef unsigned char rByte;
 #include <stream/buffered_file_stream.h>
 #include <toolbox/stream/file_stream.h>
 
-#define BF_INST_BUFFER_SIZE 1024
+#define BF_INST_BUFFER_SIZE 2048
 #define BF_STACK_INITIAL_SIZE 128
 #define BF_STACK_STEP_SIZE 32
 #define BF_OUTPUT_SIZE 512
@@ -64,12 +64,12 @@ struct BFApp {
     Submenu* submenu;
     Popup* popup;
     TextInput* text_input;
+    TextBox* text_box;
+    FuriString* text_box_store;
     FuriString* BF_file_path;
     BFDevEnv* BF_dev_env;
-    BFExecEnv* BF_exec_env;
     int dataSize;
-    rByte dataBuffer[BF_INST_BUFFER_SIZE];
-    rByte* bfStack;
+    char dataBuffer[BF_INST_BUFFER_SIZE];
 };
 
 typedef enum {
@@ -77,6 +77,7 @@ typedef enum {
     brainfuckViewPopup,
     brainfuckViewLoading,
     brainfuckViewTextInput,
+    brainfuckViewTextBox,
     brainfuckViewWidget,
     brainfuckViewDev,
     brainfuckViewExec,

+ 1 - 1
scenes/brainfuck_scene_exec.c

@@ -2,7 +2,7 @@
 
 void brainfuck_scene_exec_env_on_enter(void* context) {
     BFApp* app = context;
-    view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewExec);
+    view_dispatcher_switch_to_view(app->view_dispatcher, brainfuckViewTextBox);
 }
 
 bool brainfuck_scene_exec_env_on_event(void* context, SceneManagerEvent event) {

+ 2 - 2
scenes/brainfuck_scene_file_create.c

@@ -6,7 +6,7 @@ void file_name_text_input_callback(void* context) {
 }
 
 char tmpName[64] = {};
-rByte empty[1] = {0x00};
+byte empty[1] = {0x00};
 void brainfuck_scene_file_create_on_enter(void* context) {
     BFApp* app = context;
     TextInput* text_input = app->text_input;
@@ -39,7 +39,7 @@ bool brainfuck_scene_file_create_on_event(void* context, SceneManagerEvent event
             //save new file
             Stream* stream = buffered_file_stream_alloc(storage);
             buffered_file_stream_open(stream, furi_string_get_cstr(app->BF_file_path), FSAM_WRITE, FSOM_CREATE_ALWAYS);
-            stream_write(stream, empty, 1);
+            stream_write(stream, (const uint8_t*)empty, 1);
             buffered_file_stream_close(stream);
 
             //scene_manager_next_scene(app->scene_manager, brainfuckSceneFileSelect);

+ 17 - 14
views/bf_dev_env.c

@@ -9,8 +9,8 @@ typedef struct BFDevEnv {
 } BFDevEnv;
 
 typedef struct {
-    rByte row;
-    rByte col;
+    uint32_t row;
+    uint32_t col;
 } BFDevEnvModel;
 
 typedef struct{
@@ -158,7 +158,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 0:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'+'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'+'; 
                 appDev->dataSize++; }
             break;
         }
@@ -166,7 +166,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 1:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'-'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'-'; 
                 appDev->dataSize++; }
             break;
         }
@@ -174,7 +174,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 2:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'<'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'<'; 
                 appDev->dataSize++; }
             break;
         }
@@ -182,7 +182,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 3:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'>'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'>'; 
                 appDev->dataSize++; }
             break;
         }
@@ -190,7 +190,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 4:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'['; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'['; 
                 appDev->dataSize++; }
             break;
         }
@@ -198,7 +198,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 5:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)']'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)']'; 
                 appDev->dataSize++; }
             break;
         }
@@ -206,7 +206,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 6:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)'.'; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)'.'; 
                 appDev->dataSize++; }
             break;
         }
@@ -214,7 +214,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         case 7:
         {
             if(appDev->dataSize < BF_INST_BUFFER_SIZE){ 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)','; 
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)','; 
                 appDev->dataSize++; }
             break;
         }
@@ -223,12 +223,15 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
         {
             if(appDev->dataSize > 0){
                 appDev->dataSize--; 
-                appDev->dataBuffer[appDev->dataSize] = (rByte)0x00;}
+                appDev->dataBuffer[appDev->dataSize] = (uint32_t)0x00;}
             break;
         }
 
         case 9:
         {
+            initWorker(appDev->dataBuffer, appDev->dataSize);
+            beginWorker();
+            text_box_set_text(appDev->text_box, workerGetOutput());
             scene_manager_next_scene(appDev->scene_manager, brainfuckSceneExecEnv);
             break;
         }
@@ -242,7 +245,7 @@ static bool bf_dev_process_ok(BFDevEnv* devEnv, InputEvent* event) {
             //save new file
             Stream* stream = buffered_file_stream_alloc(storage);
             buffered_file_stream_open(stream, furi_string_get_cstr(appDev->BF_file_path), FSAM_WRITE, FSOM_CREATE_ALWAYS);
-            stream_write(stream, appDev->dataBuffer, appDev->dataSize);
+            stream_write(stream, (const uint8_t*)appDev->dataBuffer, appDev->dataSize);
             buffered_file_stream_close(stream);
 
             //notify
@@ -271,7 +274,7 @@ static void bf_dev_enter_callback(void* context) {
     appDev = devEnv->appDev;
 
     //clear the bf instruction buffer
-    memset(appDev->dataBuffer, 0x00, BF_INST_BUFFER_SIZE);
+    memset(appDev->dataBuffer, 0x00, BF_INST_BUFFER_SIZE * sizeof(char));
 
     //open the file
     Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -280,7 +283,7 @@ static void bf_dev_enter_callback(void* context) {
 
     //read into the buffer
     appDev->dataSize = stream_size(stream);
-    stream_read(stream, appDev->dataBuffer, appDev->dataSize);
+    stream_read(stream, (uint8_t*)appDev->dataBuffer, appDev->dataSize);
     buffered_file_stream_close(stream);
 
     //find the end of the file to begin editing

+ 191 - 3
worker.c

@@ -1,19 +1,207 @@
 #include "brainfuck_i.h"
 
+int status = 0; //0: idle, 1: running, 2: failure
+
+char* inst = 0;
+int instCount = 0;
+int instPtr = 0;
+int runOpCount = 0;
+
 char* wOutput = 0;
+int wOutputPtr = 0;
+
+char wInput = 0x00;
+bool wInputFlag = false;
 
-uint32_t* bfStack = 0;
+char* bfStack = 0;
+int stackPtr = 0;
 int stackSize = BF_STACK_INITIAL_SIZE;
+int stackSizeReal = 0;
+
+bool validateInstPtr(){
+    if(instPtr > instCount || instPtr < 0){
+        return false;
+    }
+    return true;
+}
+
+bool validateStackPtr(){
+    if(stackPtr > stackSize || stackPtr < 0){
+        return false;
+    }
+    return true;
+}
 
 char* workerGetOutput(){
     return wOutput;
 }
 
-void initWorker(){
+int getStackSize(){
+    return stackSizeReal;
+}
+
+int getOpCount(){
+    return runOpCount;
+}
+
+int getStatus(){
+    return status;
+}
+
+void workerSetInput(char c){
+    wInput = c;
+    wInputFlag = true;
+}
+
+void initWorker(char* instructions, int instructionsCount){
+    //rebuild output
+    if(wOutput){ free(wOutput); }
     wOutput = (char*)malloc(BF_OUTPUT_SIZE);
-    bfStack = (uint32_t*)malloc(BF_STACK_INITIAL_SIZE);
+    wOutputPtr = 0;
+
+    //rebuild stack
+    if(bfStack){ free(bfStack); }
+    bfStack = (char*)malloc(BF_STACK_INITIAL_SIZE);
+    memset(bfStack, 0x00, BF_STACK_INITIAL_SIZE);
+    stackSize = BF_STACK_INITIAL_SIZE;
+    stackSizeReal = 0;
+    stackPtr = 0;
+
+    //reset input
+    wInput = 0x00;
+    wInputFlag = false;
+
+    //set instructions
+    inst = instructions;
+    instCount = instructionsCount;
+    instPtr = 0;
+    runOpCount = 0;
+
+    //set status
+    status = 0;
+}
+
+void rShift(){
+    runOpCount++;
+    stackPtr++;
+    if(!validateStackPtr()){ status = 2; return; }
+
+    while(stackPtr > stackSize){
+        stackSize += BF_STACK_STEP_SIZE;
+        void* tmp = realloc(bfStack, stackSize);
+
+        if(!tmp){ 
+            status = 2;
+            return;
+        }
+
+        memset((tmp + stackSize) - BF_STACK_STEP_SIZE, 0x00, BF_STACK_STEP_SIZE);
+        bfStack = tmp;
+    };
+    if(stackPtr > stackSizeReal){ 
+        stackSizeReal = stackPtr; 
+    }
+}
+
+void lShift(){
+    runOpCount++;
+    stackPtr--;
+    if(!validateStackPtr()){ status = 2; return; }
+}
+
+void inc(){
+    runOpCount++;
+    if(!validateStackPtr()){ status = 2; return; }
+    bfStack[stackPtr]++;
+}
+
+void dec(){
+    runOpCount++;
+    if(!validateStackPtr()){ status = 2; return; }
+    bfStack[stackPtr]--;
+}
+
+void print(){
+    runOpCount++;
+    wOutput[wOutputPtr] = bfStack[stackPtr];
+    wOutputPtr++;
+    if(wOutputPtr > (BF_OUTPUT_SIZE - 1)){ wOutputPtr = 0;}
+}
+
+void input(){
+    runOpCount++;
+    //todo
+    wInput = 0x00;
+    wInputFlag = true;
+}
+
+void loop() {
+    runOpCount++;
+	if (bfStack[stackPtr] == 0) {
+		int loopCount = 1;
+		while (loopCount > 0) {
+			instPtr++;
+            if(!validateInstPtr()){ status = 2; return; }
+			if (inst[instPtr] == '[') { loopCount++; }
+			else if (inst[instPtr] == ']') { loopCount--; }
+		}
+	}
+}
+
+void endLoop() {
+    runOpCount++;
+	if (bfStack[stackPtr] != 0) {
+		int loopCount = 1;
+		while (loopCount > 0) {
+			instPtr--;
+            if(!validateInstPtr()){ status = 2; return; }
+			if (inst[instPtr] == ']') { loopCount++; }
+			else if (inst[instPtr] == '[') { loopCount--; }
+		}
+	}
 }
 
 void beginWorker(){
+    status = 1;
+    while (inst[instPtr] != 0x00) {
+        if(status == 2){ return; }
+        switch (inst[instPtr]) {
+            case '>':
+                rShift();
+                break;
+            case '<':
+                lShift();
+                break;
 
+            case '+':
+                inc();
+                break;
+                
+            case '-':
+                dec();
+                break;
+                
+            case '.':
+                print();
+                break;
+            
+            case ',':
+                input();
+                break;
+                
+            case '[':
+                loop();
+                break;
+                
+            case ']':
+                endLoop();
+                break;
+                
+            default:
+                break;
+        }
+        instPtr++;
+        if(!validateInstPtr()){ status = 2; return; }
+    }
+    status = 0;
 }

+ 4 - 1
worker.h

@@ -1,3 +1,6 @@
-void initWorker();
+void initWorker(char* instructions, int instructionsCount);
 char* workerGetOutput();
+int getStackSize();
+int getOpCount();
+int getStatus();
 void beginWorker();