diff --git a/include/evaluator.h b/include/evaluator.h index e69de29..8e1ea47 100644 --- a/include/evaluator.h +++ b/include/evaluator.h @@ -0,0 +1,9 @@ +#ifndef EVALUATOR_H +#define EVALUATOR_H + +#include "lexer.h" +#include + +uint64_t evaluate(ASTNode *tree); + +#endif // !EVALUATOR_H diff --git a/include/parser.h b/include/parser.h index 64f5df4..911d964 100644 --- a/include/parser.h +++ b/include/parser.h @@ -1,3 +1,6 @@ +#ifndef PARSER_H +#define PARSER_H + #include "lexer.h" #include @@ -23,3 +26,4 @@ uint8_t node_rbp(ASTNode node); AST parse(ASTNodeArray *arr); ASTNode *parse_expr(ASTNodeSlice *slice, uint8_t min_bp); +#endif // !PARSER_H diff --git a/src/evaluator.c b/src/evaluator.c index e69de29..fc0048d 100644 --- a/src/evaluator.c +++ b/src/evaluator.c @@ -0,0 +1,22 @@ +#include "evaluator.h" +#include "lexer.h" +#include + +uint64_t evaluate(ASTNode *tree) { + if (tree->type == NODE_BINARY_OP) { + switch (tree->data.binary.op) { + case OP_ADD: + return evaluate(tree->data.binary.left) + evaluate(tree->data.binary.left); + case OP_SUB: + return evaluate(tree->data.binary.left) - evaluate(tree->data.binary.left); + case OP_MUL: + return evaluate(tree->data.binary.left) * evaluate(tree->data.binary.left); + case OP_DIV: + return evaluate(tree->data.binary.left) / evaluate(tree->data.binary.left); + + } + } else { + return tree->data.integer; + } +} + diff --git a/test/test_evaluator.c b/test/test_evaluator.c new file mode 100644 index 0000000..cf97930 --- /dev/null +++ b/test/test_evaluator.c @@ -0,0 +1,32 @@ +#include "lexer.h" +#include "parser.h" +#include "evaluator.h" +#include +#include +#include +#include +#include +#include +#include + +static void test_basic_evaluation(void** state) { + (void) state; + + char expr[256] = "2 + 4 * 40 / 2"; + ASTNodeArray context; + + tokenize(expr, &context); + AST tree = parse(&context); + uint64_t value = evaluate(tree.head); + + assert_int_equal(value, 82); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_basic_evaluation), + }; + + cmocka_run_group_tests(tests, NULL, NULL); + return EXIT_SUCCESS; +} diff --git a/test/test_parser.c b/test/test_parser.c index 70e550d..83a6592 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -17,34 +17,6 @@ static void test_parsing_basic_expression(void **state) { assert_int_equal(tokenize(expr, &tokens), LEXER_OK); assert_int_equal(tokens.len, 7); - ASTNodeArray_get(&tokens, 0, &node); - assert_int_equal(node.type, NODE_INTEGER); - assert_int_equal(node.data.integer, 2); - - ASTNodeArray_get(&tokens, 1, &node); - assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, OP_ADD); - - ASTNodeArray_get(&tokens, 2, &node); - assert_int_equal(node.type, NODE_INTEGER); - assert_int_equal(node.data.integer, 3); - - ASTNodeArray_get(&tokens, 3, &node); - assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, OP_DIV); - - ASTNodeArray_get(&tokens, 4, &node); - assert_int_equal(node.type, NODE_INTEGER); - assert_int_equal(node.data.integer, 66); - - ASTNodeArray_get(&tokens, 5, &node); - assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, OP_MUL); - - ASTNodeArray_get(&tokens, 6, &node); - assert_int_equal(node.type, NODE_INTEGER); - assert_int_equal(node.data.integer, 789); - AST tree = parse(&tokens); // Assert head is + assert_int_equal(tree.head->type, NODE_BINARY_OP);