worker.c 4.9 KB

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