evalexpr: initial recursive descent parser

This commit is contained in:
Bruno BELANYI 2020-10-28 15:30:54 +01:00
commit a92e39dbec
8 changed files with 536 additions and 0 deletions

67
src/ast/ast.c Normal file
View file

@ -0,0 +1,67 @@
#include "ast.h"
#include <stdlib.h>
struct ast_node *make_num(int val)
{
struct ast_node *ret = malloc(sizeof(*ret));
if (ret == NULL)
return ret;
ret->kind = NODE_NUM;
ret->val.num = val;
return ret;
}
struct ast_node *make_unop(enum unop_kind op, struct ast_node *tree)
{
struct ast_node *ret = malloc(sizeof(*ret));
if (ret == NULL)
return ret;
ret->kind = NODE_UNOP;
ret->val.un_op.op = op;
ret->val.un_op.tree = tree;
return ret;
}
struct ast_node *make_binop(enum binop_kind op, struct ast_node *lhs,
struct ast_node *rhs)
{
struct ast_node *ret = malloc(sizeof(*ret));
if (ret == NULL)
return ret;
ret->kind = NODE_BINOP;
ret->val.bin_op.op = op;
ret->val.bin_op.lhs = lhs;
ret->val.bin_op.rhs = rhs;
return ret;
}
void destroy_ast(struct ast_node *ast)
{
if (!ast)
return;
switch (ast->kind)
{
case NODE_BINOP:
destroy_ast(ast->val.bin_op.lhs);
destroy_ast(ast->val.bin_op.rhs);
break;
case NODE_UNOP:
destroy_ast(ast->val.un_op.tree);
/* fallthrough */
case NODE_NUM:
break;
}
free(ast);
}

61
src/ast/ast.h Normal file
View file

@ -0,0 +1,61 @@
#ifndef AST_H
#define AST_H
// Forward declaration
struct ast_node;
enum unop_kind
{
UNOP_IDENTITY,
UNOP_NEGATE,
UNOP_FACT,
};
enum binop_kind
{
BINOP_PLUS,
BINOP_MINUS,
BINOP_TIMES,
BINOP_DIVIDES,
BINOP_POW,
};
struct unop_node
{
enum unop_kind op;
struct ast_node *tree;
};
struct binop_node
{
enum binop_kind op;
struct ast_node *lhs;
struct ast_node *rhs;
};
struct ast_node
{
enum node_kind
{
NODE_UNOP,
NODE_BINOP,
NODE_NUM,
} kind;
union ast_val
{
struct unop_node un_op;
struct binop_node bin_op;
int num;
} val;
};
struct ast_node *make_num(int val);
struct ast_node *make_unop(enum unop_kind op, struct ast_node *tree);
struct ast_node *make_binop(enum binop_kind op, struct ast_node *lhs,
struct ast_node *rhs);
void destroy_ast(struct ast_node *ast);
#endif /* !AST_H */