#ifndef CMONKEY_AST_H #define CMONKEY_AST_H #include "token.h" #include "vector.h" enum node_type { NODE_PROGRAM, NODE_STATEMENT, NODE_EXPRESSION, }; enum statement_type { STATEMENT_LET, STATEMENT_RETURN, STATEMENT_EXPRESSION, STATEMENT_BLOCK, }; enum expression_type { EXPRESSION_IDENT, EXPRESSION_INT, EXPRESSION_BOOL, EXPRESSION_PREFIX, EXPRESSION_INFIX, EXPRESSION_IF, EXPRESSION_FUNC, EXPRESSION_CALL, }; struct identifier { struct token token; struct slice value; }; struct prefix_expression { struct token token; struct slice operator; struct expression *right; }; struct infix_expression { struct token token; struct slice operator; struct expression *left; struct expression *right; }; struct integer_expression { struct token token; int64_t value; }; struct boolean_expression { struct token token; bool value; }; struct if_expression { struct token token; struct expression *condition; struct statement *consequence; struct statement *alternative; }; struct func_literal { struct token token; struct vector *parameters; // expression type ident struct statement *body; }; struct call_expression { struct token token; struct expression *func; struct vector *arguments; // expressions }; struct expression { enum expression_type type; union { struct token token; // Common initial sequence struct identifier ident; struct integer_expression integer; struct boolean_expression boolean; struct prefix_expression prefix; struct infix_expression infix; struct if_expression cond; struct func_literal func; struct call_expression call; }; }; struct expression_statement { struct token token; struct expression *expr; }; struct return_statement { struct token token; struct expression *value; }; struct let_statement { struct token token; struct identifier *name; struct expression *value; }; struct block_statement { struct token token; struct vector *statements; }; struct program { struct vector *statements; }; struct statement { enum statement_type type; union { struct token token; // Common initial sequence struct let_statement let; struct return_statement retrn; struct expression_statement expr; struct block_statement block; }; }; struct slice expression_token_literal(struct expression *); struct slice statement_token_literal(struct statement *); struct slice program_token_literal(struct program *); #define node_token_literal(n) _Generic((n), \ struct program *: program_token_literal, \ struct statement *: statement_token_literal, \ struct expression *: expression_token_literal \ )(n) char *expression_sprint(struct expression *, char *str); char *statement_sprint(struct statement *, char *str); char *program_sprint(struct program *, char *str); #define node_sprint(n, a) _Generic((n), \ struct expression *: expression_sprint, \ struct statement *: statement_sprint, \ struct program *: program_sprint \ )(n, a) struct vector *expression_vector_dup(const struct vector *); struct vector *statement_vector_dup(const struct vector *); struct expression *expression_dup(const struct expression *); struct statement *statement_dup(const struct statement *); #define node_dup(n) _Generic((n), \ struct expression *: expression_dup, \ struct statement *: statement_dup \ )(n) void expression_destroy(struct expression *); void statement_destroy(struct statement *); void program_destroy(struct program *); #define node_destroy(n) _Generic((n), \ struct expression *: expression_destroy, \ struct statement *: statement_destroy, \ struct program *: program_destroy \ )(n) #endif