worker.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include "worker.h"
  2. #include <furi_hal_resources.h>
  3. #include <furi.h>
  4. bool killswitch = false;
  5. int status = 0; //0: idle, 1: running, 2: failure
  6. char* inst = 0;
  7. int instCount = 0;
  8. int instPtr = 0;
  9. int runOpCount = 0;
  10. char* wOutput = 0;
  11. int wOutputPtr = 0;
  12. char* wInput = 0;
  13. int wInputPtr = 0;
  14. uint8_t* bfStack = 0;
  15. int stackPtr = 0;
  16. int stackSize = BF_STACK_INITIAL_SIZE;
  17. int stackSizeReal = 0;
  18. BFApp* wrkrApp = 0;
  19. void killThread(){
  20. killswitch = true;
  21. }
  22. bool validateInstPtr(){
  23. if(instPtr > instCount || instPtr < 0){
  24. return false;
  25. }
  26. return true;
  27. }
  28. bool validateStackPtr(){
  29. if(stackPtr > stackSize || stackPtr < 0){
  30. return false;
  31. }
  32. return true;
  33. }
  34. char* workerGetOutput(){
  35. return wOutput;
  36. }
  37. int getStackSize(){
  38. return stackSizeReal;
  39. }
  40. int getOpCount(){
  41. return runOpCount;
  42. }
  43. int getStatus(){
  44. return status;
  45. }
  46. void initWorker(BFApp* app){
  47. wrkrApp = app;
  48. //rebuild output
  49. if(wOutput){ free(wOutput); }
  50. wOutput = (char*)malloc(BF_OUTPUT_SIZE);
  51. wOutputPtr = 0;
  52. //rebuild stack
  53. if(bfStack){ free(bfStack); }
  54. bfStack = (uint8_t*)malloc(BF_STACK_INITIAL_SIZE);
  55. memset(bfStack, 0x00, BF_STACK_INITIAL_SIZE);
  56. stackSize = BF_STACK_INITIAL_SIZE;
  57. stackSizeReal = 0;
  58. stackPtr = 0;
  59. //set instructions
  60. inst = wrkrApp->dataBuffer;
  61. instCount = wrkrApp->dataSize;
  62. instPtr = 0;
  63. runOpCount = 0;
  64. //set input
  65. wInput = wrkrApp->inputBuffer;
  66. wInputPtr = 0;
  67. //set status
  68. status = 0;
  69. }
  70. void rShift(){
  71. runOpCount++;
  72. stackPtr++;
  73. if(!validateStackPtr()){ status = 2; return; }
  74. while(stackPtr > stackSize){
  75. stackSize += BF_STACK_STEP_SIZE;
  76. void* tmp = realloc(bfStack, stackSize);
  77. if(!tmp){
  78. status = 2;
  79. return;
  80. }
  81. memset((tmp + stackSize) - BF_STACK_STEP_SIZE, 0x00, BF_STACK_STEP_SIZE);
  82. bfStack = (uint8_t*)tmp;
  83. };
  84. if(stackPtr > stackSizeReal){
  85. stackSizeReal = stackPtr;
  86. }
  87. }
  88. void lShift(){
  89. runOpCount++;
  90. stackPtr--;
  91. if(!validateStackPtr()){ status = 2; return; }
  92. }
  93. void inc(){
  94. runOpCount++;
  95. if(!validateStackPtr()){ status = 2; return; }
  96. bfStack[stackPtr]++;
  97. }
  98. void dec(){
  99. runOpCount++;
  100. if(!validateStackPtr()){ status = 2; return; }
  101. bfStack[stackPtr]--;
  102. }
  103. void print(){
  104. runOpCount++;
  105. wOutput[wOutputPtr] = bfStack[stackPtr];
  106. wOutputPtr++;
  107. if(wOutputPtr > (BF_OUTPUT_SIZE - 1)){ wOutputPtr = 0;}
  108. }
  109. void input(){
  110. runOpCount++;
  111. bfStack[stackPtr] = (uint8_t)wInput[wInputPtr];
  112. if(wInput[wInputPtr] == 0x00 || wInputPtr >= 64){
  113. wInputPtr = 0;
  114. }
  115. else{
  116. wInputPtr++;
  117. }
  118. }
  119. void loop() {
  120. runOpCount++;
  121. if (bfStack[stackPtr] == 0) {
  122. int loopCount = 1;
  123. while (loopCount > 0) {
  124. instPtr++;
  125. if(!validateInstPtr()){ status = 2; return; }
  126. if (inst[instPtr] == '[') { loopCount++; }
  127. else if (inst[instPtr] == ']') { loopCount--; }
  128. }
  129. }
  130. }
  131. void endLoop() {
  132. runOpCount++;
  133. if (bfStack[stackPtr] != 0) {
  134. int loopCount = 1;
  135. while (loopCount > 0) {
  136. instPtr--;
  137. if(!validateInstPtr()){ status = 2; return; }
  138. if (inst[instPtr] == ']') { loopCount++; }
  139. else if (inst[instPtr] == '[') { loopCount--; }
  140. }
  141. }
  142. }
  143. static const NotificationSequence led_on = {
  144. &message_blue_255,
  145. &message_do_not_reset,
  146. NULL,
  147. };
  148. static const NotificationSequence led_off = {
  149. &message_blue_0,
  150. NULL,
  151. };
  152. void input_kill(void* _ctx) {
  153. UNUSED(_ctx);
  154. killswitch = true;
  155. }
  156. void beginWorker(){
  157. status = 1;
  158. //redefined from furi_hal_resources.c
  159. const GpioPin gpio_button_back = {.port = GPIOC, .pin = LL_GPIO_PIN_13};
  160. while (inst[instPtr] != 0x00) {
  161. if(runOpCount % 500 == 0){
  162. text_box_set_text(wrkrApp->text_box, workerGetOutput());
  163. notification_message(wrkrApp->notifications, &led_on);
  164. }
  165. //status 2 indicates failure
  166. if(status == 2){ status = 0; break; }
  167. //read back button directly to avoid weirdness in furi
  168. if(killswitch || !furi_hal_gpio_read(&gpio_button_back)) {
  169. status = 0;
  170. killswitch = false;
  171. break;
  172. }
  173. switch (inst[instPtr]) {
  174. case '>':
  175. rShift();
  176. break;
  177. case '<':
  178. lShift();
  179. break;
  180. case '+':
  181. inc();
  182. break;
  183. case '-':
  184. dec();
  185. break;
  186. case '.':
  187. print();
  188. break;
  189. case ',':
  190. input();
  191. break;
  192. case '[':
  193. loop();
  194. break;
  195. case ']':
  196. endLoop();
  197. break;
  198. default:
  199. break;
  200. }
  201. instPtr++;
  202. if(!validateInstPtr()){ status = 0; break; }
  203. }
  204. notification_message(wrkrApp->notifications, &led_off);
  205. text_box_set_text(wrkrApp->text_box, workerGetOutput());
  206. status = 0;
  207. }