Guest User

BinaryStateMachine

a guest
Oct 20th, 2016
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.23 KB | None | 0 0
  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "string.h"
  4.  
  5. #include "termios.h"
  6. #include "fcntl.h"
  7. #include "errno.h"
  8. #include "signal.h"
  9. #include "unistd.h"
  10. const char NEXTSTATE = 0;
  11. const char STAYSTATE = 1;
  12. const char ROOTSTATE = 2;
  13.  
  14. typedef struct BinaryStateLink {
  15. int (*decision)(char);
  16.  
  17. void (*left)(void *, char);
  18. char leftMask;
  19. void (*right)(void *, char);
  20. char rightMask;
  21.  
  22. struct BinaryStateLink * next;
  23. } BSL;
  24.  
  25. typedef struct BinaryStateMachine {
  26. BSL * root;
  27. BSL * current;
  28. void * data;
  29. } BSM;
  30.  
  31. BSM * makeMachine(void * d) {
  32. BSM * machine = malloc(sizeof(BSM));
  33. machine->root = NULL;
  34. machine->current = NULL;
  35. machine->data = d;
  36. return machine;
  37. }
  38.  
  39. void addState(BSM * machine, int (*d)(char), void (*l)(void *, char), char lm, void (*r)(void *, char), char rm) {
  40. BSL * link = malloc(sizeof(BSL));
  41. link->decision = d;
  42.  
  43. link->left = l;
  44. link->leftMask = lm;
  45. link->right = r;
  46. link->rightMask = rm;
  47.  
  48. link->next = NULL;
  49.  
  50. BSL * walker = machine->root;
  51.  
  52. if (walker == NULL) {
  53. machine->root = link;
  54. } else {
  55. while (walker->next != NULL) {
  56. walker = walker->next;
  57. }
  58.  
  59. walker->next = link;
  60. }
  61. }
  62.  
  63. void restart(BSM * machine) {
  64. machine->current = machine->root;
  65. }
  66.  
  67. void decide(BSM * machine, char c) {
  68. if (machine->current == NULL) {
  69. fprintf(stderr, "STATE MACHINE NOT STARTED YET!");
  70. return;
  71. }
  72.  
  73. char mask;
  74.  
  75. if (machine->current->decision(c) == 0) { //Left
  76. machine->current->left(machine->data, c);
  77. mask = machine->current->leftMask;
  78. } else { //Right
  79. machine->current->right(machine->data, c);
  80. mask = machine->current->rightMask;
  81. }
  82.  
  83. if (mask == NEXTSTATE) {
  84. machine->current = machine->current->next;
  85. } else if (mask == STAYSTATE) {
  86. machine->current = machine->current;
  87. } else if (mask == ROOTSTATE) {
  88. machine->current = machine->root;
  89. } else {
  90. fprintf(stderr, "UNDEFINED MASK!");
  91. }
  92. }
  93. #include "stdio.h"
  94.  
  95. int always_right(char c) {
  96. return 1;
  97. }
  98.  
  99. int always_left(char c) {
  100. return 0;
  101. }
  102.  
  103. int match_escape(char c) {
  104. return c == 27;
  105. }
  106.  
  107. int match_bracket(char c) {
  108. return c == '[';
  109. }
  110.  
  111. int match_arrows(char c) {
  112. if (c == 'A') {
  113. fprintf(stdout, "Up Arrow");
  114. } else if (c == 'B') {
  115. fprintf(stdout, "Down Arrow");
  116. } else if (c == 'C') {
  117. fprintf(stdout, "Right Arrow");
  118. } else if (c == 'D') {
  119. fprintf(stdout, "Left Arrow");
  120. } else {
  121. return 0;
  122. }
  123.  
  124. return 1;
  125. }
  126.  
  127. void doNothing(void * mem, char c) {
  128. //I do nothing!
  129. }
  130.  
  131. void printChar(void * mem, char c) {
  132. if (c<' ' || c>'~' || c=='[' || c==']' || c=='"') {
  133. fprintf(stdout, "[%d]", c);
  134. } else {
  135. fprintf(stdout, "%c", c);
  136. }
  137. }
  138.  
  139. typedef struct MachineMemory {
  140. char * line;
  141. int appendPos;
  142. } MachineMemory;
  143.  
  144. BSM * createMachine() {
  145. MachineMemory * mem = malloc(sizeof(MachineMemory));
  146. mem->line = malloc(sizeof(char) * 100);
  147. mem->appendPos = 0;
  148.  
  149. BSM * machine = makeMachine(mem);
  150. addState(machine, match_escape, printChar, ROOTSTATE, doNothing, NEXTSTATE);
  151. addState(machine, match_bracket, printChar, ROOTSTATE, doNothing, NEXTSTATE);
  152. addState(machine, match_arrows, doNothing, ROOTSTATE, doNothing, ROOTSTATE);
  153. restart(machine);
  154. return machine;
  155. }
  156.  
  157. struct termios oldSettings;
  158.  
  159. void reset_terminal() {
  160. tcsetattr(0, TCSANOW, &oldSettings);
  161. }
  162.  
  163. int main() {
  164. tcgetattr(0, &oldSettings);
  165. atexit(reset_terminal);
  166.  
  167. struct termios settings;
  168. tcgetattr(0, &settings);
  169. settings.c_lflag &= ~ ECHO;
  170. settings.c_lflag &= ~ ICANON;
  171. settings.c_cc[VMIN] = 1;
  172. settings.c_cc[VTIME] = 0;
  173. tcsetattr(0, TCSAFLUSH, &settings);
  174.  
  175. BSM * machine = createMachine();
  176.  
  177. while (1) {
  178. char line[1000];
  179. int r = read(0, line, 999);
  180. if (r < 0) {
  181. if (errno == EAGAIN) {
  182. usleep(1000);
  183. continue;
  184. }
  185.  
  186. fprintf(stderr, "errno is %d\n", errno);
  187. perror("read error: ");
  188. } else if (r == 0) {
  189. //Nothing read.
  190. } else {
  191. line[r] = 0; //Gives the null terminating character at the end.
  192.  
  193. for (int i = 0; i < strlen(line); ++i) {
  194. decide(machine, line[i]);
  195. }
  196.  
  197. fprintf(stdout, "\n");
  198. }
  199. }
  200.  
  201. return 0;
  202. }
Advertisement
Add Comment
Please, Sign In to add comment