From 017523b516066a8143284dc8e322ea19ea2be529 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 12 Jul 2021 07:56:16 -0400 Subject: [PATCH] added constant operations for binary operators --- cerise/src/ast.c | 110 ++++++++++++++++++++++++++++++++++++++++++- cerise/src/grammar.c | 1 + 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/cerise/src/ast.c b/cerise/src/ast.c index 52ea2ea..3664af8 100644 --- a/cerise/src/ast.c +++ b/cerise/src/ast.c @@ -107,7 +107,115 @@ AstNode* ast_binop(int op, AstNode* left, AstNode* right) { 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) diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 790dfbf..a0eaaba 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -270,6 +270,7 @@ static AstNode* simple_expr(Parser* p) { int op = consume(p); // OP AstNode* operand = term(p); +// check_num(p, operand); expr = ast_unop(op, operand); } else -- 2.49.0