diff --git a/src/eval/evaluator.c b/src/eval/evaluator.c new file mode 100644 index 0000000..fd7e140 --- /dev/null +++ b/src/eval/evaluator.c @@ -0,0 +1,46 @@ +#include "evaluator.h" + +static int evaluate_unop(const struct unop_node *un_op) +{ + switch (un_op->op) + { + case IDENTITY: + return evaluate_ast(un_op->rhs); + case NEGATE: + return -evaluate_ast(un_op->rhs); + default: + return 0; + } +} + +static int evaluate_binop(const struct binop_node *bin_op) +{ + switch (bin_op->op) + { + case PLUS: + return evaluate_ast(bin_op->lhs) + evaluate_ast(bin_op->rhs); + case MINUS: + return evaluate_ast(bin_op->lhs) - evaluate_ast(bin_op->rhs); + case TIMES: + return evaluate_ast(bin_op->lhs) * evaluate_ast(bin_op->rhs); + case DIVIDE: + return evaluate_ast(bin_op->lhs) / evaluate_ast(bin_op->rhs); + default: + return 0; + } +} + +int evaluate_ast(const struct ast_node *ast) +{ + switch (ast->kind) + { + case NUM: + return ast->val.num; + case UNOP: + return evaluate_unop(&ast->val.un_op); + case BINOP: + return evaluate_binop(&ast->val.bin_op); + default: + return 0; + } +} diff --git a/src/eval/evaluator.h b/src/eval/evaluator.h new file mode 100644 index 0000000..70c982e --- /dev/null +++ b/src/eval/evaluator.h @@ -0,0 +1,8 @@ +#ifndef EVALUATOR_H +#define EVALUATOR_H + +#include "ast/ast.h" + +int evaluate_ast(const struct ast_node *ast); + +#endif /* !EVALUATOR_H */ diff --git a/src/eval/local.am b/src/eval/local.am new file mode 100644 index 0000000..f0f187b --- /dev/null +++ b/src/eval/local.am @@ -0,0 +1,4 @@ +jitters_SOURCES += \ + %D%/evaluator.c \ + %D%/evaluator.h \ + $(NULL) diff --git a/src/local.am b/src/local.am index a548005..79f1590 100644 --- a/src/local.am +++ b/src/local.am @@ -15,5 +15,6 @@ AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src jitters_LDADD = include %D%/ast/local.am +include %D%/eval/local.am include %D%/parse/local.am include %D%/print/local.am