X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fparser.h;h=c9e9f752bb8f8747693229f4b79751f68f7aa1fa;hp=41741c0152abdd2e51c9672573f67e9ab195b4f7;hb=98d971f89db2431ef24dac508cf9797ef93646c6;hpb=1c837573a87e0d375768e990a28d1b2706dbaf43 diff --git a/src/parser.h b/src/parser.h index 41741c0..c9e9f75 100644 --- a/src/parser.h +++ b/src/parser.h @@ -7,6 +7,7 @@ #include #include +#include /* fcall */ #include "parser_proc.h" @@ -27,6 +28,13 @@ typedef struct PSI_Token { char buf[1]; } PSI_Token; +static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); + +typedef struct zend_fcall { + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} zend_fcall; + typedef union impl_val { char cval; int8_t i8; @@ -49,9 +57,9 @@ typedef union impl_val { zend_bool bval; zend_long lval; zend_string *str; + zend_fcall *cb; } zend; void *ptr; - uint8_t _dbg[sizeof(void *)]; } impl_val; typedef struct decl_type { @@ -60,6 +68,7 @@ typedef struct decl_type { token_t type; struct decl_type *real; struct decl_struct *strct; + struct decl_union *unn; struct decl_enum *enm; struct decl *func; } decl_type; @@ -78,60 +87,18 @@ static inline decl_type *real_decl_type(decl_type *type) { return type; } +static inline void free_decl(struct decl *decl); static inline void free_decl_type(decl_type *type) { if (type->token) { free(type->token); } + if (type->type == PSI_T_FUNCTION) { + free_decl(type->func); + } free(type->name); free(type); } -typedef struct decl_typedef { - PSI_Token *token; - char *alias; - decl_type *type; -} decl_typedef; - -static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) { - decl_typedef *t = calloc(1, sizeof(*t)); - t->alias = strdup(name); - t->type = type; - return t; -} - -static inline void free_decl_typedef(decl_typedef *t) { - if (t->token) { - free(t->token); - } - free(t->alias); - free_decl_type(t->type); - free(t); -} - -typedef struct decl_typedefs { - size_t count; - decl_typedef **list; -} decl_typedefs; - -static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) { - if (!defs) { - defs = calloc(1, sizeof(*defs)); - } - defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); - defs->list[defs->count-1] = def; - return defs; -} - -static void free_decl_typedefs(decl_typedefs *defs) { - size_t i; - - for (i = 0; i < defs->count; ++i) { - free_decl_typedef(defs->list[i]); - } - free(defs->list); - free(defs); -} - typedef struct decl_var { PSI_Token *token; char *name; @@ -148,6 +115,17 @@ static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as return v; } +static inline decl_var *copy_decl_var(decl_var *src) { + decl_var *dest = calloc(1, sizeof(*dest)); + + memcpy(dest, src, sizeof(*dest)); + dest->name = strdup(dest->name); + if (dest->token) { + dest->token = PSI_TokenCopy(dest->token); + } + return dest; +} + static inline void free_decl_var(decl_var *var) { if (var->token) { free(var->token); @@ -178,9 +156,9 @@ typedef struct decl_arg { decl_type *type; decl_var *var; decl_struct_layout *layout; - struct let_stmt *let; impl_val val; void *ptr; + void *let; void *mem; } decl_arg; @@ -191,10 +169,14 @@ static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) { arg->var = var; var->arg = arg; arg->ptr = &arg->val; + arg->let = arg->ptr; return arg; } static inline void free_decl_arg(decl_arg *arg) { + if (arg->token && arg->token != arg->var->token) { + free(arg->token); + } free_decl_type(arg->type); free_decl_var(arg->var); if (arg->layout) { @@ -203,6 +185,30 @@ static inline void free_decl_arg(decl_arg *arg) { free(arg); } +typedef struct decl_typedefs { + size_t count; + decl_arg **list; +} decl_typedefs; + +static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) { + if (!defs) { + defs = calloc(1, sizeof(*defs)); + } + defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); + defs->list[defs->count-1] = def; + return defs; +} + +static void free_decl_typedefs(decl_typedefs *defs) { + size_t i; + + for (i = 0; i < defs->count; ++i) { + free_decl_arg(defs->list[i]); + } + free(defs->list); + free(defs); +} + typedef struct decl_vars { decl_var **vars; size_t count; @@ -348,6 +354,7 @@ typedef struct decl_struct { char *name; decl_args *args; size_t size; + size_t align; struct { void *type; void (*dtor)(void *type); @@ -399,6 +406,56 @@ static inline void free_decl_structs(decl_structs *ss) { free(ss); } +typedef struct decl_union { + PSI_Token *token; + char *name; + decl_args *args; + size_t size; + size_t align; +} decl_union; + +static inline decl_union *init_decl_union(const char *name, decl_args *args) { + decl_union *u = calloc(1, sizeof(*u)); + u->name = strdup(name); + u->args = args; + return u; +} + +static inline void free_decl_union(decl_union *u) { + if (u->token) { + free(u->token); + } + if (u->args) { + free_decl_args(u->args); + } + free(u->name); + free(u); +} + +typedef struct decl_unions { + decl_union **list; + size_t count; +} decl_unions; + +static inline decl_unions *add_decl_union(decl_unions *uu, decl_union *u) { + if (!uu) { + uu = calloc(1, sizeof(*uu)); + } + uu->list = realloc(uu->list, ++uu->count * sizeof(*uu->list)); + uu->list[uu->count-1] = u; + return uu; +} + +static inline void free_decl_unions(decl_unions *uu) { + size_t i; + + for (i = 0; i < uu->count; ++i) { + free_decl_union(uu->list[i]); + } + free(uu->list); + free(uu); +} + typedef struct impl_type { char *name; token_t type; @@ -420,6 +477,7 @@ static inline void free_impl_type(impl_type *type) { typedef struct impl_var { PSI_Token *token; char *name; + struct impl_arg *arg; unsigned reference:1; } impl_var; @@ -430,6 +488,17 @@ static inline impl_var *init_impl_var(const char *name, int is_reference) { return var; } +static inline impl_var *copy_impl_var(impl_var *var) { + impl_var *cpy = malloc(sizeof(*cpy)); + + memcpy(cpy, var, sizeof(*cpy)); + cpy->name = strdup(cpy->name); + if (cpy->token) { + cpy->token = PSI_TokenCopy(cpy->token); + } + return cpy; +} + static inline void free_impl_var(impl_var *var) { if (var->token) { free(var->token); @@ -529,6 +598,7 @@ static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_v impl_arg *arg = calloc(1, sizeof(*arg)); arg->type = type; arg->var = var; + arg->var->arg = arg; arg->def = def; return arg; } @@ -641,7 +711,6 @@ static inline num_exp *init_num_exp(token_t t, void *num) { return exp; } -static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); static inline num_exp *copy_num_exp(num_exp *exp) { decl_var *dvar; num_exp *num = calloc(1, sizeof(*num)); @@ -828,11 +897,35 @@ static inline void free_let_calloc(let_calloc *alloc) { free(alloc); } +typedef struct let_callback { + struct let_func *func; + struct set_values *args; + decl *decl; +} let_callback; + +static inline void free_let_func(struct let_func *func); +static inline void free_set_values(struct set_values *vals); +static inline let_callback *init_let_callback(struct let_func *func, struct set_values *args) { + let_callback *cb = calloc(1, sizeof(*cb)); + + cb->func = func; + cb->args = args; + return cb; +} + +static inline void free_let_callback(let_callback *cb) { + free_let_func(cb->func); + free_set_values(cb->args); + free(cb); +} + +typedef impl_val *(*let_func_handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free); + typedef struct let_func { token_t type; char *name; impl_var *var; - impl_arg *arg; + let_func_handler handler; } let_func; static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) { @@ -855,12 +948,14 @@ typedef struct let_val { PSI_LET_NULL, PSI_LET_NUMEXP, PSI_LET_CALLOC, + PSI_LET_CALLBACK, PSI_LET_FUNC, PSI_LET_TMP, } kind; union { num_exp *num; let_calloc *alloc; + let_callback *callback; let_func *func; decl_var *var; } data; @@ -883,6 +978,9 @@ static inline let_val *init_let_val(enum let_val_kind kind, void *data) { case PSI_LET_CALLOC: let->data.alloc = data; break; + case PSI_LET_CALLBACK: + let->data.callback = data; + break; case PSI_LET_FUNC: let->data.func = data; break; @@ -904,6 +1002,9 @@ static inline void free_let_val(let_val *let) { case PSI_LET_CALLOC: free_let_calloc(let->data.alloc); break; + case PSI_LET_CALLBACK: + free_let_callback(let->data.callback); + break; case PSI_LET_FUNC: free_let_func(let->data.func); break; @@ -918,8 +1019,6 @@ static inline void free_let_val(let_val *let) { typedef struct let_stmt { decl_var *var; let_val *val; - - void *ptr; } let_stmt; static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) { @@ -972,19 +1071,25 @@ typedef struct set_value { struct set_value *set; impl_val *val; } outer; - struct set_value **inner; - size_t count; + struct set_values *inner; } set_value; +typedef struct set_values { + set_value **vals; + size_t count; +} set_values; + + static inline set_value *init_set_value(set_func *func, decl_vars *vars) { set_value *val = calloc(1, sizeof(*val)); val->func = func; val->vars = vars; return val; } + +static inline set_values *add_set_value(set_values *vals, set_value *val); static inline set_value *add_inner_set_value(set_value *val, set_value *inner) { - val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner)); - val->inner[val->count-1] = inner; + val->inner = add_set_value(val->inner, inner); inner->outer.set = val; return val; } @@ -997,11 +1102,7 @@ static inline void free_set_value(set_value *val) { free_decl_vars(val->vars); } if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) { - size_t i; - for (i = 0; i < val->count; ++i) { - free_set_value(val->inner[i]); - } - free(val->inner); + free_set_values(val->inner); } if (val->num) { free_num_exp(val->num); @@ -1009,6 +1110,37 @@ static inline void free_set_value(set_value *val) { free(val); } +static inline set_values *init_set_values(set_value *val) { + set_values *vals = calloc(1, sizeof(*vals)); + if (val) { + vals->count = 1; + vals->vals = calloc(1, sizeof(val)); + vals->vals[0] = val; + } + return vals; +} + +static inline set_values *add_set_value(set_values *vals, set_value *val) { + if (!vals) { + vals = calloc(1, sizeof(*vals)); + } + vals->vals = realloc(vals->vals, ++vals->count * sizeof(val)); + vals->vals[vals->count-1] = val; + return vals; +} + +static inline void free_set_values(set_values *vals) { + if (vals->vals) { + size_t i; + + for (i = 0; i < vals->count; ++i) { + free_set_value(vals->vals[i]); + } + free(vals->vals); + } + free(vals); +} + typedef struct set_stmt { impl_var *var; set_value *val; @@ -1360,13 +1492,14 @@ static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_pt #define PSI_ERROR 16 #define PSI_WARNING 32 -typedef void (*psi_error_cb)(PSI_Token *token, int type, const char *msg, ...); +typedef void (*psi_error_cb)(void *context, PSI_Token *token, int type, const char *msg, ...); #define PSI_DATA(D) ((PSI_Data *) (D)) #define PSI_DATA_MEMBERS \ constants *consts; \ decl_typedefs *defs; \ decl_structs *structs; \ + decl_unions *unions; \ decl_enums *enums; \ decls *decls; \ impls *impls; \ @@ -1374,7 +1507,9 @@ typedef void (*psi_error_cb)(PSI_Token *token, int type, const char *msg, ...); decl_file file; \ decl_libs libs; \ } psi; \ - psi_error_cb error + psi_error_cb error; \ + unsigned errors; \ + unsigned flags typedef struct PSI_Data { PSI_DATA_MEMBERS; } PSI_Data; @@ -1398,6 +1533,9 @@ static inline void PSI_DataDtor(PSI_Data *data) { if (data->structs) { free_decl_structs(data->structs); } + if (data->unions) { + free_decl_unions(data->unions); + } if (data->enums) { free_decl_enums(data->enums); } @@ -1415,7 +1553,7 @@ typedef struct PSI_Parser { FILE *fp; token_t num; void *proc; - unsigned flags, errors, line, col; + unsigned line, col; char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE]; } PSI_Parser; @@ -1511,6 +1649,7 @@ static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) { return T; } +char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen); static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) { php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to))); return T; @@ -1546,6 +1685,7 @@ static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) { } #define PSI_PARSER_DEBUG 0x1 +#define PSI_PARSER_SILENT 0x2 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags); void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);