It works, basic but works, need to move out logic to places, like ASTNode array shouldn't be on the lexer or future logic for fractions and error handling in the evaluator. Just the things at the top of my head
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef EVALUATOR_H
|
||||||
|
#define EVALUATOR_H
|
||||||
|
|
||||||
|
#include "lexer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint64_t evaluate(ASTNode *tree);
|
||||||
|
|
||||||
|
#endif // !EVALUATOR_H
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -23,3 +26,4 @@ uint8_t node_rbp(ASTNode node);
|
|||||||
AST parse(ASTNodeArray *arr);
|
AST parse(ASTNodeArray *arr);
|
||||||
ASTNode *parse_expr(ASTNodeSlice *slice, uint8_t min_bp);
|
ASTNode *parse_expr(ASTNodeSlice *slice, uint8_t min_bp);
|
||||||
|
|
||||||
|
#endif // !PARSER_H
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#include "evaluator.h"
|
||||||
|
#include "lexer.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
32
test/test_evaluator.c
Normal file
32
test/test_evaluator.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "lexer.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "evaluator.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <cmocka.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -17,34 +17,6 @@ static void test_parsing_basic_expression(void **state) {
|
|||||||
assert_int_equal(tokenize(expr, &tokens), LEXER_OK);
|
assert_int_equal(tokenize(expr, &tokens), LEXER_OK);
|
||||||
assert_int_equal(tokens.len, 7);
|
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);
|
AST tree = parse(&tokens);
|
||||||
// Assert head is +
|
// Assert head is +
|
||||||
assert_int_equal(tree.head->type, NODE_BINARY_OP);
|
assert_int_equal(tree.head->type, NODE_BINARY_OP);
|
||||||
|
|||||||
Reference in New Issue
Block a user