X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fparser.h;h=ce74067db65a94d4ba3f6c9f458a1fda5a3504b8;hp=2aaab31985ead22727f3d1f4ab3dd67cf2de3690;hb=7e5e4c6d2b654cfd3737c37e9e1894be43642721;hpb=3bca631112f4865510ea91c85e8c820c4465fc14 diff --git a/src/parser.h b/src/parser.h index 2aaab31..ce74067 100644 --- a/src/parser.h +++ b/src/parser.h @@ -35,6 +35,13 @@ static inline decl_type *init_decl_type(token_t type, char *name) { return t; } +static inline decl_type *real_decl_type(decl_type *type) { + while (type->real) { + type = type->real; + } + return type; +} + static inline void free_decl_type(decl_type *type) { free(type->name); free(type); @@ -85,6 +92,7 @@ static void free_decl_typedefs(decl_typedefs *defs) { typedef struct decl_var { char *name; unsigned pointer_level; + struct decl_arg *arg; } decl_var; static inline decl_var *init_decl_var(char *name, unsigned pl) { @@ -102,12 +110,14 @@ static inline void free_decl_var(decl_var *var) { typedef struct decl_arg { decl_type *type; decl_var *var; + struct let_stmt *let; } decl_arg; static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) { decl_arg *arg = malloc(sizeof(*arg)); arg->type = type; arg->var = var; + arg->let = NULL; return arg; } @@ -236,6 +246,26 @@ static inline void free_decls(decls *decls) { free(decls); } +typedef union impl_val { + unsigned char bval; + char cval; + short sval; + int ival; + double dval; + zend_long lval; + zend_string *str; + void *ptr; +} impl_val; + +static inline impl_val *deref_impl_val(unsigned level, impl_val *ret_val, decl_arg *darg) { + unsigned i; + + for (i = level; i < darg->var->pointer_level && ret_val->ptr; ++i) { + ret_val = *(void **)ret_val; + } + return ret_val; +} + typedef struct impl_type { char *name; token_t type; @@ -292,15 +322,8 @@ typedef struct impl_arg { impl_type *type; impl_var *var; impl_def_val *def; - union { - unsigned char bval; - zend_long lval; - double dval; - struct { - char *val; - size_t len; - } str; - } val; + impl_val val; + zval *_zv; } impl_arg; static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) { @@ -358,13 +381,15 @@ typedef struct impl_func { char *name; impl_args *args; impl_type *return_type; + unsigned return_reference:1; } impl_func; -static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type) { +static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) { impl_func *func = malloc(sizeof(*func)); func->name = strdup(name); func->args = args ? args : init_impl_args(NULL); func->return_type = type; + func->return_reference = ret_reference; return func; } @@ -395,12 +420,12 @@ static inline void free_let_func(let_func *func) { typedef struct let_value { let_func *func; impl_var *var; - unsigned null_pointer_ref:1; + unsigned is_reference:1; } let_value; -static inline let_value *init_let_value(let_func *func, impl_var *var, int null_pointer_ref) { +static inline let_value *init_let_value(let_func *func, impl_var *var, int is_reference) { let_value *val = malloc(sizeof(*val)); - val->null_pointer_ref = null_pointer_ref; + val->is_reference = is_reference; val->func = func; val->var = var; return val; @@ -419,10 +444,14 @@ static inline void free_let_value(let_value *val) { typedef struct let_stmt { decl_var *var; let_value *val; + impl_arg *arg; + impl_val out; + void *ptr; + void *mem; } let_stmt; static inline let_stmt *init_let_stmt(decl_var *var, let_value *val) { - let_stmt *let = malloc(sizeof(*let)); + let_stmt *let = calloc(1, sizeof(*let)); let->var = var; let->val = val; return let; @@ -472,6 +501,7 @@ static inline void free_set_value(set_value *val) { typedef struct set_stmt { impl_var *var; set_value *val; + impl_arg *arg; } set_stmt; static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) { @@ -487,30 +517,46 @@ static inline void free_set_stmt(set_stmt *set) { free(set); } -typedef struct ret_stmt { +typedef struct return_stmt { set_func *func; decl_var *decl; -} ret_stmt; +} return_stmt; -static inline ret_stmt *init_ret_stmt(set_func *func, decl_var *decl) { - ret_stmt *ret = malloc(sizeof(*ret)); +static inline return_stmt *init_return_stmt(set_func *func, decl_var *decl) { + return_stmt *ret = malloc(sizeof(*ret)); ret->func = func; ret->decl = decl; return ret; } -static inline void free_ret_stmt(ret_stmt *ret) { +static inline void free_return_stmt(return_stmt *ret) { free_set_func(ret->func); free_decl_var(ret->decl); free(ret); } +typedef struct free_stmt { + decl_vars *vars; +} free_stmt; + +static inline free_stmt *init_free_stmt(decl_vars *vars) { + free_stmt *free_ = malloc(sizeof(*free_)); + free_->vars = vars; + return free_; +} + +static inline void free_free_stmt(free_stmt *free_) { + free_decl_vars(free_->vars); + free(free_); +} + typedef struct impl_stmt { token_t type; union { let_stmt *let; set_stmt *set; - ret_stmt *ret; + return_stmt *ret; + free_stmt *fre; void *ptr; } s; } impl_stmt; @@ -530,8 +576,11 @@ static inline void free_impl_stmt(impl_stmt *stmt) { case PSI_T_SET: free_set_stmt(stmt->s.set); break; - case PSI_T_RET: - free_ret_stmt(stmt->s.ret); + case PSI_T_RETURN: + free_return_stmt(stmt->s.ret); + break; + case PSI_T_FREE: + free_free_stmt(stmt->s.fre); break; } free(stmt); @@ -539,7 +588,7 @@ static inline void free_impl_stmt(impl_stmt *stmt) { typedef struct impl_stmts { struct { - ret_stmt **list; + return_stmt **list; size_t count; } ret; struct { @@ -550,6 +599,10 @@ typedef struct impl_stmts { set_stmt **list; size_t count; } set; + struct { + free_stmt **list; + size_t count; + } fre; } impl_stmts; static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) { @@ -560,7 +613,7 @@ static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) { static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) { switch (stmt->type) { - case PSI_T_RET: + case PSI_T_RETURN: stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret); break; case PSI_T_LET: @@ -569,7 +622,11 @@ static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) { case PSI_T_SET: stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set); break; + case PSI_T_FREE: + stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre); + break; } + free(stmt); return stmts; } @@ -586,13 +643,17 @@ static inline void free_impl_stmts(impl_stmts *stmts) { } free(stmts->let.list); for (i = 0; i < stmts->ret.count; ++i) { - free_ret_stmt(stmts->ret.list[i]); + free_return_stmt(stmts->ret.list[i]); } free(stmts->ret.list); for (i = 0; i < stmts->set.count; ++i) { free_set_stmt(stmts->set.list[i]); } free(stmts->set.list); + for (i = 0; i < stmts->fre.count; ++i) { + free_free_stmt(stmts->fre.list[i]); + } + free(stmts->fre.list); free(stmts); } @@ -639,12 +700,82 @@ static void free_impls(impls *impls) { free(impls); } +typedef struct const_type { + token_t type; + char *name; +} const_type; + +static inline const_type *init_const_type(token_t type, const char *name) { + const_type *ct = malloc(sizeof(*ct)); + ct->type = type; + ct->name = strdup(name); + return ct; +} + +static inline void free_const_type(const_type *type) { + free(type->name); + free(type); +} + +typedef struct constant { + const_type *type; + char *name; + impl_def_val *val; +} constant; + +static inline constant *init_constant(const_type *type, char *name, impl_def_val *val) { + constant *c = malloc(sizeof(*c)); + c->type = type; + c->name = strdup(name); + c->val = val; + return c; +} + +static inline void free_constant(constant *constant) { + free_const_type(constant->type); + free(constant->name); + free_impl_def_val(constant->val); + free(constant); +} + +typedef struct constants { + size_t count; + constant **list; +} constants; + +static inline constants *add_constant(constants *constants, constant *constant) { + if (!constants) { + constants = calloc(1, sizeof(*constants)); + } + constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list)); + constants->list[constants->count-1] = constant; + return constants; +} + +static inline void free_constants(constants *c) { + size_t i; + + for (i = 0; i < c->count; ++i) { + free_constant(c->list[i]); + } + free(c->list); + free(c); +} + +#define PSI_ERROR 16 +#define PSI_WARNING 32 +typedef void (*psi_error_cb)(int type, const char *msg, ...); + +#define PSI_DATA_MEMBERS \ + constants *consts; \ + decl_typedefs *defs; \ + decls *decls; \ + impls *impls; \ + char *lib; \ + char *fn; \ + psi_error_cb error typedef struct PSI_Data { - decl_typedefs *defs; - decls *decls; - impls *impls; - char *lib; - char *fn; + PSI_DATA_MEMBERS; } PSI_Data; static inline void PSI_DataExchange(PSI_Data *dest, PSI_Data *src) { @@ -653,6 +784,9 @@ static inline void PSI_DataExchange(PSI_Data *dest, PSI_Data *src) { } static inline void PSI_DataDtor(PSI_Data *data) { + if (data->consts) { + free_constants(data->consts); + } if (data->defs) { free_decl_typedefs(data->defs); } @@ -671,11 +805,7 @@ static inline void PSI_DataDtor(PSI_Data *data) { } typedef struct PSI_Parser { - decl_typedefs *defs; - decls *decls; - impls *impls; - char *lib; - char *fn; + PSI_DATA_MEMBERS; FILE *fp; unsigned flags; unsigned errors; @@ -707,7 +837,7 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) { #define PSI_PARSER_DEBUG 0x1 -PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, unsigned flags); +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, ...); size_t PSI_ParserFill(PSI_Parser *P, size_t n); token_t PSI_ParserScan(PSI_Parser *P);