Browse Source

Evaluation of expressions implemented. Major problem with CONCAT discovered.

master
Cameron Weinfurt 1 year ago
parent
commit
651bba5f22
  1. 19
      Makefile
  2. 51
      eval.c
  3. 16
      eval.h
  4. 5
      infint.c
  5. 1
      infint.h
  6. 7
      infint_four_func.c
  7. 24
      infint_util.c
  8. 22
      main.c
  9. 20
      parse.c

19
Makefile

@ -1,4 +1,6 @@
objs = main.o token.o expr.o parse.o infint.o
objs = main.o token.o expr.o parse.o infint.o eval.o
CC = clang
dev: FLAGS= -g -D UNIT_TESTS
dev: build
@ -9,22 +11,25 @@ release: clean build
rm *.o
build: $(objs)
clang $(FLAGS) -o infcalc $(objs)
$(CC) $(FLAGS) -o infcalc $(objs)
clean:
rm *.o infcalc
main.o: main.c expr.h
clang $(FLAGS) -c main.c -o main.o
$(CC) $(FLAGS) -c main.c -o main.o
token.o: token.c token.h
clang $(FLAGS) -c token.c -o token.o
$(CC) $(FLAGS) -c token.c -o token.o
expr.o: expr.c expr.h
clang $(FLAGS) -c expr.c -o expr.o
$(CC) $(FLAGS) -c expr.c -o expr.o
parse.o: parse.c parse.h token.h expr.h
clang $(FLAGS) -c parse.c -o parse.o
$(CC) $(FLAGS) -c parse.c -o parse.o
infint.o: infint*.c
clang $(FLAGS) -c infint.c -o infint.o
$(CC) $(FLAGS) -c infint.c -o infint.o
eval.o: eval.c eval.h expr.h infint.h
$(CC) $(FLAGS) -c eval.c -o eval.o

51
eval.c

@ -0,0 +1,51 @@
#include "eval.h"
infint_t *evaluate(expr_t *e) {
infint_t *iil, *iir;
iil = NULL;
if (e->flags & EXFLAG_REXP) {
iir = evaluate(e->right.expr);
} else {
iir = infint_new(2);
iir->data[0] = e->right.data;
}
iir->sign ^= !!(e->flags & EXFLAG_RNEG);
if (e->flags & EXFLAG_LEXP) {
iil = evaluate(e->left.expr);
iil->sign ^= !!(e->flags & EXFLAG_LNEG);
}
switch(e->opcode) {
case EXPR_ADD:
if (e->flags & EXFLAG_MOD) { // Concatination
infint_grow_to(iir, iir->size + 1);
iir->data[iir->size - 1] = e->left.data;
} else { // Addition and Subtraction
if (iil) {
infint_add2(iir, iil);
} else if (e->flags & EXFLAG_LNEG) {
infint_sub(iir, e->left.data);
} else {
infint_add(iir, e->left.data);
}
}
break;
case EXPR_MULT:
if (e->flags & EXFLAG_MOD) { // Division
// Not fully supported yet. No-op for now.
} else {
if (iil) {
infint_mult2(iir, iil);
} else {
infint_mult(iir, e->left.data);
iir->sign ^= !!(e->flags & EXFLAG_LNEG);
}
}
break;
case EXPR_IPOW:
break;// Not supported at all. No-op for now.
}
return iir;
}

16
eval.h

@ -0,0 +1,16 @@
#ifndef EVALH
#define EVALH
#include "expr.h"
#include "infint.h"
infint_t *evaluate(expr_t *e);
#ifdef UNIT_TESTS
#include <assert.h>
//void test_evaluate();
#endif
#endif

5
infint.c

