evalexpr: initial recursive descent parser
This commit is contained in:
commit
a92e39dbec
8 changed files with 536 additions and 0 deletions
67
src/ast/ast.c
Normal file
67
src/ast/ast.c
Normal 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
61
src/ast/ast.h
Normal 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue