#pragma once static char *strchrnul(char *s, char c) { while (*s && *s != c) s++; return s; } enum TYPE { TYPE_BASIC, TYPE_POINTER, TYPE_ARRAY, TYPE_STRUCT, TYPE_UNION, TYPE_FUNCTION, }; struct type { char *typedef_line; enum TYPE kind; unsigned long id; // basic type char *basic; // pointer & array types struct type *base; unsigned long length; // struct & union types struct type *members; struct type *next_member; char *field_name; // function types struct type *return_type; struct type *params; struct type *next_param; unsigned long is_variadic; }; enum INSTRUCTION_TYPE { INSTRUCTION_DECLARE, INSTRUCTION_DEREF_ASSIGN, INSTRUCTION_ASSIGN_DEREF, INSTRUCTION_CAST, INSTRUCTION_COPY, INSTRUCTION_OTHER, }; struct instruction { char *line; enum INSTRUCTION_TYPE kind; struct instruction *next, **pprev; }; struct function { char *start_line; struct type *type; struct instruction *instructions; struct function *next; }; struct object { char *name; struct type *type; }; struct program { char *original; // all lines before the function definitions char *preamble; // id -> type table struct type **id2type; unsigned long n_types; // hash map of objects struct object **objects; unsigned long cap_objects; unsigned long n_objects; struct function *functions; }; struct identifiers { char *token; struct identifier *next; }; char *libdietc_tokdup(char *tok); struct program libdietc_parse(char *filename); void libdietc_print(struct program program); char *libdietc_nth_token(char *string, int n); struct type *libdietc_object_type(struct program program, char *name); struct type *libdietc_lhs_type(struct program program, struct instruction *instruction); struct instruction *libdietc_insert_before(struct instruction *i, char *line); struct instruction *libdietc_insert_after(struct instruction *i, char *line);