Use double instead of int, () are working, splitted expressionbase out to own file.
[calcinator.git] / expression.c
blob331104a5afd43c1301afac4a76690c38674094c7
1 #include "expression.h"
2 #include <math.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
7 int get_precedence(unsigned char op) {
8 switch(op) {
9 case('^'):
10 return 3;
11 break;
12 case('*'):
13 case('/'):
14 return 2;
15 break;
16 case('+'):
17 case('-'):
18 return 1;
19 break;
20 default:
21 return 0;
22 break;
26 double apply_operator(unsigned char op, double value1, double value2) {
27 #if DEBUG
28 printf("Applying %c on %f and %f\n", op, value1, value2);
29 #endif
30 switch(op) {
31 case('^'):
32 return pow(value1, value2);
33 break;
34 case('*'):
35 return value1*value2;
36 case('/'):
37 return value1/value2;
38 break;
39 case('+'):
40 return value1+value2;
41 case('-'):
42 return value1-value2;
43 break;
44 default:
45 return -1;
46 break;
50 double get_value(char *string) {
51 int i = strlen(string);
52 if (!strchr(string, '.')) {
53 strcat(string, ".0\0");
55 return atof(string);
58 void evaluate(Expression *expr) {
59 /**
60 * XXX first expression?
61 * If expr->precendence < next->precedence:
62 * evaluate(next);
63 * new_value = apply_operator(expr->op, expr->value, next->value);
64 * next->value = new_value;
65 * next->prev = expr->prev;
66 * prev->next = expr->next;
68 Expression *next = expr->next;
69 double new_value;
70 if (!next) { // Last expression, do nothing(must be an integer constant)
71 return;
73 if (expr->precedence < next->precedence) { // Next expression has higher precendence
74 evaluate(next);
75 evaluate(expr); // Re-evaluate expr again
76 return;
78 new_value = apply_operator(expr->op, expr->value, next->value);
79 next->value = new_value;
81 // Unlink expr
82 if (expr->prev) { // not first expression
83 next->prev = expr->prev;
84 expr->prev->next = next;
85 } else { // first expression
86 next->prev = 0;
90 void finish_expression(Expression *expr, char *expression, unsigned char op, int precedence_factor) {
91 if (expr->prev && expr->prev->op == 0) {
92 expr->prev->op = '*';
94 if (op == '\n') {
95 expr->op = 0;
96 expr->flags |= CONSTANT;
97 } else {
98 expr->op = op;
100 expr->value = get_value(expression);
101 expr->precedence = get_precedence(op)*precedence_factor;
105 void print_expression(Expression *expr) {
106 printf("Value: \t\t%f\nOperator: \t%c\nPrecedence: \t%d\n===\n", expr->value, expr->op, expr->precedence);