#include enum expr_form { expr_ident, expr_int_lit, expr_bool_lit, expr_string_lit, expr_list_lit, expr_tuple_lit, expr_fun_app, expr_match, expr_let, }; struct expr; struct pattern; struct decl; struct decl_list; struct expr_list { struct expr *elem; struct expr_list *next; }; struct expr_list_builder { struct expr_list *head; struct expr_list *last; }; void expr_list_append(struct expr_list_builder *b, struct expr *elem); void free_expr_list(struct expr_list *l); struct func_app { struct expr *fun; struct expr_list *args; }; /* List of case alternatives in a match expression */ struct case_list { struct pattern *pat; struct expr *body; struct case_list *next; }; struct case_list_builder { struct case_list *head; struct case_list *last; }; void case_list_append(struct case_list_builder *b, struct pattern *pat, struct expr *body); void free_case_list(struct case_list *l); struct match_expr { struct expr *cond; struct case_list *alts; }; struct let_expr { struct decl_list *local_decls; struct expr *body; }; struct expr { enum expr_form form; union { /* Useful for identifiers, string and integers */ char *lexeme; bool bool_lit; struct expr_list *list; /* A tuple is represented as a non empty list */ struct expr_list *tuple; struct func_app func_app; struct match_expr match; struct let_expr let; }; }; struct expr *make_ident_expr(char *lexeme); struct expr *make_int_lit(char *lexeme); struct expr *make_bool_lit(bool b); struct expr *make_string_lit(char *lexeme); struct expr *make_list_lit(struct expr_list *list); struct expr *make_tuple_lit(struct expr_list *list); struct expr *make_func_app(struct expr *fun, struct expr_list *args); struct expr *make_match_expr(struct expr *cond, struct case_list *alts); struct expr *make_let_expr(struct decl_list *decls, struct expr *body); void free_expr(struct expr *e);