made the real decl_type a union
[m6w6/ext-psi] / src / parser.h
index 3a00d6d766a5d75dea7a20fb7380c2aa2aae36c1..105e974a32efd407f777c734ca39d6e4711e6d1c 100644 (file)
@@ -60,18 +60,19 @@ typedef union impl_val {
                zend_fcall *cb;
        } zend;
        void *ptr;
-       uint8_t _dbg[sizeof(void *)];
 } impl_val;
 
 typedef struct decl_type {
        PSI_Token *token;
        char *name;
        token_t type;
-       struct decl_type *real;
-       struct decl_struct *strct;
-       struct decl_union *unn;
-       struct decl_enum *enm;
-       struct decl *func;
+       union {
+               struct decl_arg *def;
+               struct decl_struct *strct;
+               struct decl_union *unn;
+               struct decl_enum *enm;
+               struct decl *func;
+       } real;
 } decl_type;
 
 static inline decl_type *init_decl_type(token_t type, const char *name) {
@@ -81,11 +82,17 @@ static inline decl_type *init_decl_type(token_t type, const char *name) {
        return t;
 }
 
-static inline decl_type *real_decl_type(decl_type *type) {
-       while (type->real) {
-               type = type->real;
+static inline int weak_decl_type(decl_type *type) {
+       switch (type->type) {
+       case PSI_T_CHAR:
+       case PSI_T_SHORT:
+       case PSI_T_INT:
+       case PSI_T_LONG:
+       case PSI_T_NAME:
+               return type->type;
+       default:
+               return 0;
        }
-       return type;
 }
 
 static inline void free_decl(struct decl *decl);
@@ -94,7 +101,7 @@ static inline void free_decl_type(decl_type *type) {
                free(type->token);
        }
        if (type->type == PSI_T_FUNCTION) {
-               free_decl(type->func);
+               free_decl(type->real.func);
        }
        free(type->name);
        free(type);
@@ -157,9 +164,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;
 
@@ -170,6 +177,7 @@ 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;
 }
 
@@ -185,6 +193,13 @@ static inline void free_decl_arg(decl_arg *arg) {
        free(arg);
 }
 
+static inline decl_type *real_decl_type(decl_type *type) {
+       while (weak_decl_type(type)) {
+               type = type->real.def->type;
+       }
+       return type;
+}
+
 typedef struct decl_typedefs {
        size_t count;
        decl_arg **list;
@@ -297,10 +312,6 @@ typedef struct decl_callinfo {
        size_t argc;
        void **args;
        void **rval;
-       struct {
-               void *data;
-               void (*dtor)(void *data);
-       } closure;
 } decl_callinfo;
 
 typedef struct decl {
@@ -481,6 +492,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;
 
@@ -601,6 +613,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;
 }
@@ -902,6 +915,7 @@ static inline void free_let_calloc(let_calloc *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);
@@ -920,11 +934,13 @@ static inline void free_let_callback(let_callback *cb) {
        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) {
@@ -1018,8 +1034,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) {
@@ -1087,9 +1101,10 @@ static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
        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->vals = realloc(val->inner->vals, ++val->inner->count * sizeof(*val->inner->vals));
-       val->inner->vals[val->inner->count-1] = inner;
+       val->inner = add_set_value(val->inner, inner);
        inner->outer.set = val;
        return val;
 }
@@ -1102,11 +1117,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->inner->count; ++i) {
-                       free_set_value(val->inner->vals[i]);
-               }
-               free(val->inner->vals);
+               free_set_values(val->inner);
        }
        if (val->num) {
                free_num_exp(val->num);
@@ -1125,6 +1136,9 @@ static inline set_values *init_set_values(set_value *val) {
 }
 
 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;
@@ -1132,6 +1146,11 @@ static inline set_values *add_set_value(set_values *vals, set_value *val) {
 
 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);