-
Notifications
You must be signed in to change notification settings - Fork 1
/
node_binop.c
63 lines (60 loc) · 2.01 KB
/
node_binop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<assert.h>
#include<stdlib.h>
#include "node.h"
#include "data.h"
#include "util.h"
/* evaluate, allocate and return a data struct. */
Data *node_binop_evaluate(Node *node, map_t context) {
LURE_ASSERT(node != NULL, "cannot evaluate against NULL node");
LURE_ASSERT(node->left != NULL, "left side of a binary operation must not be empty");
LURE_ASSERT(node->right != NULL, "right side of a binary operation must not be empty");
Data *leftRet = node->left->evaluate(node->left, context);
Data *rightRet = node->right->evaluate(node->right, context);
bool flag = false;
if (node->op == BinOpType_OR) {
flag = leftRet->toBoolean(leftRet) || rightRet->toBoolean(rightRet);
goto eval_return;
}else if(node->op == BinOpType_AND) {
flag = leftRet->toBoolean(leftRet) && rightRet->toBoolean(rightRet);
goto eval_return;
}
int cmp = leftRet->compareTo(leftRet, rightRet);
switch (node->op) {
case BinOpType_EQ:
flag = cmp == 0;
break;
case BinOpType_GE:
flag = cmp >= 0;
break;
case BinOpType_LE:
flag = cmp <= 0;
break;
case BinOpType_GT:
flag = cmp > 0;
break;
case BinOpType_LT:
flag = cmp < 0;
break;
case BinOpType_NE:
flag = cmp != 0;
break;
default:
break;
}
eval_return:
leftRet->clean(leftRet); free(leftRet);
rightRet->clean(rightRet); free(rightRet);
return NewBoolData(flag);
}
Node *NewNodeBinOp(BinOpType op, Node *left, Node *right) {
LURE_ASSERT(left != NULL, "left side of a binary operation must not be empty");
LURE_ASSERT(right != NULL, "right side of a binary operation must not be empty");
Node *node = (Node *)calloc(1, sizeof(Node));
node->op = op;
node->type = NodeType_BinOp;
node->left = left;
node->right = right;
node->list = NULL;
node->evaluate = node_binop_evaluate;
return node;
}