{
assert(left);
assert(right);
- return ast_new(op, left->hdr.type, left, right, NULL);
+ AstNode* ret = NULL;
+ if (both_const(left,right))
+ {
+ AstValue* a = (AstValue*)left;
+ AstValue* b = (AstValue*)right;
+ if (a->hdr.type->form == FORM_INT || a->hdr.type->form == FORM_BOOL)
+ {
+ switch (op)
+ {
+ case '+': a->val.i = a->val.i + b->val.i; break;
+ case '-': a->val.i = a->val.i - b->val.i; break;
+ case '*': a->val.i = a->val.i * b->val.i; break;
+ case '/': a->val.i = a->val.i / b->val.i; break;
+ case '%': a->val.i = a->val.i % b->val.i; break;
+ case AND: a->val.i = a->val.i && b->val.i; break;
+ case OR: a->val.i = a->val.i || b->val.i; break;
+
+ case EQ:
+ a->val.i = a->val.i == b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ case NEQ:
+ a->val.i = a->val.i != b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ case '<':
+ a->val.i = a->val.i < b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ case LTEQ:
+ a->val.i = a->val.i <= b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ case '>':
+ a->val.i = a->val.i > b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ case GTEQ:
+ a->val.i = a->val.i >= b->val.i;
+ a->hdr.type = &BoolType;
+ break;
+
+ // case IS: break;
+
+ default:
+ assert(!"not a valid op");
+ break;
+ }
+ }
+ else if (a->hdr.type->form == FORM_REAL)
+ {
+ switch (op)
+ {
+ case '+': a->val.f = a->val.f + b->val.f; break;
+ case '-': a->val.f = a->val.f - b->val.f; break;
+ case '*': a->val.f = a->val.f * b->val.f; break;
+ case '/': a->val.f = a->val.f / b->val.f; break;
+
+ case EQ:
+ a->val.f = a->val.f == b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ case NEQ:
+ a->val.f = a->val.f != b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ case '<':
+ a->val.f = a->val.f < b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ case LTEQ:
+ a->val.f = a->val.f <= b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ case '>':
+ a->val.f = a->val.f > b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ case GTEQ:
+ a->val.f = a->val.f >= b->val.f;
+ a->hdr.type = &BoolType;
+ break;
+
+ default:
+ assert(!"not a valid op");
+ break;
+ }
+ }
+ else
+ {
+ assert(!"not a valid form");
+ }
+ ret = (AstNode*)a;
+ }
+ else
+ {
+ ret = ast_new(op, left->hdr.type, left, right, NULL);
+ }
+ return ret;
}
AstNode* ast_unop(int op, AstNode* operand)