diff --git a/include/evaluator.h b/include/evaluator.h index 5d5b4fe..0e63307 100644 --- a/include/evaluator.h +++ b/include/evaluator.h @@ -1,7 +1,6 @@ #ifndef EVALUATOR_H #define EVALUATOR_H -#include "lexer.h" #include "parser.h" #include @@ -20,6 +19,9 @@ typedef struct { }; } EvaluatorResult; +EvaluatorResult evaluate_binary(Node *tree); +EvaluatorResult evaluate_unary(Node *tree); + EvaluatorResult evaluate(ParserResult context); EvaluatorResult evaluate_tree(Node *tree); diff --git a/include/parser.h b/include/parser.h index 040ed6f..3a6b197 100644 --- a/include/parser.h +++ b/include/parser.h @@ -11,7 +11,6 @@ typedef enum { NODE_INT, NODE_BINARY_OP, NODE_UNARY_OP, - NODE_PARENTHESIS, } NodeType; typedef struct Node { diff --git a/src/evaluator.c b/src/evaluator.c index 9a8adaf..2c2884c 100644 --- a/src/evaluator.c +++ b/src/evaluator.c @@ -9,81 +9,93 @@ EvaluatorResult evaluate_tree(Node *tree) { if (tree->type == NODE_BINARY_OP) { - Operator op = tree->binary.op; - Node *left = tree->binary.left; - Node *right = tree->binary.right; - - switch (op) { - case OP_ADD: { - EvaluatorResult left_result = evaluate_tree(left); - EvaluatorResult right_result = evaluate_tree(right); - if (!left_result.is_valid || !right_result.is_valid) { - return left_result; - } - return (EvaluatorResult) { - .is_valid = true, - .val = left_result.val + right_result.val, - }; - } - case OP_SUB: { - EvaluatorResult left_result = evaluate_tree(left); - EvaluatorResult right_result = evaluate_tree(right); - if (!left_result.is_valid || !right_result.is_valid) { - return left_result; - } - return (EvaluatorResult) { - .is_valid = true, - .val = left_result.val - right_result.val, - }; - } - case OP_MUL: { - EvaluatorResult left_result = evaluate_tree(left); - EvaluatorResult right_result = evaluate_tree(right); - if (!left_result.is_valid || !right_result.is_valid) { - return left_result; - } - return (EvaluatorResult) { - .is_valid = true, - .val = left_result.val * right_result.val, - }; - } - case OP_DIV: { - EvaluatorResult left_result = evaluate_tree(left); - EvaluatorResult right_result = evaluate_tree(right); - if (!left_result.is_valid || !right_result.is_valid) { - return left_result; - } - return (EvaluatorResult) { - .is_valid = true, - .val = left_result.val / right_result.val, - }; - } - case OP_POW: { - EvaluatorResult left_result = evaluate_tree(left); - EvaluatorResult right_result = evaluate_tree(right); - if (!left_result.is_valid || !right_result.is_valid) { - return left_result; - } - return (EvaluatorResult) { - .is_valid = true, - .val = pow(left_result.val, right_result.val), - }; - } - default: - return (EvaluatorResult) { - .is_valid = false, - .err = EVALUATOR_INVALID_TREE, - }; - } + return evaluate_binary(tree); } else if (tree->type == NODE_UNARY_OP) { - + return evaluate_unary(tree); } - int64_t return_val = tree->data.integer; - return return_val; + return (EvaluatorResult) { + .is_valid = true, + .val = tree->num, + }; } -EvaluatorResult evaluate(ParseResult context) { +EvaluatorResult evaluate_binary(Node *tree) { + Operator op = tree->binary.op; + Node *left = tree->binary.left; + Node *right = tree->binary.right; + + EvaluatorResult left_result = evaluate_tree(left); + EvaluatorResult right_result = evaluate_tree(right); + if (!left_result.is_valid || !right_result.is_valid) { + return left_result; + } + + switch (op) { + case OP_ADD: + return (EvaluatorResult) { + .is_valid = true, + .val = left_result.val + right_result.val, + }; + case OP_SUB: + return (EvaluatorResult) { + .is_valid = true, + .val = left_result.val - right_result.val, + }; + case OP_MUL: + return (EvaluatorResult) { + .is_valid = true, + .val = left_result.val * right_result.val, + }; + case OP_DIV: + return (EvaluatorResult) { + .is_valid = true, + .val = left_result.val / right_result.val, + }; + case OP_POW: + return (EvaluatorResult) { + .is_valid = true, + .val = pow(left_result.val, right_result.val), + }; + default: + return (EvaluatorResult) { + .is_valid = false, + .err = EVALUATOR_INVALID_TREE, + }; + } +} + +EvaluatorResult evaluate_unary(Node *tree) { + Operator op = tree->unary.op; + Node *to = tree->unary.to; + + EvaluatorResult result = evaluate_tree(to); + if (!result.is_valid) { + return result; + } + + switch (op) { + case OP_ADD: + return result; + case OP_SUB: + return (EvaluatorResult) { + .is_valid = true, + .val = -result.val, + }; + case OP_FACTORIAL: + return (EvaluatorResult) { + .is_valid = true, + .val = tgamma(result.val + 1), + }; + default: + return (EvaluatorResult) { + .is_valid = false, + .err = EVALUATOR_INVALID_TREE, + }; + } +} + +EvaluatorResult evaluate(ParserResult context) { if (!context.is_valid) { return (EvaluatorResult) { .is_valid = false,