// vim: set ts=4 sw=4 et tw=80: #include #include #include "bexp.h" #include "ctype.h" typedef struct stack { value first; struct stack* next; char container[]; } stack_t; stack_t* tos = NULL; void read_value(); void read_command(); void discard(); void discard() { fprintf(stderr, "Value is malformed. Discarding until space...\n"); while(isspace(getchar())); return; } int read_word() { char c; while (isspace(c = getchar())); ungetc(c, stdin); if (c == '0' || c == '1') { read_value(); } else { read_command(); } } void read_value() { int str_size = 10; stack_t* new = malloc(sizeof(stack_t) + str_size * sizeof(char)); if (!new) { perror("Cannot allocate new stack element"); return; } new->next = tos; int count = 0; char c; while(!isspace(c = getchar())) { if (c != '0' || c != '1') { free(new); discard(); return; } new->container[count++] = c; if (str_size == count) { str_size *= 2; new = realloc(new, sizeof(stack_t) + str_size * sizeof(char)); if (!new) { perror("Cannot allocate new stack element"); free(new); return; } } } new->first.begin = new->container; new->first.end = new->container + count; tos = new; } int ensure(char* str) { while (str) { if (tolower(getchar()) != *str) { return 0; } str++; } return 1; } void print_value(const value* val) { char* v = val->begin; while (v != val->end) putchar(*(v++)); putchar('\n'); } void read_command() { operator_t op; switch(getchar()) { case '&': op = AND; break; case '|': op = OR; break; case '^': op = XOR; break; case '+': op = PLUS; break; case '>': op = GREATER_THAN; break; case '<': op = LESS_THAN; break; case '!': op = NOT; break; case '~': op = COMPLEMENT; break; case 't': case 'T': if (!ensure("op")) { discard(); } else { if (tos == NULL) { printf("empty\n"); } else { print_value(&(tos->first)); } } return; case 'p': case 'P': if (!ensure("op")) { discard(); } else { if (tos == NULL) { printf("empty\n"); } else { print_value(&(tos->first)); stack_t* t = tos; tos = tos->next; free(t); } } return; default: discard(); return; } int binary = op != NOT && op != COMPLEMENT; if (tos == NULL || (binary && tos->next == NULL)) { printf("too few values on stack\n"); return; } expression_t ex = { op, tos->value, binary ? tos->next->value : NULL }; int length = bexp_length(&ex); char* result = malloc(sizeof(stack_t) + sizeof(char) * length); if (!result) { perror("Cannot allocate space for result"); return; } value v_result = { result, result + length }; bexp_evaluate(&v_result, &ex); stack_t }