diff options
Diffstat (limited to 'wrapperhelper/src/lang.h')
| -rw-r--r-- | wrapperhelper/src/lang.h | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/wrapperhelper/src/lang.h b/wrapperhelper/src/lang.h new file mode 100644 index 00000000..568ab855 --- /dev/null +++ b/wrapperhelper/src/lang.h @@ -0,0 +1,439 @@ +#pragma once + +#ifndef LANG_H +#define LANG_H + +#include "cstring.h" +#include "khash.h" +#include "vector.h" + +#define LONG_IS_32BITS 0 + +enum token_sym_type_e { + SYM_LBRACKET, + SYM_RBRACKET, + SYM_LSQBRACKET, + SYM_RSQBRACKET, + SYM_LPAREN, + SYM_RPAREN, + SYM_HASH, + SYM_HASHHASH, + SYM_SEMICOLON, + SYM_COLON, + SYM_COLONCOLON, + SYM_VARIADIC, + SYM_QUESTION, + SYM_DOT, + SYM_DASHGT, + SYM_TILDE, + SYM_EXCL, + SYM_PLUS, + SYM_DASH, + SYM_STAR, + SYM_SLASH, + SYM_PERCENT, + SYM_HAT, + SYM_AMP, + SYM_PIPE, + SYM_EQ, + SYM_PLUSEQ, + SYM_DASHEQ, + SYM_STAREQ, + SYM_SLASHEQ, + SYM_PERCENTEQ, + SYM_HATEQ, + SYM_AMPEQ, + SYM_PIPEEQ, + SYM_EQEQ, + SYM_EXCLEQ, + SYM_LT, + SYM_GT, + SYM_LTEQ, + SYM_GTEQ, + SYM_AMPAMP, + SYM_PIPEPIPE, + SYM_LTLT, + SYM_GTGT, + SYM_LTLTEQ, + SYM_GTGTEQ, + SYM_PLUSPLUS, + SYM_DASHDASH, + SYM_COMMA, +}; +#define LAST_SYM SYM_COMMA + +typedef struct preproc_token_s { + enum preproc_token_e { + PPTOK_INVALID = 0, + PPTOK_IDENT, // Expandable ident + PPTOK_IDENT_UNEXP, // Unexpandable ident + PPTOK_NUM, + PPTOK_STRING, + PPTOK_INCL, + PPTOK_SYM, + PPTOK_NEWLINE, + PPTOK_BLANK, + PPTOK_START_LINE_COMMENT, + PPTOK_EOF + } tokt; + union { + string_t *str; + struct { + string_t *sstr; // The string literal content + int sisstr; // 0 for '' or <>, 1 for "" + }; + char c; + enum token_sym_type_e sym; + } tokv; +} preproc_token_t; +VECTOR_DECLARE(preproc, preproc_token_t) +void preproc_token_del(preproc_token_t *tok); + +enum token_keyword_type_e { + KW_ALIGNAS = 0, + KW_ALIGNOF, + KW_ATOMIC, + KW_AUTO, + KW_BOOL, + KW_BREAK, + KW_CASE, + KW_CHAR, + KW_COMPLEX, + KW_CONST, + KW_CONTINUE, + KW_DEFAULT, + KW_DO, + KW_DOUBLE, + KW_ELSE, + KW_ENUM, + KW_EXTERN, + KW_FLOAT, + KW_FOR, + KW_GENERIC, + KW_GOTO, + KW_IF, + KW_IMAGINARY, + KW_INLINE, + KW_INT, + KW_INT128, + KW_LONG, + KW_NORETURN, + KW_REGISTER, + KW_RESTRICT, + KW_RETURN, + KW_SHORT, + KW_SIGNED, + KW_SIZEOF, + KW_STATIC, + KW_STATIC_ASSERT, + KW_STRUCT, + KW_SWITCH, + KW_THREAD_LOCAL, + KW_TYPEDEF, + KW_UNION, + KW_UNSIGNED, + KW_VOID, + KW_VOLATILE, + KW_WHILE, +}; +#define LAST_KEYWORD KW_WHILE + +typedef struct proc_token_s { + enum proc_token_e { + PTOK_INVALID = 0, + PTOK_IDENT, + PTOK_KEYWORD, + PTOK_NUM, + PTOK_STRING, + PTOK_SYM, + PTOK_PRAGMA, + PTOK_EOF + } tokt; + union proc_token_val_u { + string_t *str; + struct { + string_t *sstr; // The string literal content + int sisstr; // 0 for '' or <>, 1 for "" + }; + char c; + enum token_sym_type_e sym; + enum token_keyword_type_e kw; + struct { + enum proc_pragma_e { + PRAGMA_ALLOW_INTS, + PRAGMA_MARK_SIMPLE, + } typ; + string_t *val; + } pragma; + } tokv; +} proc_token_t; +VECTOR_DECLARE(proc, proc_token_t) +void proc_token_del(proc_token_t *tok); + +typedef struct num_constant_s { + enum num_constant_e { + NCT_FLOAT, + NCT_DOUBLE, + NCT_LDOUBLE, + NCT_INT32, + NCT_UINT32, + NCT_INT64, + NCT_UINT64, + } typ; + union { + float f; + double d; + long double l; + int32_t i32; + uint32_t u32; + int64_t i64; + uint64_t u64; + } val; +} num_constant_t; +int num_constant_convert(string_t *str, num_constant_t *cst); +KHASH_MAP_DECLARE_STR(const_map, num_constant_t) + +typedef struct expr_s { + enum expr_type_e { + ETY_VAR, + ETY_CONST, + // ETY_GENERIC, + ETY_CALL, + ETY_ACCESS, + ETY_PTRACCESS, // Convertible to DEREF + ACCESS + ETY_UNARY, + ETY_BINARY, + ETY_TERNARY, + // ETY_INIT_LIST, + ETY_CAST, + } typ; + union { + string_t *var; + num_constant_t cst; + // TODO: _Generic + struct { + struct expr_s *fun, **args; + size_t nargs; + } call; + struct { + struct expr_s *val; + string_t *member; + } access; + struct { + enum unary_op_e { + UOT_POSTINCR, + UOT_POSTDECR, + UOT_PREINCR, + UOT_PREDECR, + UOT_REF, + UOT_POS, + UOT_NEG, + UOT_DEREF, + UOT_ANOT, // Arithmetic not, ie '~' + UOT_BNOT, // Boolean not, ie '!' + } typ; + struct expr_s *e; + } unary; + struct { + enum binary_op_e { + BOT_ADD, + BOT_SUB, + BOT_MUL, + BOT_DIV, + BOT_MOD, + BOT_LSH, + BOT_RSH, + BOT_LT, + BOT_GT, + BOT_LE, + BOT_GE, + BOT_EQ, + BOT_NE, + BOT_AAND, + BOT_AXOR, + BOT_AOR, + BOT_BAND, + BOT_BOR, + BOT_ASSGN_EQ, + BOT_ASSGN_ADD, + BOT_ASSGN_SUB, + BOT_ASSGN_MUL, + BOT_ASSGN_DIV, + BOT_ASSGN_MOD, + BOT_ASSGN_LSH, + BOT_ASSGN_RSH, + BOT_ASSGN_AAND, + BOT_ASSGN_AXOR, + BOT_ASSGN_AOR, + BOT_COMMA, + + BOT_ARRAY, // Convertible to DEREF + ADD + } typ; + struct expr_s *e1, *e2; + } binary; + struct { + enum ternary_op_e { + TOT_COND, + } typ; + struct expr_s *e1, *e2, *e3; + } ternary; + // TODO: (type){init} + struct { + struct type_s *typ; + struct expr_s *e; + } cast; + } val; +} expr_t; +void expr_del(expr_t *e); + +typedef struct size_info_s { + size_t size, align; +} size_info_t; + +typedef struct type_s { + struct { + unsigned is_atomic : 1; + unsigned is_const : 1; + unsigned is_restrict : 1; + unsigned is_volatile : 1; + unsigned is_incomplete : 1; // \ The type needs to be complete and + unsigned is_validated : 1; // / validated for the size_info to be populated + unsigned _internal_use : 1; + }; + size_t nrefs; + enum type_type_e { + TYPE_BUILTIN, // builtin + TYPE_ARRAY, // array + TYPE_STRUCT_UNION, // st + TYPE_ENUM, // typ which points to TYPE_BUILTIN + TYPE_PTR, // typ + TYPE_FUNCTION, // fun + } typ; + union { + enum type_builtin_e { + BTT_VOID, + BTT_BOOL, + BTT_CHAR, + BTT_SCHAR, + BTT_UCHAR, + BTT_SHORT, + BTT_SSHORT, + BTT_USHORT, + BTT_INT, + BTT_SINT, + BTT_UINT, + BTT_LONG, + BTT_SLONG, + BTT_ULONG, + BTT_LONGLONG, + BTT_SLONGLONG, + BTT_ULONGLONG, + BTT_INT128, + BTT_SINT128, + BTT_UINT128, + BTT_S8, + BTT_U8, + BTT_S16, + BTT_U16, + BTT_S32, + BTT_U32, + BTT_S64, + BTT_U64, +#define BTT_START_INT_EXT BTT_S8 +#define BTT_INT_EXTS "__int8_t", "__uint8_t", "__int16_t", "__uint16_t", "__int32_t", "__uint32_t", "__int64_t", "__uint64_t" + BTT_FLOAT, + BTT_CFLOAT, + BTT_IFLOAT, + BTT_DOUBLE, + BTT_CDOUBLE, + BTT_IDOUBLE, + BTT_LONGDOUBLE, + BTT_CLONGDOUBLE, + BTT_ILONGDOUBLE, + BTT_VA_LIST, + } builtin; +#define LAST_BUILTIN BTT_VA_LIST + struct type_s *typ; + struct { + struct type_s *typ; + size_t array_sz; // -1 for VLA + } array; + struct struct_s *st; + struct { + struct type_s *ret; + size_t nargs; // -1 for no specification + struct type_s **args; + int has_varargs; + } fun; + } val; + size_info_t szinfo; +} type_t; +void type_del(type_t *typ); +KHASH_MAP_DECLARE_STR(type_map, type_t*) +void type_map_del(khash_t(type_map) *map); + +int type_t_equal(type_t*, type_t*); + +typedef struct st_member_s { + string_t *name; // May be NULL + type_t *typ; + _Bool is_bitfield; + size_t bitfield_width; +} st_member_t; +typedef struct struct_s { + string_t *tag; + int is_defined; + size_t nrefs; + int is_struct; // 0 = union, 1 = struct + int has_incomplete; // 1 if the last element of the structure is a VLA or if an element of the union recursively contains a VLA + int explicit_simple; + size_t nmembers; + st_member_t *members; +} struct_t; +void st_member_del(st_member_t *member); +void struct_del(struct_t *st); +KHASH_MAP_DECLARE_STR(struct_map, struct_t*) + +type_t *type_new(void); // Create a new (complete) builtin type +type_t *type_new_ptr(type_t *target); // Create a new pointer type; doesn't increment the use counter of the target +// type_t *type_do_copy(type_t *ref); // Always duplicate ref; decrements the use counter +// type_t *type_do_copy_nodec(const type_t *ref); // Always duplicate ref; doesn't decrements the use counter +// type_t *type_maybe_copy(type_t *ref); // Only duplicate ref if it is used elsewhere; in that case, decrements the use counter +int type_copy_into(type_t *dest, const type_t *ref); // Copy ref into dest, keeping additional qualifiers and without changing any use counter + +struct_t *struct_new(int is_struct, string_t *tag); // Create a new struct + +// Try to merge some types with other types; this may delete ptr and increase a use counter in a type referenced by the table +KHASH_DECLARE(type_set, type_t*, char) +type_t *type_try_merge(type_t *ptr, khash_t(type_set) *set); + +extern const char *builtin2str[LAST_BUILTIN + 1]; +void type_print(type_t *typ); +void struct_print(const struct_t *st); + +typedef struct file_s { + khash_t(struct_map) *struct_map; + khash_t(type_map) *type_map; + khash_t(type_map) *enum_map; + khash_t(type_map) *decl_map; + type_t *builtins[LAST_BUILTIN + 1]; + khash_t(const_map) *const_map; + khash_t(type_set) *type_set; +} file_t; +file_t *file_new(void); +void file_del(file_t *f); + +extern const char *sym2str[LAST_SYM + 1]; +extern const char *kw2str[LAST_KEYWORD + 1]; +void preproc_token_print(const preproc_token_t *tok); +int preproc_token_isend(const preproc_token_t *tok); +void proc_token_print(const proc_token_t *tok); +int proc_token_iserror(const proc_token_t *tok); +int proc_token_isend(const proc_token_t *tok); + +KHASH_MAP_DECLARE_STR(str2kw, enum token_keyword_type_e) +extern khash_t(str2kw) *str2kw; +int init_str2kw(void); +void del_str2kw(void); + +#endif // LANG_H |