@ -12,6 +12,7 @@ void test_utils() {
assert(ii1->size == ii1->capacity == 1);
assert(ii1->sign == 0);
ii2 = infint_clone(ii1);
assert(ii2->data[0] == 0);
assert(ii2->size == ii1->capacity == 1);
@ -53,6 +54,10 @@ void test_utils() {
assert(ii2->data[0] == 0);
assert(ii2->data[1] == 1);
char *ii1s = infint_to_string(ii1);
assert(strcmp(ii1s, "10099") == 0);
free(ii1s);
infint_free(ii1);
infint_free(ii2);
}

1
infint.h

@ -25,6 +25,7 @@ void infint_comp(infint_t *ii);
char infint_abs_less_than(infint_t *ii, uint8_t n);
char infint_abs_less_than2(infint_t *ii1, infint_t *ii2);
void infint_shift_right(infint_t *ii, size_t n);
char *infint_to_string(infint_t *ii);
// Four functions
void infint_add(infint_t *ii, uint8_t n);

7
infint_four_func.c

@ -26,10 +26,13 @@ void infint_sub(infint_t *ii, uint8_t n) {
ii->data[0] = n - ii->data[0];
ii->sign = 1;
} else {
size_t old_size = ii->size;
infint_comp(ii);
infint_add(ii, n);
ii->data[ii->size - 1] = 0;
while (ii->data[ii->size - 1] == 0 && ii->size > 1) ii->size -= 1;
if (ii->size > old_size)
ii->data[ii->size - 1] = 0;
while (ii->data[ii->size - 1] == 0 && ii->size > 1)
ii->size -= 1;
infint_comp(ii);
}
}

24
infint_util.c

@ -80,3 +80,27 @@ void infint_shift_right(infint_t *ii, size_t n) {
memset(ii->data, 0, n);
}
}
char *infint_to_string(infint_t *ii) {
char *str = malloc(ii->size * 2 * sizeof(char) + 1);
size_t si;
uint8_t *ii_ptr = ii->data + ii->size - 1;
if (*ii_ptr >= 10) {
str[0] = *ii_ptr / 10 + '0';
str[1] = *ii_ptr % 10 + '0';
si = 2;
} else {
str[0] = *ii_ptr + '0';
si = 1;
}
--ii_ptr;
while (ii_ptr >= ii->data) {
str[si] = *ii_ptr / 10 + '0';
++si;
str[si] = *ii_ptr % 10 + '0';
++si;
--ii_ptr;
}
str[si] = 0;
return str;
}

22
main.c

@ -4,19 +4,16 @@
#include "expr.h"
#include "infint.h"
#include "parse.h"
#include "eval.h"
#ifdef UNIT_TESTS
int main() {
#ifdef UNIT_TESTS
test_infint();
test_expr_and_parse();
printf("**********************\n| All tests passed |\n**********************\n");
}
#else
#endif
int main() {
char *line = NULL;
size_t line_len = 0;
getline(&line,&line_len,stdin);
@ -26,8 +23,15 @@ int main() {
free(line);
print_expr_tree(e, 0);
#ifdef UNIT_TESTS
print_expr_tree(e, 0);
#endif
infint_t *iie = evaluate(e);
char *iistr = infint_to_string(iie);
printf("%s\n", iistr);
free(iistr);
infint_free(iie);
destroy_expr(e);
}
#endif

20
parse.c

@ -16,7 +16,9 @@ expr_t *parse_hex_int() {
num->right.data = fromhex(ptr);
for (int d = 0; d < 16; ++d) {
ptr++;
if (ptr == input_str) return num;
if (ptr == input_str) {
return num;
}
num->right.data = num->right.data * 16 + fromhex(ptr);
}
ptr++;
@ -29,7 +31,9 @@ expr_t *parse_hex_int() {
more_num->right.data = *ptr - '0';
for (int d = 0; d < 16; ++d) {
ptr++;
if (ptr == input_str) return bubble_expr(num, more_num);
if (ptr == input_str) {
return bubble_expr(num, more_num);
}
more_num->right.data = more_num->right.data * 16 + fromhex(ptr);
}
ptr++;
@ -48,7 +52,11 @@ expr_t *parse_decimal_int() {
num->par = NULL;
num->right.data = *ptr - '0';
ptr++;
if (ptr == input_str) return num;
if (ptr == input_str) {
num->flags |= EXFLAG_RNEG;
num->right.data *= 10;
return num;
}
num->right.data = num->right.data * 10 + *ptr - '0';
ptr++;
@ -59,7 +67,11 @@ expr_t *parse_decimal_int() {
more_num->left.data = 0;
more_num->right.data = *ptr - '0';
ptr++;
if (ptr == input_str) return bubble_expr(num, more_num);
if (ptr == input_str) {
num->flags |= EXFLAG_RNEG;
num->right.data *= 10;
return bubble_expr(num, more_num);
}
more_num->right.data = more_num->right.data * 10 + *ptr - '0';
ptr++;
num = bubble_expr(num, more_num);

Loading…
Cancel
Save