expr.c (2007B)
1 #include <stdio.h> 2 #include <stdbool.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 #include <string.h> 6 7 #include "expr.h" 8 9 #define SAME(s1, s2) (strcmp(s1, s2) == 0) 10 11 extern FILE *yyin; 12 extern void yyparse(); 13 extern btree *program; 14 extern char vars[26]; 15 bool vals[26]; 16 17 bool 18 eval(btree *p) { 19 bool l, r; 20 switch (p->op) { 21 case '.': 22 l = eval(p->left); 23 r = eval(p->right); 24 return l && r; 25 case '+': 26 l = eval(p->left); 27 r = eval(p->right); 28 return l || r; 29 case '!': 30 l = eval(p->left); 31 return !l; 32 default: 33 return vals[p->op - 65]; 34 } 35 } 36 37 bool 38 read_bool(char *s) { 39 if (s[1] != '\n') goto err; 40 41 switch (*s) { 42 case '0': return false; 43 case '1': return true; 44 } 45 err: 46 fprintf(stderr, "expected 1 or 0\n"); 47 return false; 48 } 49 50 void 51 incvars() { 52 int carry = 1; 53 for (int i = 0; i < 26 && carry; i++) { 54 if (vars[i]) { 55 if (!vals[i]) carry = 0; 56 vals[i] = !vals[i]; 57 } 58 } 59 } 60 61 void 62 mktable() { 63 bool start[26] = {false}; 64 memcpy(start, vals, 26); 65 66 for (int i = 0; i < 26; i++) 67 if (vars[i]) 68 printf("%c | ", vars[i]); 69 printf("RES\n"); 70 71 do { 72 for (int i = 0; i < 26; i++) 73 if (vars[i]) 74 printf("%b | ", vals[i]); 75 printf("%b\n", eval(program)); 76 incvars(); 77 } while (memcmp(start, vals, 26) != 0); 78 } 79 80 int 81 main(int argc, char **argv) { 82 yyin = stdin; 83 if (argc > 1) 84 yyin = fopen(argv[1], "r"); 85 if (!yyin) { 86 fprintf(stderr, "failed to open file, using stdin\n"); 87 yyin = stdin; 88 } 89 90 yyparse(); 91 92 char line[128]; 93 bool res = eval(program); 94 95 for (;;) { 96 printf("> "); 97 fgets(line, 128, stdin); 98 if (isupper(line[0])) { 99 vals[(int)line[0] - 65] = read_bool(line + 2); 100 } 101 else if (SAME(line, "s\n")) 102 printf("res = %s\n", (res) ? "true" : "false"); 103 else if (SAME(line, "q\n")) 104 break; 105 else if (SAME(line, "p\n")) { 106 for (int i = 0; i < 26; i++) { 107 if (vars[i]) 108 printf("%c = %s\n", vars[i], (vals[i]) ? "true" : "false"); 109 } 110 } 111 else if (SAME(line, "t\n")) { 112 mktable(); 113 } 114 else 115 fprintf(stderr, "?\n"); 116 } 117 118 fclose(yyin); 119 return 0; 120 }