This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
sys_prog/bexp/bexp_calculator.c
2019-11-04 10:29:44 +01:00

151 lines
3.5 KiB
C

// vim: set ts=4 sw=4 et tw=80:
#include <stdio.h>
#include <stdlib.h>
#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
}