mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 11:38:36 -07:00
Rename plugins to external
This commit is contained in:
291
applications/external/brainfuck/worker.c
vendored
Normal file
291
applications/external/brainfuck/worker.c
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
#include "worker.h"
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi.h>
|
||||
|
||||
bool killswitch = false;
|
||||
|
||||
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 = 0;
|
||||
int wInputPtr = 0;
|
||||
|
||||
uint8_t* bfStack = 0;
|
||||
int stackPtr = 0;
|
||||
int stackSize = BF_STACK_INITIAL_SIZE;
|
||||
int stackSizeReal = 0;
|
||||
|
||||
BFApp* wrkrApp = 0;
|
||||
|
||||
void killThread() {
|
||||
killswitch = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int getStackSize() {
|
||||
return stackSizeReal;
|
||||
}
|
||||
|
||||
int getOpCount() {
|
||||
return runOpCount;
|
||||
}
|
||||
|
||||
int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
void initWorker(BFApp* app) {
|
||||
wrkrApp = app;
|
||||
|
||||
//rebuild output
|
||||
if(wOutput) {
|
||||
free(wOutput);
|
||||
}
|
||||
wOutput = (char*)malloc(BF_OUTPUT_SIZE);
|
||||
wOutputPtr = 0;
|
||||
|
||||
//rebuild stack
|
||||
if(bfStack) {
|
||||
free(bfStack);
|
||||
}
|
||||
bfStack = (uint8_t*)malloc(BF_STACK_INITIAL_SIZE);
|
||||
memset(bfStack, 0x00, BF_STACK_INITIAL_SIZE);
|
||||
stackSize = BF_STACK_INITIAL_SIZE;
|
||||
stackSizeReal = 0;
|
||||
stackPtr = 0;
|
||||
|
||||
//set instructions
|
||||
inst = wrkrApp->dataBuffer;
|
||||
instCount = wrkrApp->dataSize;
|
||||
instPtr = 0;
|
||||
runOpCount = 0;
|
||||
|
||||
//set input
|
||||
wInput = wrkrApp->inputBuffer;
|
||||
wInputPtr = 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 = (uint8_t*)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++;
|
||||
|
||||
bfStack[stackPtr] = (uint8_t)wInput[wInputPtr];
|
||||
if(wInput[wInputPtr] == 0x00 || wInputPtr >= 64) {
|
||||
wInputPtr = 0;
|
||||
} else {
|
||||
wInputPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const NotificationSequence led_on = {
|
||||
&message_blue_255,
|
||||
&message_do_not_reset,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NotificationSequence led_off = {
|
||||
&message_blue_0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void input_kill(void* _ctx) {
|
||||
UNUSED(_ctx);
|
||||
killswitch = true;
|
||||
}
|
||||
|
||||
void beginWorker() {
|
||||
status = 1;
|
||||
|
||||
//redefined from furi_hal_resources.c
|
||||
const GpioPin gpio_button_back = {.port = GPIOC, .pin = LL_GPIO_PIN_13};
|
||||
|
||||
while(inst[instPtr] != 0x00) {
|
||||
if(runOpCount % 500 == 0) {
|
||||
text_box_set_text(wrkrApp->text_box, workerGetOutput());
|
||||
notification_message(wrkrApp->notifications, &led_on);
|
||||
}
|
||||
|
||||
//status 2 indicates failure
|
||||
if(status == 2) {
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//read back button directly to avoid weirdness in furi
|
||||
if(killswitch || !furi_hal_gpio_read(&gpio_button_back)) {
|
||||
status = 0;
|
||||
killswitch = false;
|
||||
break;
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
notification_message(wrkrApp->notifications, &led_off);
|
||||
text_box_set_text(wrkrApp->text_box, workerGetOutput());
|
||||
status = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user