api refactoring
authorMichael Wallner <mike@php.net>
Thu, 25 Aug 2016 10:19:01 +0000 (12:19 +0200)
committerMichael Wallner <mike@php.net>
Thu, 25 Aug 2016 10:19:01 +0000 (12:19 +0200)
73 files changed:
Makefile.frag
config.m4
php_psi.h
src/context.c
src/context.h
src/context_dump.c
src/context_validate.c
src/data.c [new file with mode: 0644]
src/data.h [new file with mode: 0644]
src/engine.c
src/engine.h
src/libffi.c
src/libffi.h
src/libjit.c
src/libjit.h
src/module.c
src/parser.h
src/parser.re
src/parser_def.h
src/parser_proc.inc
src/parser_proc.y
src/token.c [new file with mode: 0644]
src/token.h [new file with mode: 0644]
src/types.h [new file with mode: 0644]
src/types/const_type.h [new file with mode: 0644]
src/types/constant.h [new file with mode: 0644]
src/types/constants.h [new file with mode: 0644]
src/types/decl.h [new file with mode: 0644]
src/types/decl_abi.h [new file with mode: 0644]
src/types/decl_arg.h [new file with mode: 0644]
src/types/decl_args.h [new file with mode: 0644]
src/types/decl_callinfo.h [new file with mode: 0644]
src/types/decl_enum.h [new file with mode: 0644]
src/types/decl_enum_item.h [new file with mode: 0644]
src/types/decl_enum_items.h [new file with mode: 0644]
src/types/decl_enums.h [new file with mode: 0644]
src/types/decl_file.h [new file with mode: 0644]
src/types/decl_libs.h [new file with mode: 0644]
src/types/decl_struct.h [new file with mode: 0644]
src/types/decl_struct_layout.h [new file with mode: 0644]
src/types/decl_structs.h [new file with mode: 0644]
src/types/decl_type.h [new file with mode: 0644]
src/types/decl_typedefs.h [new file with mode: 0644]
src/types/decl_union.h [new file with mode: 0644]
src/types/decl_unions.h [new file with mode: 0644]
src/types/decl_var.h [new file with mode: 0644]
src/types/decl_vars.h [new file with mode: 0644]
src/types/decls.h [new file with mode: 0644]
src/types/free_call.h [new file with mode: 0644]
src/types/free_calls.h [new file with mode: 0644]
src/types/free_stmt.h [new file with mode: 0644]
src/types/impl.h [new file with mode: 0644]
src/types/impl_arg.h [new file with mode: 0644]
src/types/impl_args.h [new file with mode: 0644]
src/types/impl_def_val.h [new file with mode: 0644]
src/types/impl_func.h [new file with mode: 0644]
src/types/impl_stmt.h [new file with mode: 0644]
src/types/impl_stmts.h [new file with mode: 0644]
src/types/impl_type.h [new file with mode: 0644]
src/types/impl_val.h [new file with mode: 0644]
src/types/impl_var.h [new file with mode: 0644]
src/types/impls.h [new file with mode: 0644]
src/types/let_callback.h [new file with mode: 0644]
src/types/let_calloc.h [new file with mode: 0644]
src/types/let_func.h [new file with mode: 0644]
src/types/let_stmt.h [new file with mode: 0644]
src/types/let_val.h [new file with mode: 0644]
src/types/num_exp.h [new file with mode: 0644]
src/types/return_stmt.h [new file with mode: 0644]
src/types/set_func.h [new file with mode: 0644]
src/types/set_stmt.h [new file with mode: 0644]
src/types/set_value.h [new file with mode: 0644]
src/types/set_values.h [new file with mode: 0644]

index 6bb4061..bcdaa40 100644 (file)
@@ -7,7 +7,7 @@ $(PHP_PSI_BUILDDIR)/%.h: $(PHP_PSI_SRCDIR)/src/%.h
        @cat >$@ <$<
 
 install-headers: psi-build-headers
-clean: psi-clean-headers
+clean: psi-clean
 
 .PHONY: psi-build-headers
 psi-build-headers: $(PHP_PSI_HEADERS)
@@ -16,6 +16,19 @@ psi-build-headers: $(PHP_PSI_HEADERS)
 psi-clean-headers:
        -rm -f $(PHP_PSI_HEADERS)
 
+.PHONY: psi-clean-sources
+psi-clean-sources:
+       -rm -f $(PHP_PSI_BUILDDIR)/src/*o
+       -rm -f $(PHP_PSI_SRCDIR)/src/parser.c $(PHP_PSI_SRCDIR)/src/parser_proc.c $(PHP_PSI_SRCDIR)/src/parser_proc.y
+
+.PHONY: psi-clean-aux
+psi-clean-aux:
+       -rm -f lempar.c lemon.c lemon
+
+.PHONY: psi-clean
+psi-clean: psi-clean-headers psi-clean-sources psi-clean-aux
+       
+               
 lempar.c:
        curl -sSo $@ "http://www.sqlite.org/src/raw/tool/lempar.c?name=3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7"
 
@@ -27,15 +40,14 @@ lemon.c:
 
 $(PHP_PSI_SRCDIR)/src/parser_proc.h: $(PHP_PSI_SRCDIR)/src/parser_proc.c
 
-$(PHP_PSI_SRCDIR)/src/%.c: $(PHP_PSI_SRCDIR)/src/parser.h $(PHP_PSI_SRCDIR)/src/parser_proc.h
-       touch $@
-$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser_def.h $(PHP_PSI_SRCDIR)/src/parser.h
+$(PHP_PSI_SRCDIR)/src/parser_proc.inc:
+$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser_def.h $(PHP_PSI_SRCDIR)/src/parser_proc.inc
        cat $(PHP_PSI_SRCDIR)/src/parser_proc.inc >$@
        $(CPP) -P -DGENERATE $< >>$@
 $(PHP_PSI_SRCDIR)/src/parser_proc.c: $(PHP_PSI_SRCDIR)/src/parser_proc.y $(LEMON)
        $(LEMON) -c $<
 
-$(PHP_PSI_SRCDIR)/src/parser.re: $(PHP_PSI_SRCDIR)/src/parser.h $(PHP_PSI_SRCDIR)/src/parser_proc.h
+$(PHP_PSI_SRCDIR)/src/parser.re: $(PHP_PSI_SRCDIR)/src/parser_proc.h
        touch $@
 $(PHP_PSI_SRCDIR)/src/parser.c: $(PHP_PSI_SRCDIR)/src/parser.re
        $(RE2C) -o $@ $<
index e42e3bf..f9cf24d 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -113,12 +113,13 @@ if test "$PHP_PSI" != no; then
        PHP_ADD_INCLUDE($PHP_PSI_SRCDIR/src)
        PHP_ADD_BUILD_DIR($PHP_PSI_BUILDDIR/src)
 
-       PHP_PSI_HEADERS=`(cd $PHP_PSI_SRCDIR/src && echo *.h)`
-       PHP_PSI_SOURCES= # parser* should come first
-       PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/parser_proc.c src/parser.c"
-       PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/libjit.c src/libffi.c src/engine.c"
-       PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/marshal.c src/calc.c src/module.c"
-       PHP_PSI_SOURCES="$PHP_PSI_SOURCES `(cd $PHP_PSI_SRCDIR && echo src/context*.c)`"
+       PHP_PSI_HEADERS=`(cd $PHP_PSI_SRCDIR/src && ls *.h types/*.h)`
+       # parser* should come first
+       PHP_PSI_SOURCES=" \
+               src/parser_proc.c \
+               src/parser.c \
+               `(cd $PHP_PSI_SRCDIR && ls src/*.c | $EGREP -v '^src/parser')` \
+       "
 
        PHP_NEW_EXTENSION(psi, $PHP_PSI_SOURCES, $ext_shared)
        PHP_INSTALL_HEADERS(ext/psi, php_psi.h $PHP_PSI_HEADERS)
index 3d68d58..84dc1b7 100644 (file)
--- a/php_psi.h
+++ b/php_psi.h
@@ -20,7 +20,7 @@ extern zend_module_entry psi_module_entry;
 
 #include "context.h"
 
-void psi_error_wrapper(void *context, PSI_Token *t, int type, const char *msg, ...);
+void psi_error_wrapper(void *context, struct psi_token *t, int type, const char *msg, ...);
 void psi_error(int type, const char *fn, unsigned ln, const char *msg, ...);
 void psi_verror(int type, const char *fn, unsigned ln, const char *msg, va_list argv);
 
@@ -47,7 +47,7 @@ PHP_PSI_API zend_class_entry *psi_object_get_class_entry();
 ZEND_BEGIN_MODULE_GLOBALS(psi)
        char *engine;
        char *directory;
-       PSI_Context context;
+       struct psi_context context;
 ZEND_END_MODULE_GLOBALS(psi);
 
 ZEND_EXTERN_MODULE_GLOBALS(psi);
index 5585dfe..805309d 100644 (file)
 
 #include <fnmatch.h>
 
-#include "php.h"
 #include "php_scandir.h"
 #include "php_psi.h"
 #include "calc.h"
 #include "libjit.h"
 #include "libffi.h"
 
+#include "token.h"
+#include "parser.h"
+
 #include "php_psi_types.h"
 #include "php_psi_consts.h"
 #include "php_psi_decls.h"
@@ -39,9 +41,9 @@
 #include "php_psi_structs.h"
 #include "php_psi_unions.h"
 
-PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error, unsigned flags)
+struct psi_context *psi_context_init(struct psi_context *C, struct psi_context_ops *ops, psi_context_error_func error, unsigned flags)
 {
-       PSI_Data T;
+       struct psi_data T;
        struct psi_predef_type *predef_type;
        struct psi_predef_const *predef_const;
        struct psi_predef_struct *predef_struct;
@@ -165,11 +167,11 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
                predef_decl = farg;
        }
 
-       PSI_ContextValidateData(PSI_DATA(C), &T);
+       psi_context_validate_data(PSI_DATA(C), &T);
 
        C->count = 1;
        C->data = malloc(sizeof(*C->data));
-       PSI_DataExchange(C->data, &T);
+       psi_data_exchange(C->data, &T);
 
        return C;
 }
@@ -182,7 +184,7 @@ static int psi_select_dirent(const struct dirent *entry)
        return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD);
 }
 
-void PSI_ContextBuild(PSI_Context *C, const char *paths)
+void psi_context_build(struct psi_context *C, const char *paths)
 {
        int i, n;
        char *sep = NULL, *cpy = strdup(paths), *ptr = cpy;
@@ -201,28 +203,28 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths)
                if (n > 0) {
                        for (i = 0; i < n; ++i) {
                                char psi[MAXPATHLEN];
-                               PSI_Parser P;
+                               struct psi_parser P;
 
                                if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", ptr, entries[i]->d_name)) {
                                        C->error(C, NULL, PSI_WARNING, "Path to PSI file too long: %s/%s",
                                                ptr, entries[i]->d_name);
                                }
-                               if (!PSI_ParserInit(&P, psi, C->error, C->flags)) {
+                               if (!psi_parser_init(&P, psi, C->error, C->flags)) {
                                        C->error(C, NULL, PSI_WARNING, "Failed to init PSI parser (%s): %s",
                                                psi, strerror(errno));
                                        continue;
                                }
 
-                               while (0 < PSI_ParserScan(&P)) {
-                                       PSI_ParserParse(&P, PSI_TokenAlloc(&P));
+                               while (0 < psi_parser_scan(&P)) {
+                                       psi_parser_parse(&P, psi_token_alloc(&P));
                                        if (P.num == PSI_T_EOF) {
                                                break;
                                        }
                                }
 
-                               PSI_ParserParse(&P, NULL);
-                               PSI_ContextValidate(C, &P);
-                               PSI_ParserDtor(&P);
+                               psi_parser_parse(&P, NULL);
+                               psi_context_validate(C, &P);
+                               psi_parser_dtor(&P);
                        }
                }
 
@@ -237,7 +239,7 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths)
        } while (sep);
 
 
-       if (PSI_ContextCompile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) {
+       if (psi_context_compile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) {
                C->error(C, NULL, PSI_WARNING, "Failed to register functions!");
        }
 
@@ -245,7 +247,7 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths)
 
 }
 
-zend_function_entry *PSI_ContextCompile(PSI_Context *C)
+zend_function_entry *psi_context_compile(struct psi_context *C)
 {
        size_t i;
        zend_constant zc;
@@ -295,13 +297,13 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *C)
 }
 
 
-void PSI_ContextCall(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va)
+void psi_context_call(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va)
 {
        C->ops->call(C, decl_call, va);
 }
 
 
-void PSI_ContextDtor(PSI_Context *C)
+void psi_context_dtor(struct psi_context *C)
 {
        size_t i;
        zend_function_entry *zfe;
@@ -314,7 +316,7 @@ void PSI_ContextDtor(PSI_Context *C)
 
        if (C->data) {
                for (i = 0; i < C->count; ++i) {
-                       PSI_DataDtor(&C->data[i]);
+                       psi_data_dtor(&C->data[i]);
                }
                free(C->data);
        }
@@ -372,10 +374,10 @@ void PSI_ContextDtor(PSI_Context *C)
        memset(C, 0, sizeof(*C));
 }
 
-void PSI_ContextFree(PSI_Context **C)
+void psi_context_free(struct psi_context **C)
 {
        if (*C) {
-               PSI_ContextDtor(*C);
+               psi_context_dtor(*C);
                free(*C);
                *C = NULL;
        }
index 6de7389..d2ff1b3 100644 (file)
@@ -1,39 +1,43 @@
 #ifndef _PSI_CONTEXT_H
 #define _PSI_CONTEXT_H
 
-#include "parser.h"
+struct psi_context;
+struct psi_token;
+struct psi_parser;
+struct decl_callinfo;
+struct impl_vararg;
 
 #define PSI_ERROR 16
 #define PSI_WARNING 32
-typedef void (*PSI_ContextErrorFunc)(void *context, PSI_Token *token, int type, const char *msg, ...);
+typedef void (*psi_context_error_func)(void *context, struct psi_token *token, int type, const char *msg, ...);
 
-typedef struct PSI_Context PSI_Context;
-typedef struct PSI_ContextOps PSI_ContextOps;
 
-struct PSI_ContextOps {
-       void (*init)(PSI_Context *C);
-       void (*dtor)(PSI_Context *C);
-       zend_function_entry *(*compile)(PSI_Context *C);
-       void (*call)(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va);
+struct psi_context_ops {
+       void (*init)(struct psi_context *C);
+       void (*dtor)(struct psi_context *C);
+       zend_function_entry *(*compile)(struct psi_context *C);
+       void (*call)(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va);
 };
 
-struct PSI_Context {
+#include "data.h"
+
+struct psi_context {
        PSI_DATA_MEMBERS;
        void *context;
-       struct PSI_ContextOps *ops;
+       struct psi_context_ops *ops;
        zend_function_entry *closures;
-       PSI_Data *data;
+       struct psi_data *data;
        size_t count;
 };
 
-PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error, unsigned flags);
-void PSI_ContextBuild(PSI_Context *C, const char *path);
-int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P);
-int PSI_ContextValidateData(PSI_Data *C, PSI_Data *D);
-zend_function_entry *PSI_ContextCompile(PSI_Context *C);
-void PSI_ContextCall(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va);
-void PSI_ContextDump(PSI_Context *C, int fd);
-void PSI_ContextDtor(PSI_Context *C);
-void PSI_ContextFree(PSI_Context **C);
+struct psi_context *psi_context_init(struct psi_context *C, struct psi_context_ops *ops, psi_context_error_func error, unsigned flags);
+void psi_context_build(struct psi_context *C, const char *path);
+int psi_context_validate(struct psi_context *C, struct psi_parser *P);
+int psi_context_validate_data(struct psi_data *C, struct psi_data *D);
+zend_function_entry *psi_context_compile(struct psi_context *C);
+void psi_context_call(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va);
+void psi_context_dump(struct psi_context *C, int fd);
+void psi_context_dtor(struct psi_context *C);
+void psi_context_free(struct psi_context **C);
 
 #endif
index f138671..1f40e4f 100644 (file)
@@ -1,6 +1,12 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include "php.h"
 #include "php_psi.h"
 
+#include "types.h"
+
 #include "libjit.h"
 #include "libffi.h"
 
@@ -497,15 +503,15 @@ static inline void dump_impls(int fd, impls *impls) {
        }
 }
 
-void PSI_ContextDump(PSI_Context *C, int fd)
+void psi_context_dump(struct psi_context *C, int fd)
 {
 #ifdef HAVE_LIBJIT
-       if (C->ops == PSI_Libjit()) {
+       if (C->ops == psi_libjit_ops()) {
                dprintf(fd, "// psi.engine=jit\n");
        }
 #endif
 #ifdef HAVE_LIBFFI
-       if (C->ops == PSI_Libffi()) {
+       if (C->ops == psi_libffi_ops()) {
                dprintf(fd, "// psi.engine=ffi\n");
        }
 #endif
index f088b59..8add34d 100644 (file)
@@ -18,7 +18,7 @@
 #include "marshal.h"
 #include "engine.h"
 
-static int validate_lib(PSI_Data *data, void **dlopened) {
+static int validate_lib(struct psi_data *data, void **dlopened) {
        char lib[MAXPATHLEN];
        const char *ptr = data->psi.file.ln;
        size_t len;
@@ -128,12 +128,12 @@ static inline int locate_decl_type_decl(decls *decls, decl_type *type) {
        return 0;
 }
 
-static inline int validate_decl_nodl(PSI_Data *data, decl *decl);
-static inline int validate_decl_struct(PSI_Data *data, decl_struct *s);
-static inline int validate_decl_union(PSI_Data *data, decl_union *u);
-static inline int validate_decl_enum(PSI_Data *data, decl_enum *e);
+static inline int validate_decl_nodl(struct psi_data *data, decl *decl);
+static inline int validate_decl_struct(struct psi_data *data, decl_struct *s);
+static inline int validate_decl_union(struct psi_data *data, decl_union *u);
+static inline int validate_decl_enum(struct psi_data *data, decl_enum *e);
 
-static inline int validate_decl_type(PSI_Data *data, decl_type *type, decl_arg *def) {
+static inline int validate_decl_type(struct psi_data *data, decl_type *type, decl_arg *def) {
        if (weak_decl_type(type)) {
                if (!locate_decl_type_alias(data->defs, type)) {
                        return 0;
@@ -171,7 +171,7 @@ static inline int validate_decl_type(PSI_Data *data, decl_type *type, decl_arg *
        }
        return 1;
 }
-static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) {
+static inline int validate_decl_typedef(struct psi_data *data, decl_arg *def) {
        if (!validate_decl_type(data, def->type, def)) {
                const char *pre;
 
@@ -199,12 +199,12 @@ static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) {
        return 1;
 }
 
-static inline int validate_constant(PSI_Data *data, constant *c) {
+static inline int validate_constant(struct psi_data *data, constant *c) {
        /* FIXME */
        return 1;
 }
 
-static inline int validate_decl_arg(PSI_Data *data, decl_arg *arg) {
+static inline int validate_decl_arg(struct psi_data *data, decl_arg *arg) {
        if (!validate_decl_type(data, arg->type, NULL)) {
                data->error(data, arg->type->token, PSI_WARNING,
                        "Cannot use '%s' as type for '%s'",
@@ -243,7 +243,7 @@ static inline void psi_sort_struct_args(void **args, size_t count) {
                        psi_sort_struct_arg_cmp, psi_sort_struct_arg_swp);
 }
 
-static inline int validate_decl_struct_darg(PSI_Data *data, decl_arg *darg, void *current) {
+static inline int validate_decl_struct_darg(struct psi_data *data, decl_arg *darg, void *current) {
        decl_type *real = real_decl_type(darg->type);
 
        /* pre-validate any structs/unions/enums */
@@ -394,7 +394,7 @@ static inline size_t align_decl_arg(decl_arg *darg, size_t *pos, size_t *len) {
        return align;
 }
 
-static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
+static inline int validate_decl_struct(struct psi_data *data, decl_struct *s) {
        size_t i, pos, len, size, align;
 
        if (!s->size && !s->args->count) {
@@ -465,7 +465,7 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
        return 1;
 }
 
-static inline int validate_decl_union(PSI_Data *data, decl_union *u) {
+static inline int validate_decl_union(struct psi_data *data, decl_union *u) {
        size_t i, pos, len, size = 0, align;
 
        if (!u->size && !u->args->count) {
@@ -537,7 +537,7 @@ static const char * const abi_ccs[] = {
                "stdcall",
                "fastcall",
 };
-static inline int validate_decl_abi(PSI_Data *data, decl_abi *abi) {
+static inline int validate_decl_abi(struct psi_data *data, decl_abi *abi) {
        size_t i;
 
        for (i = 0; i < sizeof(abi_ccs)/sizeof(char*); ++i) {
@@ -547,7 +547,7 @@ static inline int validate_decl_abi(PSI_Data *data, decl_abi *abi) {
        }
        return 0;
 }
-static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_arg *func)
+static inline int validate_decl_func(struct psi_data *data, void *dl, decl *decl, decl_arg *func)
 {
        struct psi_func_redir *redir;
 
@@ -574,7 +574,7 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_
        }
        return 1;
 }
-static inline int validate_decl_nodl(PSI_Data *data, decl *decl) {
+static inline int validate_decl_nodl(struct psi_data *data, decl *decl) {
        if (!validate_decl_abi(data, decl->abi)) {
                data->error(data, decl->abi->token, PSI_WARNING,
                                "Invalid calling convention: '%s'", decl->abi->token->text);
@@ -594,7 +594,7 @@ static inline int validate_decl_nodl(PSI_Data *data, decl *decl) {
        }
        return 1;
 }
-static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) {
+static inline int validate_decl(struct psi_data *data, void *dl, decl *decl) {
        if (!validate_decl_nodl(data, decl)) {
                return 0;
        }
@@ -669,7 +669,7 @@ static inline decl_enum_item *locate_num_exp_enum_item(num_exp *exp, decl_enums
        }
        return NULL;
 }
-static inline int validate_num_exp(PSI_Data *data, num_exp *exp, decl_args *dargs, decl_arg *func, decl_enum *enm) {
+static inline int validate_num_exp(struct psi_data *data, num_exp *exp, decl_args *dargs, decl_arg *func, decl_enum *enm) {
        if (exp->operand) {
                switch (exp->operator) {
                case PSI_T_PLUS:
@@ -715,7 +715,7 @@ static inline int validate_num_exp(PSI_Data *data, num_exp *exp, decl_args *darg
        }
 }
 
-static inline int validate_decl_enum(PSI_Data *data, decl_enum *e) {
+static inline int validate_decl_enum(struct psi_data *data, decl_enum *e) {
        size_t j;
 
        if (!e->items || !e->items->count) {
@@ -782,7 +782,7 @@ static inline void decl_var_arg_v(decl_args *args, va_list argp) {
                }
        }
 }
-static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg *ref, decl_args *ref_list) {
+static inline int validate_set_value_ex(struct psi_data *data, set_value *set, decl_arg *ref, decl_args *ref_list) {
        size_t i;
        decl_type *ref_type;
        decl_var *set_var = set->vars->vars[0];
@@ -856,7 +856,7 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg
 
        return 1;
 }
-static inline int validate_set_value(PSI_Data *data, set_value *set, ...) {
+static inline int validate_set_value(struct psi_data *data, set_value *set, ...) {
        va_list argp;
        decl_args args = {0};
        int check;
@@ -885,7 +885,7 @@ static inline decl *locate_impl_decl(decls *decls, return_stmt *ret) {
 
        return NULL;
 }
-static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) {
+static inline int validate_impl_ret_stmt(struct psi_data *data, impl *impl) {
        return_stmt *ret;
 
        /* we must have exactly one ret stmt delcaring the native func to call */
@@ -936,7 +936,7 @@ static inline impl_arg *locate_impl_var_arg(impl_var *var, impl_args *args) {
        return NULL;
 }
 
-static inline int validate_let_func(PSI_Data *data, let_func *func, impl *impl) {
+static inline int validate_let_func(struct psi_data *data, let_func *func, impl *impl) {
        if (impl->func->args) {
                if (!locate_impl_var_arg(func->var, impl->func->args)) {
                        data->error(data, func->var->token, PSI_WARNING,
@@ -961,7 +961,7 @@ static inline int validate_let_func(PSI_Data *data, let_func *func, impl *impl)
        return 1;
 }
 
-static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_callback *cb, impl *impl) {
+static inline int validate_let_callback(struct psi_data *data, decl_var *cb_var, let_callback *cb, impl *impl) {
        size_t i;
        decl *cb_func;
        decl_type *cb_type = real_decl_type(cb_var->arg->type);
@@ -990,7 +990,7 @@ static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_ca
        return 1;
 }
 
-static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) {
+static inline int validate_impl_let_stmts(struct psi_data *data, impl *impl) {
        size_t i, j;
        /* we can have multiple let stmts */
 
@@ -1078,7 +1078,7 @@ static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) {
 
        return 1;
 }
-static inline int validate_impl_set_stmts(PSI_Data *data, impl *impl) {
+static inline int validate_impl_set_stmts(struct psi_data *data, impl *impl) {
        size_t i, j, k;
        /* we can have any count of set stmts; processing out vars */
        /* check that set stmts reference known variables */
@@ -1162,7 +1162,7 @@ static inline decl *locate_free_decl(decls *decls, free_call *f) {
 
        return NULL;
 }
-static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) {
+static inline int validate_impl_free_stmts(struct psi_data *data, impl *impl) {
        size_t i, j, k, l;
        /* we can have any count of free stmts; freeing any out vars */
        for (i = 0; i < impl->stmts->fre.count; ++i) {
@@ -1214,7 +1214,7 @@ static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) {
        }
        return 1;
 }
-static inline int validate_impl_stmts(PSI_Data *data, impl *impl) {
+static inline int validate_impl_stmts(struct psi_data *data, impl *impl) {
        if (!impl->stmts) {
                data->error(data, impl->func->token, PSI_WARNING,
                                "Missing body for implementation %s!",
@@ -1239,7 +1239,7 @@ static inline int validate_impl_stmts(PSI_Data *data, impl *impl) {
        return 1;
 }
 
-static inline int validate_impl_args(PSI_Data *data, impl *impl) {
+static inline int validate_impl_args(struct psi_data *data, impl *impl) {
        int def = 0;
        size_t i;
 
@@ -1260,7 +1260,7 @@ static inline int validate_impl_args(PSI_Data *data, impl *impl) {
        return 1;
 }
 
-static inline int validate_impl(PSI_Data *data, impl *impl) {
+static inline int validate_impl(struct psi_data *data, impl *impl) {
        if (!validate_impl_args(data, impl)) {
                return 0;
        }
@@ -1268,9 +1268,9 @@ static inline int validate_impl(PSI_Data *data, impl *impl) {
 }
 
 
-int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P)
+int psi_context_validate(struct psi_context *C, struct psi_parser *P)
 {
-       PSI_Data *D;
+       struct psi_data *D;
        void *dlopened = NULL;
        size_t i, count = C->count++, check_round, check_count;
        decl_typedefs *check_defs = P->defs;
@@ -1280,7 +1280,7 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P)
        unsigned silent = C->flags & PSI_PARSER_SILENT;
 
        C->data = realloc(C->data, C->count * sizeof(*C->data));
-       D = PSI_DataExchange(&C->data[count], PSI_DATA(P));
+       D = psi_data_exchange(&C->data[count], PSI_DATA(P));
 
 #define REVALIDATE(what) do { \
                if (check_round && check_ ##what) { \
@@ -1376,7 +1376,7 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P)
        return 1;
 }
 
-int PSI_ContextValidateData(PSI_Data *dest, PSI_Data *source)
+int psi_context_validate_data(struct psi_data *dest, struct psi_data *source)
 {
        size_t i;
        int errors = 0;
diff --git a/src/data.c b/src/data.c
new file mode 100644 (file)
index 0000000..860387d
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
+#include <string.h>
+
+#include "data.h"
+
+struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src) {
+       if (!dest) {
+               dest = malloc(sizeof(*dest));
+       }
+       memcpy(dest, src, sizeof(*dest));
+       memset(src, 0, sizeof(*src));
+       return dest;
+}
+
+void psi_data_dtor(struct psi_data *data) {
+       if (data->consts) {
+               free_constants(data->consts);
+       }
+       if (data->defs) {
+               free_decl_typedefs(data->defs);
+       }
+       if (data->structs) {
+               free_decl_structs(data->structs);
+       }
+       if (data->unions) {
+               free_decl_unions(data->unions);
+       }
+       if (data->enums) {
+               free_decl_enums(data->enums);
+       }
+       if (data->decls) {
+               free_decls(data->decls);
+       }
+       if (data->impls) {
+               free_impls(data->impls);
+       }
+       free_decl_file(&data->psi.file);
+}
+
diff --git a/src/data.h b/src/data.h
new file mode 100644 (file)
index 0000000..cc497fb
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _PSI_DATA_H
+#define _PSI_DATA_H
+
+#include "types.h"
+
+#define PSI_DATA(D) ((struct 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; \
+       union { \
+               decl_file file; \
+               decl_libs libs; \
+       } psi; \
+       psi_error_cb error; \
+       unsigned errors; \
+       unsigned flags
+
+struct psi_data {
+       PSI_DATA_MEMBERS;
+};
+
+struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src);
+void psi_data_dtor(struct psi_data *data);
+
+#endif
index a4bf0d7..38cdb0e 100644 (file)
 #include "calc.h"
 #include "marshal.h"
 
-size_t psi_t_alignment(token_t t)
-{
-#define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T;
-       switch (t) {
-       PSI_ALIGNOF(INT8);
-       PSI_ALIGNOF(UINT8);
-       PSI_ALIGNOF(INT16);
-       PSI_ALIGNOF(UINT16);
-       PSI_ALIGNOF(INT32);
-       PSI_ALIGNOF(UINT32);
-       PSI_ALIGNOF(INT64);
-       PSI_ALIGNOF(UINT64);
-       case PSI_T_FLOAT:
-               return ALIGNOF_FLOAT;
-       case PSI_T_DOUBLE:
-               return ALIGNOF_DOUBLE;
-       case PSI_T_POINTER:
-       case PSI_T_FUNCTION:
-               return ALIGNOF_VOID_P;
-       case PSI_T_ENUM:
-               return ALIGNOF_INT;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       return 0;
-}
-
-size_t psi_t_size(token_t t)
-{
-#define PSI_SIZEOF(T) case PSI_T_## T : return SIZEOF_## T ##_T;
-       switch (t) {
-       PSI_SIZEOF(INT8);
-       PSI_SIZEOF(UINT8);
-       PSI_SIZEOF(INT16);
-       PSI_SIZEOF(UINT16);
-       PSI_SIZEOF(INT32);
-       PSI_SIZEOF(UINT32);
-       PSI_SIZEOF(INT64);
-       PSI_SIZEOF(UINT64);
-       case PSI_T_FLOAT:
-               return SIZEOF_FLOAT;
-       case PSI_T_DOUBLE:
-               return SIZEOF_DOUBLE;
-       case PSI_T_POINTER:
-       case PSI_T_FUNCTION:
-               return SIZEOF_VOID_P;
-       case PSI_T_ENUM:
-               return SIZEOF_INT;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       return 0;
-}
 
 int psi_internal_type(impl_type *type)
 {
@@ -329,7 +278,7 @@ static inline void psi_do_free(free_stmt *fre)
                }
 
                /* FIXME: check in validate_* that free functions return scalar */
-               PSI_ContextCall(&PSI_G(context), &f->decl->call, NULL);
+               psi_context_call(&PSI_G(context), &f->decl->call, NULL);
        }
 }
 
@@ -520,7 +469,7 @@ ZEND_RESULT_CODE psi_call(zend_execute_data *execute_data, zval *return_value, i
                }
        }
 
-       PSI_ContextCall(&PSI_G(context), &impl->decl->call, va);
+       psi_context_call(&PSI_G(context), &impl->decl->call, va);
        psi_do_return(return_value, impl->stmts->ret.list[0]);
 
        for (i = 0; i < impl->stmts->set.count; ++i) {
index 3aa78a4..e8d86ff 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef _PSI_ENGINE_H
 #define _PSI_ENGINE_H
 
-size_t psi_t_alignment(token_t t);
-size_t psi_t_size(token_t t);
-
 static inline size_t psi_align(size_t s, size_t a) {
        return ((s - 1) | (a - 1)) + 1;
 }
index 627c97f..2dbe0bc 100644 (file)
@@ -7,7 +7,7 @@
 #ifdef HAVE_LIBFFI
 
 #include "php_psi.h"
-#include "libffi.h"
+#include "ffi.h"
 #include "engine.h"
 
 #undef PACKAGE
@@ -83,26 +83,26 @@ static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_
 
 static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg);
 
-typedef struct PSI_LibffiContext {
+struct psi_ffi_context {
        ffi_cif signature;
        ffi_type *params[2];
-} PSI_LibffiContext;
+};
 
-typedef struct PSI_LibffiCall {
+struct psi_ffi_call {
        void *code;
        ffi_closure *closure;
        ffi_cif signature;
        void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */
-} PSI_LibffiCall;
+};
 
 static inline ffi_abi psi_ffi_abi(const char *convention) {
        return FFI_DEFAULT_ABI;
 }
 
-static inline PSI_LibffiCall *PSI_LibffiCallAlloc(PSI_Context *C, decl *decl) {
+static inline struct psi_ffi_call *psi_ffi_call_alloc(struct psi_context *C, decl *decl) {
        int rc;
        size_t i, c = decl->args ? decl->args->count : 0;
-       PSI_LibffiCall *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
+       struct psi_ffi_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
 
        for (i = 0; i < c; ++i) {
                call->params[i] = psi_ffi_decl_arg_type(decl->args->args[i]);
@@ -121,17 +121,17 @@ static inline PSI_LibffiCall *PSI_LibffiCallAlloc(PSI_Context *C, decl *decl) {
        return call;
 }
 
-static inline ffi_status PSI_LibffiCallInitClosure(PSI_Context *C, PSI_LibffiCall *call, impl *impl) {
-       PSI_LibffiContext *context = C->context;
+static inline ffi_status psi_ffi_call_init_closure(struct psi_context *C, struct psi_ffi_call *call, impl *impl) {
+       struct psi_ffi_context *context = C->context;
 
        return psi_ffi_prep_closure(&call->closure, &call->code, &context->signature, psi_ffi_handler, impl);
 }
 
-static inline ffi_status PSI_LibffiCallInitCallbackClosure(PSI_Context *C, PSI_LibffiCall *call, let_callback *cb) {
+static inline ffi_status psi_ffi_call_init_callback_closure(struct psi_context *C, struct psi_ffi_call *call, let_callback *cb) {
        return psi_ffi_prep_closure(&call->closure, &call->code, &call->signature, psi_ffi_callback, cb);
 }
 
-static inline void PSI_LibffiCallFree(PSI_LibffiCall *call) {
+static inline void psi_ffi_call_free(struct psi_ffi_call *call) {
        if (call->closure) {
                psi_ffi_closure_free(call->closure);
        }
@@ -300,7 +300,7 @@ static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg) {
 }
 
 
-static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) {
+static inline struct psi_ffi_context *psi_ffi_context_init(struct psi_ffi_context *L) {
        ffi_status rc;
 
        if (!L) {
@@ -316,19 +316,19 @@ static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) {
        return L;
 }
 
-static inline void PSI_LibffiContextFree(PSI_LibffiContext **L) {
+static inline void psi_ffi_context_free(struct psi_ffi_context **L) {
        if (*L) {
                free(*L);
                *L = NULL;
        }
 }
 
-static void psi_ffi_init(PSI_Context *C)
+static void psi_ffi_init(struct psi_context *C)
 {
-       C->context = PSI_LibffiContextInit(NULL);
+       C->context = psi_ffi_context_init(NULL);
 }
 
-static void psi_ffi_dtor(PSI_Context *C)
+static void psi_ffi_dtor(struct psi_context *C)
 {
        if (C->decls) {
                size_t i;
@@ -337,7 +337,7 @@ static void psi_ffi_dtor(PSI_Context *C)
                        decl *decl = C->decls->list[i];
 
                        if (decl->call.info) {
-                               PSI_LibffiCallFree(decl->call.info);
+                               psi_ffi_call_free(decl->call.info);
                        }
                }
 
@@ -355,16 +355,16 @@ static void psi_ffi_dtor(PSI_Context *C)
                                        let_callback *cb = let->val->data.callback;
 
                                        if (cb->decl && cb->decl->call.info) {
-                                               PSI_LibffiCallFree(cb->decl->call.info);
+                                               psi_ffi_call_free(cb->decl->call.info);
                                        }
                                }
                        }
                }
        }
-       PSI_LibffiContextFree((void *) &C->context);
+       psi_ffi_context_free((void *) &C->context);
 }
 
-static zend_function_entry *psi_ffi_compile(PSI_Context *C)
+static zend_function_entry *psi_ffi_compile(struct psi_context *C)
 {
        size_t c, i, j = 0;
        zend_function_entry *zfe;
@@ -376,16 +376,16 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C)
        zfe = calloc(C->impls->count + 1, sizeof(*zfe));
        for (i = 0; i < C->impls->count; ++i) {
                zend_function_entry *zf = &zfe[j];
-               PSI_LibffiCall *call;
+               struct psi_ffi_call *call;
                impl *impl = C->impls->list[i];
 
                if (!impl->decl) {
                        continue;
                }
 
-               if ((call = PSI_LibffiCallAlloc(C, impl->decl))) {
-                       if (FFI_OK != PSI_LibffiCallInitClosure(C, call, impl)) {
-                               PSI_LibffiCallFree(call);
+               if ((call = psi_ffi_call_alloc(C, impl->decl))) {
+                       if (FFI_OK != psi_ffi_call_init_closure(C, call, impl)) {
+                               psi_ffi_call_free(call);
                                continue;
                        }
                }
@@ -402,9 +402,9 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C)
                        if (let->val && let->val->kind == PSI_LET_CALLBACK) {
                                let_callback *cb = let->val->data.callback;
 
-                               if ((call = PSI_LibffiCallAlloc(C, cb->decl))) {
-                                       if (FFI_OK != PSI_LibffiCallInitCallbackClosure(C, call, cb)) {
-                                               PSI_LibffiCallFree(call);
+                               if ((call = psi_ffi_call_alloc(C, cb->decl))) {
+                                       if (FFI_OK != psi_ffi_call_init_callback_closure(C, call, cb)) {
+                                               psi_ffi_call_free(call);
                                                continue;
                                        }
 
@@ -421,14 +421,14 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C)
                        continue;
                }
 
-               PSI_LibffiCallAlloc(C, decl);
+               psi_ffi_call_alloc(C, decl);
        }
 
        return zfe;
 }
 
-static void psi_ffi_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va) {
-       PSI_LibffiCall *call = decl_call->info;
+static void psi_ffi_call(struct psi_context *C, decl_callinfo *decl_call, impl_vararg *va) {
+       struct psi_ffi_call *call = decl_call->info;
 
        if (va) {
                ffi_status rc;
@@ -461,14 +461,14 @@ static void psi_ffi_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *
        }
 }
 
-static PSI_ContextOps ops = {
+static struct psi_context_ops ops = {
        psi_ffi_init,
        psi_ffi_dtor,
        psi_ffi_compile,
        psi_ffi_call,
 };
 
-PSI_ContextOps *PSI_Libffi(void)
+struct psi_context_ops *psi_libffi_ops(void)
 {
        return &ops;
 }
index 4b36b30..8db73ee 100644 (file)
@@ -4,7 +4,7 @@
 #include "context.h"
 
 #ifdef HAVE_LIBFFI
-PSI_ContextOps *PSI_Libffi(void);
+struct psi_context_ops *psi_libffi_ops(void);
 #endif
 
 #endif
index 62540cc..b6022c5 100644 (file)
@@ -175,30 +175,30 @@ static inline jit_type_t psi_jit_decl_arg_type(decl_arg *darg) {
        }
 }
 
-typedef struct PSI_LibjitContext {
+struct psi_jit_context {
        jit_context_t jit;
        jit_type_t signature;
        struct {
-               struct PSI_LibjitData **list;
+               struct psi_jit_data **list;
                size_t count;
        } data;
-} PSI_LibjitContext;
+};
 
-typedef struct PSI_LibjitCall {
+struct psi_jit_call {
        void *closure;
        jit_type_t signature;
        void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */
-} PSI_LibjitCall;
+};
 
-typedef struct PSI_LibjitData {
-       PSI_LibjitContext *context;
+struct psi_jit_data {
+       struct psi_jit_context *context;
        impl *impl;
        zend_internal_arg_info *arginfo;
-} PSI_LibjitData;
+};
 
-static inline PSI_LibjitCall *PSI_LibjitCallAlloc(PSI_Context *C, decl *decl) {
+static inline struct psi_jit_call *psi_jit_call_alloc(struct psi_context *C, decl *decl) {
        size_t i, c = decl->args ? decl->args->count : 0;
-       PSI_LibjitCall *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
+       struct psi_jit_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
 
        for (i = 0; i < c; ++i) {
                call->params[i] = psi_jit_decl_arg_type(decl->args->args[i]);
@@ -219,24 +219,24 @@ static inline PSI_LibjitCall *PSI_LibjitCallAlloc(PSI_Context *C, decl *decl) {
        return call;
 }
 
-static inline void *PSI_LibjitCallInitClosure(PSI_Context *C, PSI_LibjitCall *call, impl *impl) {
-       PSI_LibjitContext *context = C->context;
+static inline void *psi_jit_call_init_closure(struct psi_context *C, struct psi_jit_call *call, impl *impl) {
+       struct psi_jit_context *context = C->context;
        return call->closure = jit_closure_create(context->jit, context->signature,
                        &psi_jit_handler, impl);
 }
 
-static inline void *PSI_LibjitCallInitCallbackClosure(PSI_Context *C, PSI_LibjitCall *call, let_callback *cb) {
-       PSI_LibjitContext *context = C->context;
+static inline void *psi_jit_call_init_callback_closure(struct psi_context *C, struct psi_jit_call *call, let_callback *cb) {
+       struct psi_jit_context *context = C->context;
        return call->closure = jit_closure_create(context->jit, call->signature,
                        &psi_jit_callback, cb);
 }
 
-static inline void PSI_LibjitCallFree(PSI_LibjitCall *call) {
+static inline void psi_jit_call_free(struct psi_jit_call *call) {
        jit_type_free(call->signature);
        free(call);
 }
 
-static inline PSI_LibjitContext *PSI_LibjitContextInit(PSI_LibjitContext *L) {
+static inline struct psi_jit_context *psi_jit_context_init(struct psi_jit_context *L) {
        jit_type_t params[] = {
                jit_type_void_ptr,
                jit_type_void_ptr
@@ -254,25 +254,25 @@ static inline PSI_LibjitContext *PSI_LibjitContextInit(PSI_LibjitContext *L) {
        return L;
 }
 
-static inline void PSI_LibjitContextDtor(PSI_LibjitContext *L) {
+static inline void psi_jit_context_dtor(struct psi_jit_context *L) {
        jit_type_free(L->signature);
        jit_context_destroy(L->jit);
 }
 
-static inline void PSI_LibjitContextFree(PSI_LibjitContext **L) {
+static inline void psi_jit_context_free(struct psi_jit_context **L) {
        if (*L) {
-               PSI_LibjitContextDtor(*L);
+               psi_jit_context_dtor(*L);
                free(*L);
                *L = NULL;
        }
 }
 
-static void psi_jit_init(PSI_Context *C)
+static void psi_jit_init(struct psi_context *C)
 {
-       C->context = PSI_LibjitContextInit(NULL);
+       C->context = psi_jit_context_init(NULL);
 }
 
-static void psi_jit_dtor(PSI_Context *C)
+static void psi_jit_dtor(struct psi_context *C)
 {
        if (C->decls) {
                size_t i;
@@ -281,7 +281,7 @@ static void psi_jit_dtor(PSI_Context *C)
                        decl *decl = C->decls->list[i];
 
                        if (decl->call.info) {
-                               PSI_LibjitCallFree(decl->call.info);
+                               psi_jit_call_free(decl->call.info);
                        }
                }
        }
@@ -298,20 +298,20 @@ static void psi_jit_dtor(PSI_Context *C)
                                        let_callback *cb = let->val->data.callback;
 
                                        if (cb->decl && cb->decl->call.info) {
-                                               PSI_LibjitCallFree(cb->decl->call.info);
+                                               psi_jit_call_free(cb->decl->call.info);
                                        }
                                }
                        }
                }
        }
-       PSI_LibjitContextFree((void *) &C->context);
+       psi_jit_context_free((void *) &C->context);
 }
 
-static zend_function_entry *psi_jit_compile(PSI_Context *C)
+static zend_function_entry *psi_jit_compile(struct psi_context *C)
 {
        size_t c, i, j = 0;
        zend_function_entry *zfe;
-       PSI_LibjitContext *ctx = C->context;
+       struct psi_jit_context *ctx = C->context;
 
        if (!C->impls) {
                return NULL;
@@ -322,16 +322,16 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C)
 
        for (i = 0; i < C->impls->count; ++i) {
                zend_function_entry *zf = &zfe[j];
-               PSI_LibjitCall *call;
+               struct psi_jit_call *call;
                impl *impl = C->impls->list[i];
 
                if (!impl->decl) {
                        continue;
                }
 
-               if ((call = PSI_LibjitCallAlloc(C, impl->decl))) {
-                       if (!PSI_LibjitCallInitClosure(C, call, impl)) {
-                               PSI_LibjitCallFree(call);
+               if ((call = psi_jit_call_alloc(C, impl->decl))) {
+                       if (!psi_jit_call_init_closure(C, call, impl)) {
+                               psi_jit_call_free(call);
                                continue;
                        }
                }
@@ -348,9 +348,9 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C)
                        if (let->val && let->val->kind == PSI_LET_CALLBACK) {
                                let_callback *cb = let->val->data.callback;
 
-                               if ((call = PSI_LibjitCallAlloc(C, cb->decl))) {
-                                       if (!PSI_LibjitCallInitCallbackClosure(C, call, cb)) {
-                                               PSI_LibjitCallFree(call);
+                               if ((call = psi_jit_call_alloc(C, cb->decl))) {
+                                       if (!psi_jit_call_init_callback_closure(C, call, cb)) {
+                                               psi_jit_call_free(call);
                                                continue;
                                        }
 
@@ -367,7 +367,7 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C)
                        continue;
                }
 
-               PSI_LibjitCallAlloc(C, decl);
+               psi_jit_call_alloc(C, decl);
        }
 
        jit_context_build_end(ctx->jit);
@@ -375,8 +375,8 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C)
        return zfe;
 }
 
-static void psi_jit_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va) {
-       PSI_LibjitCall *call = decl_call->info;
+static void psi_jit_call(struct psi_context *C, decl_callinfo *decl_call, impl_vararg *va) {
+       struct psi_jit_call *call = decl_call->info;
 
        if (va) {
                jit_type_t signature;
@@ -408,14 +408,14 @@ static void psi_jit_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *
        }
 }
 
-static PSI_ContextOps ops = {
+static struct psi_context_ops ops = {
        psi_jit_init,
        psi_jit_dtor,
        psi_jit_compile,
        psi_jit_call,
 };
 
-PSI_ContextOps *PSI_Libjit(void)
+struct psi_context_ops *psi_libjit_ops(void)
 {
        return &ops;
 }
index 3cd4b28..602fc51 100644 (file)
@@ -4,7 +4,7 @@
 #include "context.h"
 
 #ifdef HAVE_LIBJIT
-PSI_ContextOps *PSI_Libjit(void);
+struct psi_context_ops *psi_libjit_ops(void);
 #endif
 
 #endif
index aff784d..33e3ae2 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
@@ -10,6 +9,8 @@
 #include "zend_operators.h"
 
 #include "php_psi.h"
+#include "token.h"
+#include "parser.h"
 
 #if HAVE_LIBJIT
 # include "libjit.h"
@@ -37,7 +38,7 @@ zend_class_entry *psi_object_get_class_entry()
        return psi_class_entry;
 }
 
-void psi_error_wrapper(void *context, PSI_Token *t, int type, const char *msg, ...)
+void psi_error_wrapper(void *context, struct psi_token *t, int type, const char *msg, ...)
 {
        va_list argv;
        const char *fn = NULL;
@@ -119,7 +120,7 @@ static PHP_FUNCTION(psi_dump) {
                        RETURN_FALSE;
                }
        }
-       PSI_ContextDump(&PSI_G(context), fd);
+       psi_context_dump(&PSI_G(context), fd);
 }
 
 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1)
@@ -127,35 +128,35 @@ ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1)
 ZEND_END_ARG_INFO();
 static PHP_FUNCTION(psi_validate) {
        zend_string *file;
-       PSI_Parser P;
+       struct psi_parser P;
 
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file)) {
                return;
        }
 
-       if (!PSI_ParserInit(&P, file->val, psi_error_wrapper, 0)) {
+       if (!psi_parser_init(&P, file->val, psi_error_wrapper, 0)) {
                RETURN_FALSE;
        }
 
-       while (0 < PSI_ParserScan(&P)) {
-               PSI_ParserParse(&P, PSI_TokenAlloc(&P));
+       while (0 < psi_parser_scan(&P)) {
+               psi_parser_parse(&P, psi_token_alloc(&P));
                if (P.num == PSI_T_EOF) {
                        break;
                }
        }
-       PSI_ParserParse(&P, NULL);
+       psi_parser_parse(&P, NULL);
 
-       if (0 == PSI_ContextValidateData(NULL, PSI_DATA(&P)) && !P.errors) {
+       if (0 == psi_context_validate_data(NULL, PSI_DATA(&P)) && !P.errors) {
                RETVAL_TRUE;
        } else {
                RETVAL_FALSE;
        }
-       PSI_ParserDtor(&P);
+       psi_parser_dtor(&P);
 }
 
 static PHP_MINIT_FUNCTION(psi)
 {
-       PSI_ContextOps *ops = NULL;
+       struct psi_context_ops *ops = NULL;
        zend_class_entry ce = {0};
        unsigned flags = psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG : (
                        psi_check_env("PSI_SILENT") ? PSI_PARSER_SILENT : 0);
@@ -173,11 +174,11 @@ static PHP_MINIT_FUNCTION(psi)
 
 #ifdef HAVE_LIBJIT
        if (!strcasecmp(PSI_G(engine), "jit")) {
-               ops = PSI_Libjit();
+               ops = psi_libjit_ops();
        } else
 #endif
 #ifdef HAVE_LIBFFI
-               ops = PSI_Libffi();
+               ops = psi_libffi_ops();
 #endif
 
        if (!ops) {
@@ -185,11 +186,11 @@ static PHP_MINIT_FUNCTION(psi)
                return FAILURE;
        }
 
-       PSI_ContextInit(&PSI_G(context), ops, psi_error_wrapper, flags);
-       PSI_ContextBuild(&PSI_G(context), PSI_G(directory));
+       psi_context_init(&PSI_G(context), ops, psi_error_wrapper, flags);
+       psi_context_build(&PSI_G(context), PSI_G(directory));
 
        if (psi_check_env("PSI_DUMP")) {
-               PSI_ContextDump(&PSI_G(context), STDOUT_FILENO);
+               psi_context_dump(&PSI_G(context), STDOUT_FILENO);
        }
 
        return SUCCESS;
@@ -197,7 +198,7 @@ static PHP_MINIT_FUNCTION(psi)
 
 static PHP_MSHUTDOWN_FUNCTION(psi)
 {
-       PSI_ContextDtor(&PSI_G(context));
+       psi_context_dtor(&PSI_G(context));
 
        UNREGISTER_INI_ENTRIES();
 
index c99c266..5851ee6 100644 (file)
 #include <stdarg.h>
 #include <string.h>
 
-#include <Zend/zend_types.h>
-#include <Zend/zend_API.h> /* fcall */
-
 #include "parser_proc.h"
 
 #define BSIZE 256
 
-#define PSI_T_POINTER PSI_T_ASTERISK
-#define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
-
-typedef int token_t;
-
-size_t psi_t_alignment(token_t);
-size_t psi_t_size(token_t);
-
-typedef struct PSI_Token {
-       token_t type;
-       unsigned size, line, col;
-       char *text, *file;
-       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;
-       uint8_t u8;
-       short sval;
-       int16_t i16;
-       uint16_t u16;
-       int ival;
-       int32_t i32;
-       uint32_t u32;
-       long lval;
-       int64_t i64;
-       uint64_t u64;
-       float fval;
-       double dval;
-#ifdef HAVE_LONG_DOUBLE
-       long double ldval;
-#endif
-       union {
-               zend_bool bval;
-               zend_long lval;
-               zend_string *str;
-               zend_fcall *cb;
-       } zend;
-       void *ptr;
-} impl_val;
-
-typedef struct decl_type {
-       PSI_Token *token;
-       char *name;
-       token_t type;
-       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) {
-       decl_type *t = calloc(1, sizeof(*t));
-       t->type = type;
-       t->name = strdup(name);
-       return t;
-}
-
-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;
-       }
-}
-
-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->real.func);
-       }
-       free(type->name);
-       free(type);
-}
-
-typedef struct decl_var {
-       PSI_Token *token;
-       char *name;
-       unsigned pointer_level;
-       unsigned array_size;
-       struct decl_arg *arg;
-} decl_var;
-
-static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
-       decl_var *v = calloc(1, sizeof(*v));
-       v->name = (char *) strdup((const char *) name);
-       v->pointer_level = pl;
-       v->array_size = 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);
-       }
-       free(var->name);
-       free(var);
-}
-
-typedef struct decl_struct_layout {
-       size_t pos;
-       size_t len;
-} decl_struct_layout;
-
-static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
-       decl_struct_layout *l = calloc(1, sizeof(*l));
-       ZEND_ASSERT(pos+len);
-       l->pos = pos;
-       l->len = len;
-       return l;
-}
-
-static inline void free_decl_struct_layout(decl_struct_layout *l) {
-       free(l);
-}
-
-typedef struct decl_arg {
-       PSI_Token *token;
-       decl_type *type;
-       decl_var *var;
-       decl_struct_layout *layout;
-       impl_val val;
-       void *ptr;
-       void *let;
-       void *mem;
-} decl_arg;
-
-static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
-       decl_arg *arg = calloc(1, sizeof(*arg));
-       arg->token = var->token;
-       arg->type = type;
-       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) {
-               free_decl_struct_layout(arg->layout);
-       }
-       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;
-} 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;
-} decl_vars;
-
-static inline decl_vars *init_decl_vars(decl_var *var) {
-       decl_vars *vars = calloc(1, sizeof(*vars));
-       if (var) {
-               vars->count = 1;
-               vars->vars = calloc(1, sizeof(*vars->vars));
-               vars->vars[0] = var;
-       }
-       return vars;
-}
-
-static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
-       vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
-       vars->vars[vars->count-1] = var;
-       return vars;
-}
-
-static inline void free_decl_vars(decl_vars *vars) {
-       size_t i;
-
-       for (i = 0; i < vars->count; ++i) {
-               free_decl_var(vars->vars[i]);
-       }
-       free(vars->vars);
-       free(vars);
-}
-
-typedef struct decl_args {
-       decl_arg **args;
-       size_t count;
-       unsigned varargs:1;
-} decl_args;
-
-static inline decl_args *init_decl_args(decl_arg *arg) {
-       decl_args *args = calloc(1, sizeof(*args));
-       if (arg) {
-               args->count = 1;
-               args->args = calloc(1, sizeof(*args->args));
-               args->args[0] = arg;
-       }
-       return args;
-}
-
-static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
-       args->args = realloc(args->args, ++args->count * sizeof(*args->args));
-       args->args[args->count-1] = arg;
-       return args;
-}
-
-static inline void free_decl_args(decl_args *args) {
-       size_t i;
-
-       for (i = 0; i < args->count; ++i) {
-               free_decl_arg(args->args[i]);
-       }
-       free(args->args);
-       free(args);
-}
-
-typedef struct decl_abi {
-       PSI_Token *token;
-       char *convention;
-} decl_abi;
-
-static inline decl_abi *init_decl_abi(const char *convention) {
-       decl_abi *abi = calloc(1, sizeof(*abi));
-       abi->convention = strdup(convention);
-       return abi;
-}
-
-static inline void free_decl_abi(decl_abi *abi) {
-       if (abi->token) {
-               free(abi->token);
-       }
-       free(abi->convention);
-       free(abi);
-}
-
-typedef struct decl_callinfo {
-       void *sym;
-       void *info;
-       size_t argc;
-       void **args;
-       void **rval;
-} decl_callinfo;
-
-typedef struct decl {
-       decl_abi *abi;
-       decl_arg *func;
-       decl_args *args;
-       struct impl *impl;
-       decl_callinfo call;
-} decl;
-
-static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
-       decl *d = calloc(1, sizeof(*d));
-       d->abi = abi;
-       d->func = func;
-       d->args = args;
-       return d;
-}
-
-static inline void free_decl(decl *d) {
-       free_decl_abi(d->abi);
-       free_decl_arg(d->func);
-       if (d->args) {
-               free_decl_args(d->args);
-       }
-       free(d);
-}
-
-typedef struct decls {
-       size_t count;
-       decl **list;
-} decls;
-
-static inline decls *add_decl(decls *decls, decl *decl) {
-       if (!decls) {
-               decls = calloc(1, sizeof(*decls));
-       }
-       decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
-       decls->list[decls->count-1] = decl;
-       return decls;
-}
-
-static inline void free_decls(decls *decls) {
-       size_t i;
-
-       for (i = 0; i < decls->count; ++i) {
-               free_decl(decls->list[i]);
-       }
-       free(decls->list);
-       free(decls);
-}
-
-
-typedef struct decl_struct {
-       PSI_Token *token;
-       char *name;
-       decl_args *args;
-       size_t size;
-       size_t align;
-       struct {
-               void *type;
-               void (*dtor)(void *type);
-       } engine;
-} decl_struct;
-
-static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
-       decl_struct *s = calloc(1, sizeof(*s));
-       s->name = strdup(name);
-       s->args = args;
-       return s;
-}
-
-static inline void free_decl_struct(decl_struct *s) {
-       if (s->token) {
-               free(s->token);
-       }
-       if (s->args) {
-               free_decl_args(s->args);
-       }
-       if (s->engine.type && s->engine.dtor) {
-               s->engine.dtor(s->engine.type);
-       }
-       free(s->name);
-       free(s);
-}
-
-typedef struct decl_structs {
-       size_t count;
-       decl_struct **list;
-} decl_structs;
-
-static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
-       if (!ss) {
-               ss = calloc(1, sizeof(*ss));
-       }
-       ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
-       ss->list[ss->count-1] = s;
-       return ss;
-}
-
-static inline void free_decl_structs(decl_structs *ss) {
-       size_t i;
-
-       for (i = 0; i < ss->count; ++i) {
-               free_decl_struct(ss->list[i]);
-       }
-       free(ss->list);
-       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;
-} impl_type;
-
-static inline impl_type *init_impl_type(token_t type, const char *name) {
-       impl_type *t = calloc(1, sizeof(*t));
-
-       t->type = type;
-       t->name = strdup(name);
-       return t;
-}
-
-static inline void free_impl_type(impl_type *type) {
-       free(type->name);
-       free(type);
-}
-
-typedef struct impl_var {
-       PSI_Token *token;
-       char *name;
-       struct impl_arg *arg;
-       unsigned reference:1;
-} impl_var;
-
-static inline impl_var *init_impl_var(const char *name, int is_reference) {
-       impl_var *var = calloc(1, sizeof(*var));
-       var->name = strdup(name);
-       var->reference = 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);
-       }
-       free(var->name);
-       free(var);
-}
-
-typedef struct impl_def_val {
-       token_t type;
-       char *text;
-} impl_def_val;
-
-static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
-       impl_def_val *def = calloc(1, sizeof(*def));
-       def->type = t;
-       def->text = strdup(text);
-       return def;
-}
-
-static inline void free_impl_def_val(impl_def_val *def) {
-       free(def->text);
-       free(def);
-}
-
-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 = calloc(1, 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, const char *name, impl_def_val *val) {
-       constant *c = calloc(1, 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);
-}
-
-typedef struct impl_arg {
-       impl_type *type;
-       impl_var *var;
-       impl_def_val *def;
-       impl_val val;
-       zval *_zv;
-} impl_arg;
-
-static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
-       impl_arg *arg = calloc(1, sizeof(*arg));
-       arg->type = type;
-       arg->var = var;
-       arg->var->arg = arg;
-       arg->def = def;
-       return arg;
-}
-
-static inline void free_impl_arg(impl_arg *arg) {
-       free_impl_type(arg->type);
-       free_impl_var(arg->var);
-       if (arg->def) {
-               free_impl_def_val(arg->def);
-       }
-       free(arg);
-}
-
-typedef struct impl_vararg {
-       impl_arg *name;
-       struct impl_args *args;
-       token_t *types;
-       impl_val *values;
-       void **free_list;
-} impl_vararg;
-
-typedef struct impl_args {
-       impl_arg **args;
-       size_t count;
-       impl_vararg vararg;
-} impl_args;
-
-static inline impl_args *init_impl_args(impl_arg *arg) {
-       impl_args *args = calloc(1, sizeof(*args));
-       if (arg) {
-               args->count = 1;
-               args->args = calloc(1, sizeof(*args->args));
-               args->args[0] = arg;
-       }
-       return args;
-}
-
-static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
-       args->args = realloc(args->args, ++args->count * sizeof(*args->args));
-       args->args[args->count-1] = arg;
-       return args;
-}
-
-static inline void free_impl_args(impl_args *args) {
-       size_t i;
-
-       for (i = 0; i < args->count; ++i) {
-               free_impl_arg(args->args[i]);
-       }
-       if (args->vararg.name) {
-               free_impl_arg(args->vararg.name);
-       }
-       free(args->args);
-       free(args);
-}
-
-typedef struct impl_func {
-       PSI_Token *token;
-       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, int ret_reference) {
-       impl_func *func = calloc(1, 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;
-}
-
-static inline void free_impl_func(impl_func *f) {
-       if (f->token) {
-               free(f->token);
-       }
-       free_impl_type(f->return_type);
-       free_impl_args(f->args);
-       free(f->name);
-       free(f);
-}
-
-typedef struct num_exp {
-       PSI_Token *token;
-       token_t t;
-       union {
-               char *numb;
-               constant *cnst;
-               decl_var *dvar;
-               struct decl_enum_item *enm;
-       } u;
-       token_t operator;
-       int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
-       struct num_exp *operand;
-} num_exp;
-
-static inline num_exp *init_num_exp(token_t t, void *num) {
-       num_exp *exp = calloc(1, sizeof(*exp));
-       switch (exp->t = t) {
-       case PSI_T_NUMBER:
-       case PSI_T_NSNAME:
-               exp->u.numb = strdup(num);
-               break;
-       case PSI_T_NAME:
-               exp->u.dvar = num;
-               break;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       return exp;
-}
-
-static inline num_exp *copy_num_exp(num_exp *exp) {
-       decl_var *dvar;
-       num_exp *num = calloc(1, sizeof(*num));
-
-       memcpy(num, exp, sizeof(*num));
-
-       if (num->token) {
-               num->token = PSI_TokenCopy(num->token);
-       }
-       if (num->operand) {
-               num->operand = copy_num_exp(num->operand);
-       }
-       switch (num->t) {
-       case PSI_T_NUMBER:
-       case PSI_T_NSNAME:
-               num->u.numb = strdup(num->u.numb);
-               break;
-       case PSI_T_NAME:
-               dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size);
-               dvar->arg = num->u.dvar->arg;
-               if (num->u.dvar->token) {
-                       dvar->token = PSI_TokenCopy(num->u.dvar->token);
-               }
-               num->u.dvar = dvar;
-               break;
-       }
-       return num;
-}
-
-static inline void free_num_exp(num_exp *exp) {
-       if (exp->token) {
-               free(exp->token);
-       }
-       switch (exp->t) {
-       case PSI_T_NUMBER:
-               free(exp->u.numb);
-               break;
-       case PSI_T_NSNAME:
-               break;
-       case PSI_T_NAME:
-               free_decl_var(exp->u.dvar);
-               break;
-       case PSI_T_ENUM:
-               break;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       if (exp->operand) {
-               free_num_exp(exp->operand);
-       }
-       free(exp);
-}
-
-typedef struct decl_enum_item {
-       PSI_Token *token;
-       char *name;
-       num_exp *num;
-       num_exp inc;
-       struct decl_enum_item *prev;
-} decl_enum_item;
-
-static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) {
-       decl_enum_item *i = calloc(1, sizeof(*i));
-
-       i->name = strdup(name);
-       i->num = num;
-       return i;
-}
-
-static inline void free_decl_enum_item(decl_enum_item *i) {
-       if (i->token) {
-               free(i->token);
-       }
-       if (i->num && i->num != &i->inc) {
-               free_num_exp(i->num);
-       }
-       free(i->name);
-       free(i);
-}
-
-typedef struct decl_enum_items {
-       decl_enum_item **list;
-       size_t count;
-} decl_enum_items;
-
-static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) {
-       decl_enum_items *l = calloc(1, sizeof(*l));
-
-       if (i) {
-               l->count = 1;
-               l->list = calloc(1, sizeof(*l->list));
-               l->list[0] = i;
-       }
-       return l;
-}
-
-static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) {
-       l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1));
-       l->list[l->count] = i;
-       if (l->count) {
-               i->prev = l->list[l->count - 1];
-       }
-       ++l->count;
-       return l;
-}
-
-static inline void free_decl_enum_items(decl_enum_items *l) {
-       if (l->list) {
-               size_t j;
-
-               for (j = 0; j < l->count; ++j) {
-                       free_decl_enum_item(l->list[j]);
-               }
-               free(l->list);
-       }
-       free(l);
-}
-
-typedef struct decl_enum {
-       PSI_Token *token;
-       char *name;
-       decl_enum_items *items;
-} decl_enum;
-
-static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) {
-       decl_enum *e = calloc(1, sizeof(*e));
-
-       e->name = strdup(name);
-       e->items = l;
-       return e;
-}
-
-static inline void free_decl_enum(decl_enum *e) {
-       if (e->token) {
-               free(e->token);
-       }
-       if (e->items) {
-               free_decl_enum_items(e->items);
-       }
-       free(e->name);
-       free(e);
-}
-
-typedef struct decl_enums {
-       decl_enum **list;
-       size_t count;
-} decl_enums;
+#include "token.h"
+#include "types.h"
+#include "data.h"
 
-static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) {
-       if (!es) {
-               es = calloc(1, sizeof(*es));
-       }
-       es->list = realloc(es->list, ++es->count * sizeof(*es->list));
-       es->list[es->count-1] = e;
-       return es;
-}
-
-static inline void free_decl_enums(decl_enums *es) {
-       if (es->list) {
-               size_t j;
-
-               for (j = 0; j < es->count; ++j) {
-                       free_decl_enum(es->list[j]);
-               }
-       }
-       free(es->list);
-       free(es);
-}
-
-typedef struct let_calloc {
-       num_exp *nmemb;
-       num_exp *size;
-} let_calloc;
-
-static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
-       let_calloc *alloc = calloc(1, sizeof(*alloc));
-       alloc->nmemb = nmemb;
-       alloc->size = size;
-       return alloc;
-}
-
-static inline void free_let_calloc(let_calloc *alloc) {
-       free_num_exp(alloc->nmemb);
-       free_num_exp(alloc->size);
-       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;
-       let_func_handler handler;
-} let_func;
-
-static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
-       let_func *func = calloc(1, sizeof(*func));
-       func->type = type;
-       func->name = strdup(name);
-       func->var = var;
-       return func;
-}
-
-static inline void free_let_func(let_func *func) {
-       free_impl_var(func->var);
-       free(func->name);
-       free(func);
-}
-
-enum let_val_kind {
-       PSI_LET_NULL,
-       PSI_LET_NUMEXP,
-       PSI_LET_CALLOC,
-       PSI_LET_CALLBACK,
-       PSI_LET_FUNC,
-       PSI_LET_TMP,
-};
-#define PSI_LET_REFERENCE 0x1;
-typedef struct let_val {
-       enum let_val_kind kind;
-       union {
-               num_exp *num;
-               let_calloc *alloc;
-               let_callback *callback;
-               let_func *func;
-               decl_var *var;
-       } data;
-       union {
-               struct {
-                       unsigned is_reference:1;
-               } one;
-               unsigned all;
-       } flags;
-} let_val;
-
-static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
-       let_val *let = calloc(1, sizeof(*let));
-       switch (let->kind = kind) {
-       case PSI_LET_NULL:
-               break;
-       case PSI_LET_NUMEXP:
-               let->data.num = data;
-               break;
-       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;
-       case PSI_LET_TMP:
-               let->data.var = data;
-               break;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       return let;
-}
-
-static inline void free_let_val(let_val *let) {
-       switch (let->kind) {
-       case PSI_LET_NULL:
-               break;
-       case PSI_LET_NUMEXP:
-               free_num_exp(let->data.num);
-               break;
-       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;
-       case PSI_LET_TMP:
-               free_decl_var(let->data.var);
-               break;
-       EMPTY_SWITCH_DEFAULT_CASE();
-       }
-       free(let);
-}
-
-typedef struct let_stmt {
-       decl_var *var;
-       let_val *val;
-} let_stmt;
-
-static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
-       let_stmt *let = calloc(1, sizeof(*let));
-       let->var = var;
-       let->val = val;
-       return let;
-}
-
-static inline void free_let_stmt(let_stmt *stmt) {
-       if (stmt->val) {
-               if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
-                       free_decl_arg(stmt->var->arg);
-               }
-               free_let_val(stmt->val);
-       }
-       free_decl_var(stmt->var);
-       free(stmt);
-}
-
-struct set_value;
-
-typedef struct set_func {
-       PSI_Token *token;
-       token_t type;
-       char *name;
-       void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
-} set_func;
-
-static inline set_func *init_set_func(token_t type, const char *name) {
-       set_func *func = calloc(1, sizeof(*func));
-       func->type = type;
-       func->name = strdup(name);
-       return func;
-}
-
-static inline void free_set_func(set_func *func) {
-       if (func->token) {
-               free(func->token);
-       }
-       free(func->name);
-       free(func);
-}
-
-typedef struct set_value {
-       set_func *func;
-       decl_vars *vars;
-       num_exp *num;
-       struct {
-               struct set_value *set;
-               impl_val *val;
-       } outer;
-       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 = add_set_value(val->inner, inner);
-       inner->outer.set = val;
-       return val;
-}
-
-static inline void free_set_value(set_value *val) {
-       if (val->func) {
-               free_set_func(val->func);
-       }
-       if (val->vars) {
-               free_decl_vars(val->vars);
-       }
-       if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) {
-               free_set_values(val->inner);
-       }
-       if (val->num) {
-               free_num_exp(val->num);
-       }
-       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;
-       impl_arg *arg;
-} set_stmt;
-
-static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
-       set_stmt *set = calloc(1, sizeof(*set));
-       set->var = var;
-       set->val = val;
-       return set;
-}
-
-static inline void free_set_stmt(set_stmt *set) {
-       free_impl_var(set->var);
-       free_set_value(set->val);
-       free(set);
-}
-
-typedef struct return_stmt {
-       PSI_Token *token;
-       set_value *set;
-       decl_arg *decl;
-} return_stmt;
-
-static inline return_stmt *init_return_stmt(set_value *val) {
-       return_stmt *ret = calloc(1, sizeof(*ret));
-       ret->set = val;
-       return ret;
-}
-
-static inline void free_return_stmt(return_stmt *ret) {
-       if (ret->token) {
-               free(ret->token);
-       }
-       free_set_value(ret->set);
-       free(ret);
-}
-
-typedef struct free_call {
-       PSI_Token *token;
-       char *func;
-       decl_vars *vars;
-       decl *decl;
-} free_call;
-
-static inline free_call *init_free_call(const char *func, decl_vars *vars) {
-       free_call *f = calloc(1, sizeof(*f));
-       f->func = strdup(func);
-       f->vars = vars;
-       return f;
-}
-
-static inline void free_free_call(free_call *f) {
-       if (f->token) {
-               free(f->token);
-       }
-       free(f->func);
-       free_decl_vars(f->vars);
-       free(f);
-}
-
-typedef struct free_calls {
-       free_call **list;
-       size_t count;
-} free_calls;
-
-static inline free_calls *init_free_calls(free_call *f) {
-       free_calls *fcs = calloc(1, sizeof(*fcs));
-       if (f) {
-               fcs->count = 1;
-               fcs->list = calloc(1, sizeof(*fcs->list));
-               fcs->list[0] = f;
-       }
-       return fcs;
-}
-
-static inline void free_free_calls(free_calls *fcs) {
-       size_t i;
-
-       for (i = 0; i < fcs->count; ++i) {
-               free_free_call(fcs->list[i]);
-       }
-       free(fcs->list);
-       free(fcs);
-}
-
-static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
-       fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
-       fcs->list[fcs->count-1] = f;
-       return fcs;
-}
-
-typedef struct free_stmt {
-       free_calls *calls;
-} free_stmt;
-
-static inline free_stmt *init_free_stmt(free_calls *calls) {
-       free_stmt *f = calloc(1, sizeof(*f));
-       f->calls = calls;
-       return f;
-}
-
-static inline void free_free_stmt(free_stmt *f) {
-       free_free_calls(f->calls);
-       free(f);
-}
-
-typedef struct impl_stmt {
-       token_t type;
-       union {
-               let_stmt *let;
-               set_stmt *set;
-               return_stmt *ret;
-               free_stmt *fre;
-               void *ptr;
-       } s;
-} impl_stmt;
-
-static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
-       impl_stmt *stmt = calloc(1, sizeof(*stmt));
-       stmt->type = type;
-       stmt->s.ptr = ptr;
-       return stmt;
-}
-
-static inline void free_impl_stmt(impl_stmt *stmt) {
-       switch (stmt->type) {
-       case PSI_T_LET:
-               free_let_stmt(stmt->s.let);
-               break;
-       case PSI_T_SET:
-               free_set_stmt(stmt->s.set);
-               break;
-       case PSI_T_RETURN:
-               free_return_stmt(stmt->s.ret);
-               break;
-       case PSI_T_FREE:
-               free_free_stmt(stmt->s.fre);
-               break;
-       }
-       free(stmt);
-}
-
-typedef struct impl_stmts {
-       struct {
-               return_stmt **list;
-               size_t count;
-       } ret;
-       struct {
-               let_stmt **list;
-               size_t count;
-       } let;
-       struct {
-               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) {
-       list = realloc(list, count * sizeof(list));
-       ((void **)list)[count-1] = stmt;
-       return list;
-}
-
-static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
-       switch (stmt->type) {
-       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:
-               stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
-               break;
-       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;
-}
-
-static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
-       impl_stmts *stmts = calloc(1, sizeof(*stmts));
-       return add_impl_stmt(stmts, stmt);
-}
-
-static inline void free_impl_stmts(impl_stmts *stmts) {
-       size_t i;
-
-       for (i = 0; i < stmts->let.count; ++i) {
-               free_let_stmt(stmts->let.list[i]);
-       }
-       free(stmts->let.list);
-       for (i = 0; i < stmts->ret.count; ++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);
-}
-
-typedef struct impl {
-       impl_func *func;
-       impl_stmts *stmts;
-       decl *decl;
-} impl;
-
-static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
-       impl *i = calloc(1, sizeof(*i));
-       i->func = func;
-       i->stmts = stmts;
-       return i;
-}
-
-static inline void free_impl(impl *impl) {
-       free_impl_func(impl->func);
-       free_impl_stmts(impl->stmts);
-       free(impl);
-}
-
-typedef struct impls {
-       size_t count;
-       impl **list;
-} impls;
-
-static inline impls *add_impl(impls *impls, impl *impl) {
-       if (!impls) {
-               impls = calloc(1, sizeof(*impls));
-       }
-       impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
-       impls->list[impls->count-1] = impl;
-       return impls;
-}
-
-static void free_impls(impls *impls) {
-       size_t i;
-
-       for (i = 0; i < impls->count; ++i) {
-               free_impl(impls->list[i]);
-       }
-       free(impls->list);
-       free(impls);
-}
-
-typedef struct decl_file {
-       char *ln;
-       char *fn;
-} decl_file;
-
-static inline void free_decl_file(decl_file *file) {
-       if (file->ln) {
-               free(file->ln);
-       }
-       if (file->fn) {
-               free(file->fn);
-       }
-       memset(file, 0, sizeof(*file));
-}
-
-typedef struct decl_libs {
-       void **dl;
-       size_t count;
-} decl_libs;
-
-static inline void free_decl_libs(decl_libs *libs) {
-       if (libs->dl) {
-               size_t i;
-               for (i = 0; i < libs->count; ++i) {
-                       if (libs->dl[i]) {
-                               dlclose(libs->dl[i]);
-                       }
-               }
-               free(libs->dl);
-       }
-       memset(libs, 0, sizeof(*libs));
-}
-
-static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
-       libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
-       libs->dl[libs->count-1] = dlopened;
-}
-
-static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
-       unsigned i;
-
-       ZEND_ASSERT(var->arg->var != var);
-#if 0
-       fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n",
-                       var->name, var->pointer_level, var->arg->var->pointer_level,
-                       var->array_size, var->arg->var->array_size, ret_val);
-#endif
-       for (i = 0; i < var->pointer_level; ++i) {
-#if 0
-               fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr);
-#endif
-               ret_val = *(void **) ret_val;
-       }
-       return ret_val;
-}
-
-static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
-       impl_val *val, *val_ptr;
-       unsigned i;
-
-       ZEND_ASSERT(var->arg->var == var);
-#if 0
-       fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n",
-                       var->name, var->pointer_level, var->arg->var->pointer_level,
-                       var->array_size, var->arg->var->array_size);
-#endif
-       if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
-               return ptr;
-       }
-
-       val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
-       for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) {
-#if 0
-               fprintf(stderr, "++\n");
-#endif
-               val_ptr->ptr = (void **) val_ptr + 1;
-               val_ptr = val_ptr->ptr;
-       }
-       val_ptr->ptr = ptr;
-       return val;
-}
-
-static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
-       void *ptr = (char *) struct_ptr + set_arg->layout->pos;
-#if 0
-       fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr);
-#endif
-       return ptr;
-}
-
-
-#define PSI_ERROR 16
-#define PSI_WARNING 32
-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; \
-       union { \
-               decl_file file; \
-               decl_libs libs; \
-       } psi; \
-       psi_error_cb error; \
-       unsigned errors; \
-       unsigned flags
-typedef struct PSI_Data {
-       PSI_DATA_MEMBERS;
-} PSI_Data;
-
-static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
-       if (!dest) {
-               dest = malloc(sizeof(*dest));
-       }
-       memcpy(dest, src, sizeof(*dest));
-       memset(src, 0, sizeof(*src));
-       return dest;
-}
-
-static inline void PSI_DataDtor(PSI_Data *data) {
-       if (data->consts) {
-               free_constants(data->consts);
-       }
-       if (data->defs) {
-               free_decl_typedefs(data->defs);
-       }
-       if (data->structs) {
-               free_decl_structs(data->structs);
-       }
-       if (data->unions) {
-               free_decl_unions(data->unions);
-       }
-       if (data->enums) {
-               free_decl_enums(data->enums);
-       }
-       if (data->decls) {
-               free_decls(data->decls);
-       }
-       if (data->impls) {
-               free_impls(data->impls);
-       }
-       free_decl_file(&data->psi.file);
-}
-
-typedef struct PSI_Parser {
+struct psi_parser {
        PSI_DATA_MEMBERS;
        FILE *fp;
        token_t num;
        void *proc;
        unsigned line, col;
        char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
-} PSI_Parser;
-
-static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
-       return sizeof(PSI_Token) + token_len + fname_len + 2;
-}
-
-static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
-       PSI_Token *T;
-       size_t token_len, fname_len;
-       token_t token_typ;
-
-       if (P->cur < P->tok) {
-               return NULL;
-       }
-
-       token_typ = P->num;
-       token_len = P->cur - P->tok;
-       fname_len = strlen(P->psi.file.fn);
-
-       T = calloc(1, PSI_TokenAllocSize(token_len, fname_len));
-       T->type = token_typ;
-       T->size = token_len;
-       T->text = &T->buf[0];
-       T->file = &T->buf[token_len + 1];
-       T->line = P->line;
-       T->col = P->col;
-
-       memcpy(T->text, P->tok, token_len);
-       memcpy(T->file, P->psi.file.fn, fname_len);
-
-       return T;
-}
-
-static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
-       size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file));
-       PSI_Token *ptr = malloc(strct_len);
-
-       memcpy(ptr, src, strct_len);
-
-       ptr->text = &ptr->buf[0];
-       ptr->file = &ptr->buf[ptr->size + 1];
-
-       return ptr;
-}
-
-static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
-       va_list argv;
-       unsigned i;
-       PSI_Token *T = NULL;
-
-       va_start(argv, argc);
-       for (i = 0; i < argc; ++i) {
-               PSI_Token *arg = va_arg(argv, PSI_Token *);
-
-               if (T) {
-                       size_t token_len = T->size, fname_len = strlen(T->file);
-
-                       T = realloc(T, PSI_TokenAllocSize(T->size += arg->size + 1, fname_len));
-                       T->text = &T->buf[0];
-                       T->file = &T->buf[T->size + 1];
-                       T->buf[token_len] = ' ';
-                       memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
-                       memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1);
-               } else {
-                       T = PSI_TokenCopy(arg);
-                       T->type = PSI_T_NAME;
-               }
-       }
-       va_end(argv);
-
-       return T;
-}
-
-static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) {
-       va_list argv;
-       unsigned i;
-
-       va_start(argv, argc);
-       for (i = 0; i < argc; ++i) {
-               char *str = va_arg(argv, char *);
-               size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file);
-
-               T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 1, fname_len));
-               T->text = &T->buf[0];
-               T->file = &T->buf[T->size + 1];
-               T->buf[token_len] = ' ';
-               memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
-               memcpy(&T->buf[token_len + 1], str, str_len + 1);
-       }
-       va_end(argv);
-
-       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;
-}
-
-static inline uint64_t psi_hash(char *digest_buf, ...)
-{
-    uint64_t hash = 5381;
-    uint8_t c;
-    const uint8_t *ptr;
-    va_list argv;
-
-    va_start(argv, digest_buf);
-    while ((ptr = va_arg(argv, const uint8_t *))) {
-               while ((c = *ptr++)) {
-                       hash = ((hash << 5) + hash) + c;
-               }
-    }
-    va_end(argv);
-
-    if (digest_buf) {
-       sprintf(digest_buf, "%" PRIx64, hash);
-    }
-
-    return hash;
-}
-
-static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) {
-       char loc_buf[48];
-
-       sprintf(loc_buf, "%u%u", t->line, t->col);
-       return psi_hash(digest_buf, t->file, loc_buf, NULL);
-}
+};
 
 #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, ...);
-size_t PSI_ParserFill(PSI_Parser *P, size_t n);
-token_t PSI_ParserScan(PSI_Parser *P);
-void PSI_ParserParse(PSI_Parser *P, PSI_Token *src);
-void PSI_ParserDtor(PSI_Parser *P);
-void PSI_ParserFree(PSI_Parser **P);
+struct psi_parser *psi_parser_init(struct psi_parser *P, const char *filename, psi_error_cb error, unsigned flags);
+void psi_parser_syntax_error(struct psi_parser *P, const char *fn, size_t ln, const char *msg, ...);
+size_t psi_parser_fill(struct psi_parser *P, size_t n);
+token_t psi_parser_scan(struct psi_parser *P);
+void psi_parser_parse(struct psi_parser *P, struct psi_token *src);
+void psi_parser_dtor(struct psi_parser *P);
+void psi_parser_free(struct psi_parser **P);
 
 #endif
index 10279ed..3cfe130 100644 (file)
@@ -1,18 +1,25 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
 #include <stddef.h>
 #include <stdio.h>
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
 
-#include "parser.h"
 #include "parser_proc.h"
 
-void *PSI_ParserProcAlloc(void*(unsigned long));
-void PSI_ParserProcFree(void*, void(*)(void*));
-void PSI_ParserProc(void *, token_t, PSI_Token *, PSI_Parser *);
-void PSI_ParserProcTrace(FILE *, const char*);
+#include "parser.h"
+
+void *psi_parser_proc_Alloc(void*(unsigned long));
+void psi_parser_proc_Free(void*, void(*)(void*));
+void psi_parser_proc_(void *, token_t, struct psi_token *, struct psi_parser *);
+void psi_parser_proc_Trace(FILE *, const char*);
 
-PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags)
+struct psi_parser *psi_parser_init(struct psi_parser *P, const char *filename, psi_error_cb error, unsigned flags)
 {
        FILE *fp;
 
@@ -37,18 +44,18 @@ PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb err
        P->line = 1;
        P->error = error;
        P->flags = flags;
-       P->proc = PSI_ParserProcAlloc(malloc);
+       P->proc = psi_parser_proc_Alloc(malloc);
 
        if (flags & PSI_PARSER_DEBUG) {
-               PSI_ParserProcTrace(stderr, "PSI> ");
+               psi_parser_proc_Trace(stderr, "PSI> ");
        }
 
-       PSI_ParserFill(P, 0);
+       psi_parser_fill(P, 0);
 
        return P;
 }
 
-size_t PSI_ParserFill(PSI_Parser *P, size_t n)
+size_t psi_parser_fill(struct psi_parser *P, size_t n)
 {
        if (P->flags & PSI_PARSER_DEBUG) {
                fprintf(stderr, "PSI> Fill: n=%zu\n", n);
@@ -89,32 +96,32 @@ size_t PSI_ParserFill(PSI_Parser *P, size_t n)
        return P->lim - P->cur;
 }
 
-void PSI_ParserParse(PSI_Parser *P, PSI_Token *T)
+void psi_parser_parse(struct psi_parser *P, struct psi_token *T)
 {
        if (T) {
-               PSI_ParserProc(P->proc, T->type, T, P);
+               psi_parser_proc_(P->proc, T->type, T, P);
        } else {
-               PSI_ParserProc(P->proc, 0, NULL, P);
+               psi_parser_proc_(P->proc, 0, NULL, P);
        }
 }
 
-void PSI_ParserDtor(PSI_Parser *P)
+void psi_parser_dtor(struct psi_parser *P)
 {
-       PSI_ParserProcFree(P->proc, free);
+       psi_parser_proc_Free(P->proc, free);
 
        if (P->fp) {
                fclose(P->fp);
        }
 
-       PSI_DataDtor((PSI_Data *) P);
+       psi_data_dtor(PSI_DATA(P));
 
        memset(P, 0, sizeof(*P));
 }
 
-void PSI_ParserFree(PSI_Parser **P)
+void psi_parser_free(struct psi_parser **P)
 {
        if (*P) {
-               PSI_ParserDtor(*P);
+               psi_parser_dtor(*P);
                free(*P);
                *P = NULL;
        }
@@ -145,7 +152,7 @@ void PSI_ParserFree(PSI_Parser **P)
        ++P->line; \
        goto label
 
-token_t PSI_ParserScan(PSI_Parser *P)
+token_t psi_parser_scan(struct psi_parser *P)
 {
        for (;;) {
                ADDCOLS;
@@ -157,7 +164,7 @@ token_t PSI_ParserScan(PSI_Parser *P)
                re2c:define:YYCURSOR = P->cur;
                re2c:define:YYLIMIT = P->lim;
                re2c:define:YYMARKER = P->mrk;
-               re2c:define:YYFILL = "{ if (!PSI_ParserFill(P,@@)) RETURN(PSI_T_EOF); }";
+               re2c:define:YYFILL = "{ if (!psi_parser_fill(P,@@)) RETURN(PSI_T_EOF); }";
                re2c:yyfill:parameter = 0;
 
                B = [^a-zA-Z0-9_];
index e286bcd..f7d7d06 100644 (file)
 #define DEF(dn, dv)
 #define LET(nt, rule)
 #define PARSE(nt, rule) \
-       static void COUNTED(nt) (PSI_Parser *P rule)
+       static void COUNTED(nt) (struct psi_parser *P rule)
 #define PARSE_NAMED(nt, nt_name, rule) \
-       static void COUNTED(nt) (PSI_Parser *P NAMED(nt, nt_name) rule)
+       static void COUNTED(nt) (struct psi_parser *P NAMED(nt, nt_name) rule)
 #define PARSE_TYPED(nt, nt_name, rule) \
-       static void COUNTED(nt) (PSI_Parser *P TYPED(nt, nt_name) rule)
+       static void COUNTED(nt) (struct psi_parser *P TYPED(nt, nt_name) rule)
 #define TOKEN(t)
-#define NAMED(t, name) , PSI_Token *name
+#define NAMED(t, name) , struct psi_token *name
 #define TYPED(t, name) , TOKEN_TYPE_NAME(t) name
 #define TOKEN_TYPE_NAME(token) _##token##_type
 #define TOKEN_TYPE(token, type) typedef type TOKEN_TYPE_NAME(token);
@@ -37,12 +37,12 @@ DEF(%include, {
 void psi_error(int, const char *, int, const char *, ...);
 })
 
-DEF(%name, PSI_ParserProc)
+DEF(%name, psi_parser_proc_)
 DEF(%token_prefix, PSI_T_)
-DEF(%token_type, {PSI_Token *})
+DEF(%token_type, {struct psi_token *})
 DEF(%token_destructor, {free($$);})
 DEF(%default_destructor, {(void)P;})
-DEF(%extra_argument, {PSI_Parser *P})
+DEF(%extra_argument, {struct psi_parser *P})
 
 /* TOKEN is defined inside syntax_error */
 DEF(%syntax_error, {
@@ -253,8 +253,8 @@ PARSE_NAMED(enum_name, n,
        } else {
                char digest[17];
 
-               PSI_TokenHash(E, digest);
-               n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@");
+               psi_token_hash(E, digest);
+               n = psi_token_translit(psi_token_append(E, 1, digest), " ", "@");
        }
 }
 
@@ -300,8 +300,8 @@ PARSE_NAMED(union_name, n,
        } else {
                char digest[17];
 
-               PSI_TokenHash(U, digest);
-               n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@");
+               psi_token_hash(U, digest);
+               n = psi_token_translit(psi_token_append(U, 1, digest), " ", "@");
        }
 }
 
@@ -314,8 +314,8 @@ PARSE_NAMED(struct_name, n,
        } else {
                char digest[17];
 
-               PSI_TokenHash(S, digest);
-               n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@");
+               psi_token_hash(S, digest);
+               n = psi_token_translit(psi_token_append(S, 1, digest), " ", "@");
        }
 }
 
@@ -406,7 +406,7 @@ PARSE_TYPED(decl_typedef_body_ex, def,
                TYPED(decl_struct_args_block, args)
                TYPED(decl_var, var)) {
        def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var);
-       def->type->token = PSI_TokenCopy(N);
+       def->type->token = psi_token_copy(N);
        def->type->real.strct = init_decl_struct(N->text, args);
        def->type->real.strct->token = N;
        def->type->real.strct->align = as.pos;
@@ -418,7 +418,7 @@ PARSE_TYPED(decl_typedef_body_ex, def,
                TYPED(decl_struct_args_block, args)
                TYPED(decl_var, var)) {
        def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var);
-       def->type->token = PSI_TokenCopy(N);
+       def->type->token = psi_token_copy(N);
        def->type->real.unn = init_decl_union(N->text, args);
        def->type->real.unn->token = N;
        def->type->real.unn->align = as.pos;
@@ -429,7 +429,7 @@ PARSE_TYPED(decl_typedef_body_ex, def,
                NAMED(NAME, ALIAS)) {
        def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0));
        def->var->token = ALIAS;
-       def->type->token = PSI_TokenCopy(e->token);
+       def->type->token = psi_token_copy(e->token);
        def->type->real.enm = e;
 }
 
@@ -448,7 +448,7 @@ PARSE_TYPED(decl_typedef_body, def,
                TYPED(decl_func, func_)
                TYPED(decl_typedef_body_fn_args, args)) {
        def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var));
-       def->type->token = PSI_TokenCopy(func_->token);
+       def->type->token = psi_token_copy(func_->token);
        def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 PARSE_TYPED(decl_typedef_body, def,
@@ -503,7 +503,7 @@ PARSE_TYPED(decl_typedef_body, def,
                copy_decl_var(func_->var)
        );
        def->var->pointer_level = type_i;
-       def->type->token = PSI_TokenCopy(func_->token);
+       def->type->token = psi_token_copy(func_->token);
        def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 PARSE_TYPED(decl_typedef_body, def,
@@ -528,7 +528,7 @@ PARSE_TYPED(decl_typedef_body, def,
                copy_decl_var(func_->var)
        );
        def->var->pointer_level = type_i;
-       def->type->token = PSI_TokenCopy(func_->token);
+       def->type->token = psi_token_copy(func_->token);
        def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 
@@ -591,7 +591,7 @@ PARSE_TYPED(decl_typedef_body, def,
                copy_decl_var(func_->var)
        );
        def->var->pointer_level = type_i;
-       def->type->token = PSI_TokenCopy(func_->token);
+       def->type->token = psi_token_copy(func_->token);
        def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 
@@ -707,7 +707,7 @@ PARSE_NAMED(decl_scalar_type, type_,
                NAMED(SHORT, S)
                NAMED(decl_scalar_type_short, s)) {
        if (s) {
-               type_ = PSI_TokenCat(2, S, s);
+               type_ = psi_token_cat(2, S, s);
                free(S);
                free(s);
        } else {
@@ -730,7 +730,7 @@ PARSE_NAMED(decl_scalar_type, type_,
                NAMED(LONG, L)
                NAMED(decl_scalar_type_long, l)) {
        if (l) {
-               type_ = PSI_TokenCat(2, L, l);
+               type_ = psi_token_cat(2, L, l);
                free(L);
                free(l);
        } else {
@@ -748,7 +748,7 @@ PARSE_NAMED(decl_scalar_type_long, l,
                NAMED(LONG, L)
                NAMED(decl_scalar_type_long_long, ll)) {
        if (ll) {
-               l = PSI_TokenCat(2, L, ll);
+               l = psi_token_cat(2, L, ll);
                free(L);
                free(ll);
        } else {
@@ -765,7 +765,7 @@ PARSE_NAMED(decl_scalar_type_long_long, ll,
 PARSE_TYPED(decl_type, type_,
                NAMED(UNSIGNED, U)
                NAMED(decl_scalar_type, N)) {
-       PSI_Token *T = PSI_TokenCat(2, U, N);
+       struct psi_token *T = psi_token_cat(2, U, N);
        type_ = init_decl_type(T->type, T->text);
        type_->token = T;
        free(U);
@@ -774,7 +774,7 @@ PARSE_TYPED(decl_type, type_,
 PARSE_TYPED(decl_type, type_,
                NAMED(SIGNED, S)
                NAMED(decl_scalar_type, N)) {
-       PSI_Token *T = PSI_TokenCat(2, S, N);
+       struct psi_token *T = psi_token_cat(2, S, N);
        type_ = init_decl_type(T->type, T->text);
        type_->token = T;
        free(S);
@@ -955,7 +955,7 @@ PARSE_TYPED(num_exp, exp,
 PARSE_TYPED(num_exp, exp,
                TYPED(decl_var, var)) {
        exp = init_num_exp(PSI_T_NAME, var);
-       exp->token = PSI_TokenCopy(var->token);
+       exp->token = psi_token_copy(var->token);
 }
 PARSE_TYPED(num_exp, exp,
                TYPED(num_exp, exp_)
index 5d87612..81489d5 100644 (file)
@@ -1,4 +1,10 @@
 %include {
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
 #include <stddef.h>
 #include <assert.h>
 #include <stdlib.h>
index 4099877..0d0aa61 100644 (file)
@@ -1,4 +1,10 @@
 %include {
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
 #include <stddef.h>
 #include <assert.h>
 #include <stdlib.h>
 #include "parser.h"
 }
 %include { void psi_error(int, const char *, int, const char *, ...); }
-%name PSI_ParserProc
+%name psi_parser_proc_
 %token_prefix PSI_T_
-%token_type {PSI_Token *}
+%token_type {struct psi_token *}
 %token_destructor {free($$);}
 %default_destructor {(void)P;}
-%extra_argument {PSI_Parser *P}
+%extra_argument {struct psi_parser *P}
 %syntax_error { ++P->errors; if (TOKEN && TOKEN->type != PSI_T_EOF) { psi_error(PSI_WARNING, TOKEN->file, TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text); } else { psi_error(PSI_WARNING, P->psi.file.fn, P->line, "PSI syntax error: Unexpected end of input"); } }
 %nonassoc NAME.
 %left PLUS MINUS.
@@ -197,8 +203,8 @@ enum_name(n) ::= ENUM(E) optional_name(N). {
   free(E);
  } else {
   char digest[17];
-  PSI_TokenHash(E, digest);
-  n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@");
+  psi_token_hash(E, digest);
+  n = psi_token_translit(psi_token_append(E, 1, digest), " ", "@");
  }
 }
 decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. {
@@ -225,8 +231,8 @@ union_name(n) ::= UNION(U) optional_name(N). {
   free(U);
  } else {
   char digest[17];
-  PSI_TokenHash(U, digest);
-  n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@");
+  psi_token_hash(U, digest);
+  n = psi_token_translit(psi_token_append(U, 1, digest), " ", "@");
  }
 }
 struct_name(n) ::= STRUCT(S) optional_name(N). {
@@ -235,8 +241,8 @@ struct_name(n) ::= STRUCT(S) optional_name(N). {
   free(S);
  } else {
   char digest[17];
-  PSI_TokenHash(S, digest);
-  n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@");
+  psi_token_hash(S, digest);
+  n = psi_token_translit(psi_token_append(S, 1, digest), " ", "@");
  }
 }
 decl_struct_args_block(args_) ::= LBRACE struct_args(args) RBRACE. {
@@ -284,7 +290,7 @@ decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. {
 }
 decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
  def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var);
- def->type->token = PSI_TokenCopy(N);
+ def->type->token = psi_token_copy(N);
  def->type->real.strct = init_decl_struct(N->text, args);
  def->type->real.strct->token = N;
  def->type->real.strct->align = as.pos;
@@ -292,7 +298,7 @@ decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args
 }
 decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). {
  def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var);
- def->type->token = PSI_TokenCopy(N);
+ def->type->token = psi_token_copy(N);
  def->type->real.unn = init_decl_union(N->text, args);
  def->type->real.unn->token = N;
  def->type->real.unn->align = as.pos;
@@ -301,7 +307,7 @@ decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_
 decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). {
  def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0));
  def->var->token = ALIAS;
- def->type->token = PSI_TokenCopy(e->token);
+ def->type->token = psi_token_copy(e->token);
  def->type->real.enm = e;
 }
 decl_typedef_body(def) ::= decl_typedef_body_ex(def_). {
@@ -312,7 +318,7 @@ decl_typedef_body_fn_args(args) ::= LPAREN decl_args(args_) RPAREN. {
 }
 decl_typedef_body(def) ::= decl_func(func_) decl_typedef_body_fn_args(args). {
  def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var));
- def->type->token = PSI_TokenCopy(func_->token);
+ def->type->token = psi_token_copy(func_->token);
  def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_typedef_body(def) ::= decl_arg(arg). {
@@ -346,7 +352,7 @@ decl_typedef_body(def) ::= VOID(T) indirection(decl_i) LPAREN indirection(type_i
   copy_decl_var(func_->var)
  );
  def->var->pointer_level = type_i;
- def->type->token = PSI_TokenCopy(func_->token);
+ def->type->token = psi_token_copy(func_->token);
  def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). {
@@ -362,7 +368,7 @@ decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(typ
   copy_decl_var(func_->var)
  );
  def->var->pointer_level = type_i;
- def->type->token = PSI_TokenCopy(func_->token);
+ def->type->token = psi_token_copy(func_->token);
  def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_abi(abi) ::= NAME(T). {
@@ -399,7 +405,7 @@ decl_typedef_body(def) ::= const_decl_type(type_) indirection(decl_i) LPAREN ind
   copy_decl_var(func_->var)
  );
  def->var->pointer_level = type_i;
- def->type->token = PSI_TokenCopy(func_->token);
+ def->type->token = psi_token_copy(func_->token);
  def->type->real.func = init_decl(init_decl_abi("default"), func_, args);
 }
 decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). {
@@ -475,7 +481,7 @@ decl_scalar_type(type_) ::= CHAR(C). {
 }
 decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). {
  if (s) {
-  type_ = PSI_TokenCat(2, S, s);
+  type_ = psi_token_cat(2, S, s);
   free(S);
   free(s);
  } else {
@@ -493,7 +499,7 @@ decl_scalar_type(type_) ::= INT(I). {
 }
 decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). {
  if (l) {
-  type_ = PSI_TokenCat(2, L, l);
+  type_ = psi_token_cat(2, L, l);
   free(L);
   free(l);
  } else {
@@ -508,7 +514,7 @@ decl_scalar_type_long(l) ::= DOUBLE(D). {
 }
 decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). {
  if (ll) {
-  l = PSI_TokenCat(2, L, ll);
+  l = psi_token_cat(2, L, ll);
   free(L);
   free(ll);
  } else {
@@ -522,14 +528,14 @@ decl_scalar_type_long_long(ll) ::= INT(I). {
  ll = I;
 }
 decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). {
PSI_Token *T = PSI_TokenCat(2, U, N);
struct psi_token *T = psi_token_cat(2, U, N);
  type_ = init_decl_type(T->type, T->text);
  type_->token = T;
  free(U);
  free(N);
 }
 decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). {
PSI_Token *T = PSI_TokenCat(2, S, N);
struct psi_token *T = psi_token_cat(2, S, N);
  type_ = init_decl_type(T->type, T->text);
  type_->token = T;
  free(S);
@@ -637,7 +643,7 @@ num_exp(exp) ::= num_exp_token(tok). {
 }
 num_exp(exp) ::= decl_var(var). {
  exp = init_num_exp(PSI_T_NAME, var);
- exp->token = PSI_TokenCopy(var->token);
+ exp->token = psi_token_copy(var->token);
 }
 num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). {
  exp_->operator = operator_->type;
diff --git a/src/token.c b/src/token.c
new file mode 100644 (file)
index 0000000..a9675f8
--- /dev/null
@@ -0,0 +1,142 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/param.h>
+
+#include "parser_proc.h"
+#include "token.h"
+#include "parser.h"
+
+size_t psi_token_alloc_size(size_t token_len, size_t fname_len) {
+       return sizeof(struct psi_token) + token_len + fname_len + 2;
+}
+
+struct psi_token *psi_token_alloc(struct psi_parser *P) {
+       struct psi_token *T;
+       size_t token_len, fname_len;
+       token_t token_typ;
+
+       if (P->cur < P->tok) {
+               return NULL;
+       }
+
+       token_typ = P->num;
+       token_len = P->cur - P->tok;
+       fname_len = strlen(P->psi.file.fn);
+
+       T = calloc(1, psi_token_alloc_size(token_len, fname_len));
+       T->type = token_typ;
+       T->size = token_len;
+       T->text = &T->buf[0];
+       T->file = &T->buf[token_len + 1];
+       T->line = P->line;
+       T->col = P->col;
+
+       memcpy(T->text, P->tok, token_len);
+       memcpy(T->file, P->psi.file.fn, fname_len);
+
+       return T;
+}
+
+struct psi_token *psi_token_copy(struct psi_token *src) {
+       size_t strct_len = psi_token_alloc_size(src->size, strlen(src->file));
+       struct psi_token *ptr = malloc(strct_len);
+
+       memcpy(ptr, src, strct_len);
+
+       ptr->text = &ptr->buf[0];
+       ptr->file = &ptr->buf[ptr->size + 1];
+
+       return ptr;
+}
+
+struct psi_token *psi_token_cat(unsigned argc, ...) {
+       va_list argv;
+       unsigned i;
+       struct psi_token *T = NULL;
+
+       va_start(argv, argc);
+       for (i = 0; i < argc; ++i) {
+               struct psi_token *arg = va_arg(argv, struct psi_token *);
+
+               if (T) {
+                       size_t token_len = T->size, fname_len = strlen(T->file);
+
+                       T = realloc(T, psi_token_alloc_size(T->size += arg->size + 1, fname_len));
+                       T->text = &T->buf[0];
+                       T->file = &T->buf[T->size + 1];
+                       T->buf[token_len] = ' ';
+                       memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
+                       memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1);
+               } else {
+                       T = psi_token_copy(arg);
+                       T->type = PSI_T_NAME;
+               }
+       }
+       va_end(argv);
+
+       return T;
+}
+
+struct psi_token *psi_token_append(struct psi_token *T, unsigned argc, ...) {
+       va_list argv;
+       unsigned i;
+
+       va_start(argv, argc);
+       for (i = 0; i < argc; ++i) {
+               char *str = va_arg(argv, char *);
+               size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file);
+
+               T = realloc(T, psi_token_alloc_size(T->size += str_len + 1, fname_len));
+               T->text = &T->buf[0];
+               T->file = &T->buf[T->size + 1];
+               T->buf[token_len] = ' ';
+               memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
+               memcpy(&T->buf[token_len + 1], str, str_len + 1);
+       }
+       va_end(argv);
+
+       return T;
+}
+
+char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen);
+struct psi_token *psi_token_translit(struct psi_token *T, char *from, char *to) {
+       php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to)));
+       return T;
+}
+
+static inline uint64_t psi_hash(char *digest_buf, ...)
+{
+    uint64_t hash = 5381;
+    uint8_t c;
+    const uint8_t *ptr;
+    va_list argv;
+
+    va_start(argv, digest_buf);
+    while ((ptr = va_arg(argv, const uint8_t *))) {
+               while ((c = *ptr++)) {
+                       hash = ((hash << 5) + hash) + c;
+               }
+    }
+    va_end(argv);
+
+    if (digest_buf) {
+       sprintf(digest_buf, "%" PRIx64, hash);
+    }
+
+    return hash;
+}
+
+uint64_t psi_token_hash(struct psi_token *t, char *digest_buf) {
+       char loc_buf[48];
+
+       sprintf(loc_buf, "%u%u", t->line, t->col);
+       return psi_hash(digest_buf, t->file, loc_buf, NULL);
+}
diff --git a/src/token.h b/src/token.h
new file mode 100644 (file)
index 0000000..c7ce751
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef _PSI_TOKEN_H
+#define _PSI_TOKEN_H
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "parser_proc.h"
+
+#define PSI_T_POINTER PSI_T_ASTERISK
+#define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
+
+typedef int token_t;
+
+static inline size_t psi_t_alignment(token_t t)
+{
+#define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T;
+       switch (t) {
+       PSI_ALIGNOF(INT8);
+       PSI_ALIGNOF(UINT8);
+       PSI_ALIGNOF(INT16);
+       PSI_ALIGNOF(UINT16);
+       PSI_ALIGNOF(INT32);
+       PSI_ALIGNOF(UINT32);
+       PSI_ALIGNOF(INT64);
+       PSI_ALIGNOF(UINT64);
+       case PSI_T_FLOAT:
+               return ALIGNOF_FLOAT;
+       case PSI_T_DOUBLE:
+               return ALIGNOF_DOUBLE;
+       case PSI_T_POINTER:
+       case PSI_T_FUNCTION:
+               return ALIGNOF_VOID_P;
+       case PSI_T_ENUM:
+               return ALIGNOF_INT;
+       default:
+               assert(0);
+       }
+       return 0;
+}
+
+static inline size_t psi_t_size(token_t t)
+{
+#define PSI_SIZEOF(T) case PSI_T_## T : return SIZEOF_## T ##_T;
+       switch (t) {
+       PSI_SIZEOF(INT8);
+       PSI_SIZEOF(UINT8);
+       PSI_SIZEOF(INT16);
+       PSI_SIZEOF(UINT16);
+       PSI_SIZEOF(INT32);
+       PSI_SIZEOF(UINT32);
+       PSI_SIZEOF(INT64);
+       PSI_SIZEOF(UINT64);
+       case PSI_T_FLOAT:
+               return SIZEOF_FLOAT;
+       case PSI_T_DOUBLE:
+               return SIZEOF_DOUBLE;
+       case PSI_T_POINTER:
+       case PSI_T_FUNCTION:
+               return SIZEOF_VOID_P;
+       case PSI_T_ENUM:
+               return SIZEOF_INT;
+       default:
+               assert(0);
+       }
+       return 0;
+}
+
+struct psi_token {
+       token_t type;
+       unsigned size, line, col;
+       char *text, *file;
+       char buf[1];
+};
+
+struct psi_parser;
+
+struct psi_token *psi_token_alloc(struct psi_parser *P);
+size_t psi_token_alloc_size(size_t token_len, size_t fname_len);
+struct psi_token *psi_token_copy(struct psi_token *src);
+struct psi_token *psi_token_cat(unsigned argc, ...);
+struct psi_token *psi_token_append(struct psi_token *T, unsigned argc, ...);
+struct psi_token *psi_token_translit(struct psi_token *T, char *from, char *to);
+uint64_t psi_token_hash(struct psi_token *t, char *digest_buf);
+
+#endif
diff --git a/src/types.h b/src/types.h
new file mode 100644 (file)
index 0000000..1b91a0c
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef _PSI_TYPES_H
+#define _PSI_TYPES_H
+
+#include "Zend/zend_API.h"
+typedef struct zend_fcall {
+       zend_fcall_info fci;
+       zend_fcall_info_cache fcc;
+} zend_fcall;
+
+#include "token.h"
+
+#include "types/impl_val.h"
+#include "types/decl_type.h"
+#include "types/decl_var.h"
+#include "types/decl_struct_layout.h"
+#include "types/decl_arg.h"
+#include "types/decl_typedefs.h"
+#include "types/decl_vars.h"
+#include "types/decl_args.h"
+#include "types/decl_abi.h"
+#include "types/decl_callinfo.h"
+#include "types/decl.h"
+#include "types/decls.h"
+#include "types/decl_struct.h"
+#include "types/decl_structs.h"
+#include "types/decl_union.h"
+#include "types/decl_unions.h"
+#include "types/impl_type.h"
+#include "types/impl_var.h"
+#include "types/impl_def_val.h"
+#include "types/const_type.h"
+#include "types/constant.h"
+#include "types/constants.h"
+#include "types/impl_arg.h"
+#include "types/impl_args.h"
+#include "types/impl_func.h"
+#include "types/num_exp.h"
+#include "types/decl_enum_item.h"
+#include "types/decl_enum_items.h"
+#include "types/decl_enum.h"
+#include "types/decl_enums.h"
+#include "types/let_calloc.h"
+#include "types/let_callback.h"
+#include "types/let_func.h"
+#include "types/let_val.h"
+#include "types/let_stmt.h"
+#include "types/set_func.h"
+#include "types/set_value.h"
+#include "types/set_values.h"
+#include "types/set_stmt.h"
+#include "types/return_stmt.h"
+#include "types/free_call.h"
+#include "types/free_calls.h"
+#include "types/free_stmt.h"
+#include "types/impl_stmt.h"
+#include "types/impl_stmts.h"
+#include "types/impl.h"
+#include "types/impls.h"
+#include "types/decl_file.h"
+#include "types/decl_libs.h"
+
+
+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;
+       }
+}
+
+static inline decl_type *real_decl_type(decl_type *type) {
+       while (weak_decl_type(type)) {
+               type = type->real.def->type;
+       }
+       return type;
+}
+
+static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
+       unsigned i;
+
+       ZEND_ASSERT(var->arg->var != var);
+#if 0
+       fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n",
+                       var->name, var->pointer_level, var->arg->var->pointer_level,
+                       var->array_size, var->arg->var->array_size, ret_val);
+#endif
+       for (i = 0; i < var->pointer_level; ++i) {
+#if 0
+               fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr);
+#endif
+               ret_val = *(void **) ret_val;
+       }
+       return ret_val;
+}
+
+static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
+       impl_val *val, *val_ptr;
+       unsigned i;
+
+       ZEND_ASSERT(var->arg->var == var);
+#if 0
+       fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n",
+                       var->name, var->pointer_level, var->arg->var->pointer_level,
+                       var->array_size, var->arg->var->array_size);
+#endif
+       if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
+               return ptr;
+       }
+
+       val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
+       for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) {
+#if 0
+               fprintf(stderr, "++\n");
+#endif
+               val_ptr->ptr = (void **) val_ptr + 1;
+               val_ptr = val_ptr->ptr;
+       }
+       val_ptr->ptr = ptr;
+       return val;
+}
+
+static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
+       void *ptr = (char *) struct_ptr + set_arg->layout->pos;
+#if 0
+       fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr);
+#endif
+       return ptr;
+}
+
+
+#define PSI_ERROR 16
+#define PSI_WARNING 32
+typedef void (*psi_error_cb)(void *context, struct psi_token *token, int type, const char *msg, ...);
+
+#endif
diff --git a/src/types/const_type.h b/src/types/const_type.h
new file mode 100644 (file)
index 0000000..af9efb7
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _PSI_TYPES_CONST_TYPE_H
+#define _PSI_TYPES_CONST_TYPE_H
+
+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 = calloc(1, 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);
+}
+
+#endif
diff --git a/src/types/constant.h b/src/types/constant.h
new file mode 100644 (file)
index 0000000..85e467b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _PSI_TYPES_CONSTANT_H
+#define _PSI_TYPES_CONSTANT_H
+
+typedef struct constant {
+       const_type *type;
+       char *name;
+       impl_def_val *val;
+} constant;
+
+static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
+       constant *c = calloc(1, 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);
+}
+
+#endif
diff --git a/src/types/constants.h b/src/types/constants.h
new file mode 100644 (file)
index 0000000..36352ab
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_CONSTANTS_H
+#define _PSI_TYPES_CONSTANTS_H
+
+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);
+}
+
+#endif
diff --git a/src/types/decl.h b/src/types/decl.h
new file mode 100644 (file)
index 0000000..0a84998
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _PSI_TYPES_DECL_H
+#define _PSI_TYPES_DECL_H
+
+typedef struct decl {
+       decl_abi *abi;
+       decl_arg *func;
+       decl_args *args;
+       struct impl *impl;
+       decl_callinfo call;
+} decl;
+
+static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
+       decl *d = calloc(1, sizeof(*d));
+       d->abi = abi;
+       d->func = func;
+       d->args = args;
+       return d;
+}
+
+static inline void free_decl(decl *d) {
+       free_decl_abi(d->abi);
+       free_decl_arg(d->func);
+       if (d->args) {
+               free_decl_args(d->args);
+       }
+       free(d);
+}
+
+#endif
diff --git a/src/types/decl_abi.h b/src/types/decl_abi.h
new file mode 100644 (file)
index 0000000..48731a3
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _PSI_TYPES_DECL_ABI_H
+#define _PSI_TYPES_DECL_ABI_H
+
+typedef struct decl_abi {
+       struct psi_token *token;
+       char *convention;
+} decl_abi;
+
+static inline decl_abi *init_decl_abi(const char *convention) {
+       decl_abi *abi = calloc(1, sizeof(*abi));
+       abi->convention = strdup(convention);
+       return abi;
+}
+
+static inline void free_decl_abi(decl_abi *abi) {
+       if (abi->token) {
+               free(abi->token);
+       }
+       free(abi->convention);
+       free(abi);
+}
+
+#endif
diff --git a/src/types/decl_arg.h b/src/types/decl_arg.h
new file mode 100644 (file)
index 0000000..22eb0f0
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _PSI_TYPES_DECL_ARG_H
+#define _PSI_TYPES_DECL_ARG_H
+
+typedef struct decl_arg {
+       struct psi_token *token;
+       decl_type *type;
+       decl_var *var;
+       decl_struct_layout *layout;
+       impl_val val;
+       void *ptr;
+       void *let;
+       void *mem;
+} decl_arg;
+
+static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
+       decl_arg *arg = calloc(1, sizeof(*arg));
+       arg->token = var->token;
+       arg->type = type;
+       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) {
+               free_decl_struct_layout(arg->layout);
+       }
+       free(arg);
+}
+
+#endif
diff --git a/src/types/decl_args.h b/src/types/decl_args.h
new file mode 100644 (file)
index 0000000..5987520
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _PSI_TYPES_DECL_ARGS_H
+#define _PSI_TYPES_DECL_ARGS_H
+
+typedef struct decl_args {
+       decl_arg **args;
+       size_t count;
+       unsigned varargs:1;
+} decl_args;
+
+static inline decl_args *init_decl_args(decl_arg *arg) {
+       decl_args *args = calloc(1, sizeof(*args));
+       if (arg) {
+               args->count = 1;
+               args->args = calloc(1, sizeof(*args->args));
+               args->args[0] = arg;
+       }
+       return args;
+}
+
+static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
+       args->args = realloc(args->args, ++args->count * sizeof(*args->args));
+       args->args[args->count-1] = arg;
+       return args;
+}
+
+static inline void free_decl_args(decl_args *args) {
+       size_t i;
+
+       for (i = 0; i < args->count; ++i) {
+               free_decl_arg(args->args[i]);
+       }
+       free(args->args);
+       free(args);
+}
+
+#endif
diff --git a/src/types/decl_callinfo.h b/src/types/decl_callinfo.h
new file mode 100644 (file)
index 0000000..13e4262
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _PSI_TYPES_DECL_CALLINFO_H
+#define _PSI_TYPES_DECL_CALLINFO_H
+
+typedef struct decl_callinfo {
+       void *sym;
+       void *info;
+       size_t argc;
+       void **args;
+       void **rval;
+} decl_callinfo;
+
+#endif
diff --git a/src/types/decl_enum.h b/src/types/decl_enum.h
new file mode 100644 (file)
index 0000000..4a616af
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _PSI_TYPES_DECL_ENUM_H
+#define _PSI_TYPES_DECL_ENUM_H
+
+typedef struct decl_enum {
+       struct psi_token *token;
+       char *name;
+       decl_enum_items *items;
+} decl_enum;
+
+static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) {
+       decl_enum *e = calloc(1, sizeof(*e));
+
+       e->name = strdup(name);
+       e->items = l;
+       return e;
+}
+
+static inline void free_decl_enum(decl_enum *e) {
+       if (e->token) {
+               free(e->token);
+       }
+       if (e->items) {
+               free_decl_enum_items(e->items);
+       }
+       free(e->name);
+       free(e);
+}
+
+#endif
diff --git a/src/types/decl_enum_item.h b/src/types/decl_enum_item.h
new file mode 100644 (file)
index 0000000..3b976de
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _PSI_TYPES_DECL_ENUM_ITEM_H
+#define _PSI_TYPES_DECL_ENUM_ITEM_H
+
+typedef struct decl_enum_item {
+       struct psi_token *token;
+       char *name;
+       num_exp *num;
+       num_exp inc;
+       struct decl_enum_item *prev;
+} decl_enum_item;
+
+static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) {
+       decl_enum_item *i = calloc(1, sizeof(*i));
+
+       i->name = strdup(name);
+       i->num = num;
+       return i;
+}
+
+static inline void free_decl_enum_item(decl_enum_item *i) {
+       if (i->token) {
+               free(i->token);
+       }
+       if (i->num && i->num != &i->inc) {
+               free_num_exp(i->num);
+       }
+       free(i->name);
+       free(i);
+}
+
+#endif
diff --git a/src/types/decl_enum_items.h b/src/types/decl_enum_items.h
new file mode 100644 (file)
index 0000000..0debc0a
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _PSI_TYPES_DECL_ENUM_ITEMS_H
+#define _PSI_TYPES_DECL_ENUM_ITEMS_H
+
+typedef struct decl_enum_items {
+       decl_enum_item **list;
+       size_t count;
+} decl_enum_items;
+
+static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) {
+       decl_enum_items *l = calloc(1, sizeof(*l));
+
+       if (i) {
+               l->count = 1;
+               l->list = calloc(1, sizeof(*l->list));
+               l->list[0] = i;
+       }
+       return l;
+}
+
+static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) {
+       l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1));
+       l->list[l->count] = i;
+       if (l->count) {
+               i->prev = l->list[l->count - 1];
+       }
+       ++l->count;
+       return l;
+}
+
+static inline void free_decl_enum_items(decl_enum_items *l) {
+       if (l->list) {
+               size_t j;
+
+               for (j = 0; j < l->count; ++j) {
+                       free_decl_enum_item(l->list[j]);
+               }
+               free(l->list);
+       }
+       free(l);
+}
+
+#endif
diff --git a/src/types/decl_enums.h b/src/types/decl_enums.h
new file mode 100644 (file)
index 0000000..61a3f72
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _PSI_TYPES_DECL_ENUMS_H
+#define _PSI_TYPES_DECL_ENUMS_H
+
+typedef struct decl_enums {
+       decl_enum **list;
+       size_t count;
+} decl_enums;
+
+static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) {
+       if (!es) {
+               es = calloc(1, sizeof(*es));
+       }
+       es->list = realloc(es->list, ++es->count * sizeof(*es->list));
+       es->list[es->count-1] = e;
+       return es;
+}
+
+static inline void free_decl_enums(decl_enums *es) {
+       if (es->list) {
+               size_t j;
+
+               for (j = 0; j < es->count; ++j) {
+                       free_decl_enum(es->list[j]);
+               }
+       }
+       free(es->list);
+       free(es);
+}
+
+#endif
diff --git a/src/types/decl_file.h b/src/types/decl_file.h
new file mode 100644 (file)
index 0000000..3eb314c
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _PSI_TYPES_DECL_FILE_H
+#define _PSI_TYPES_DECL_FILE_H
+
+typedef struct decl_file {
+       char *ln;
+       char *fn;
+} decl_file;
+
+static inline void free_decl_file(decl_file *file) {
+       if (file->ln) {
+               free(file->ln);
+       }
+       if (file->fn) {
+               free(file->fn);
+       }
+       memset(file, 0, sizeof(*file));
+}
+
+#endif
diff --git a/src/types/decl_libs.h b/src/types/decl_libs.h
new file mode 100644 (file)
index 0000000..0ac669e
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _PSI_TYPES_DECL_LIBS_H
+#define _PSI_TYPES_DECL_LIBS_H
+
+typedef struct decl_libs {
+       void **dl;
+       size_t count;
+} decl_libs;
+
+static inline void free_decl_libs(decl_libs *libs) {
+       if (libs->dl) {
+               size_t i;
+               for (i = 0; i < libs->count; ++i) {
+                       if (libs->dl[i]) {
+                               dlclose(libs->dl[i]);
+                       }
+               }
+               free(libs->dl);
+       }
+       memset(libs, 0, sizeof(*libs));
+}
+
+static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
+       libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
+       libs->dl[libs->count-1] = dlopened;
+}
+
+#endif
diff --git a/src/types/decl_struct.h b/src/types/decl_struct.h
new file mode 100644 (file)
index 0000000..439b4e9
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _PSI_TYPES_DECL_STRUCT_H
+#define _PSI_TYPES_DECL_STRUCT_H
+
+typedef struct decl_struct {
+       struct psi_token *token;
+       char *name;
+       decl_args *args;
+       size_t size;
+       size_t align;
+       struct {
+               void *type;
+               void (*dtor)(void *type);
+       } engine;
+} decl_struct;
+
+static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
+       decl_struct *s = calloc(1, sizeof(*s));
+       s->name = strdup(name);
+       s->args = args;
+       return s;
+}
+
+static inline void free_decl_struct(decl_struct *s) {
+       if (s->token) {
+               free(s->token);
+       }
+       if (s->args) {
+               free_decl_args(s->args);
+       }
+       if (s->engine.type && s->engine.dtor) {
+               s->engine.dtor(s->engine.type);
+       }
+       free(s->name);
+       free(s);
+}
+
+#endif
diff --git a/src/types/decl_struct_layout.h b/src/types/decl_struct_layout.h
new file mode 100644 (file)
index 0000000..1fcb9f0
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _PSI_TYPES_DECL_STRUCT_LAYOUT_H
+#define _PSI_TYPES_DECL_STRUCT_LAYOUT_H
+
+typedef struct decl_struct_layout {
+       size_t pos;
+       size_t len;
+} decl_struct_layout;
+
+static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
+       decl_struct_layout *l = calloc(1, sizeof(*l));
+       ZEND_ASSERT(pos+len);
+       l->pos = pos;
+       l->len = len;
+       return l;
+}
+
+static inline void free_decl_struct_layout(decl_struct_layout *l) {
+       free(l);
+}
+
+#endif
diff --git a/src/types/decl_structs.h b/src/types/decl_structs.h
new file mode 100644 (file)
index 0000000..1db3396
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_DECL_STRUCTS_H
+#define _PSI_TYPES_DECL_STRUCTS_H
+
+typedef struct decl_structs {
+       size_t count;
+       decl_struct **list;
+} decl_structs;
+
+static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
+       if (!ss) {
+               ss = calloc(1, sizeof(*ss));
+       }
+       ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
+       ss->list[ss->count-1] = s;
+       return ss;
+}
+
+static inline void free_decl_structs(decl_structs *ss) {
+       size_t i;
+
+       for (i = 0; i < ss->count; ++i) {
+               free_decl_struct(ss->list[i]);
+       }
+       free(ss->list);
+       free(ss);
+}
+
+#endif
diff --git a/src/types/decl_type.h b/src/types/decl_type.h
new file mode 100644 (file)
index 0000000..8cbb2fc
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _PSI_TYPES_DECL_TYPE_H
+#define _PSI_TYPES_DECL_TYPE_H
+
+#include "parser_proc.h"
+
+typedef struct decl_type {
+       struct psi_token *token;
+       char *name;
+       token_t type;
+       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) {
+       decl_type *t = calloc(1, sizeof(*t));
+       t->type = type;
+       t->name = strdup(name);
+       return t;
+}
+
+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->real.func);
+       }
+       free(type->name);
+       free(type);
+}
+
+
+#endif
diff --git a/src/types/decl_typedefs.h b/src/types/decl_typedefs.h
new file mode 100644 (file)
index 0000000..e58a2f5
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_DECL_TYPEDEFS_H
+#define _PSI_TYPES_DECL_TYPEDEFS_H
+
+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 inline 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);
+}
+
+#endif
diff --git a/src/types/decl_union.h b/src/types/decl_union.h
new file mode 100644 (file)
index 0000000..3bd031b
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _PSI_TYPES_DECL_UNION_H
+
+typedef struct decl_union {
+       struct 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);
+}
+
+#endif
diff --git a/src/types/decl_unions.h b/src/types/decl_unions.h
new file mode 100644 (file)
index 0000000..49c6b73
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_DECL_UNOINS_H
+#define _PSI_TYPES_DECL_UNOINS_H
+
+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);
+}
+
+#endif
diff --git a/src/types/decl_var.h b/src/types/decl_var.h
new file mode 100644 (file)
index 0000000..166a69e
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _PSI_TYPES_DECL_VAR_H
+#define _PSI_TYPES_DECL_VAR_H
+
+typedef struct decl_var {
+       struct psi_token *token;
+       char *name;
+       unsigned pointer_level;
+       unsigned array_size;
+       struct decl_arg *arg;
+} decl_var;
+
+static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
+       decl_var *v = calloc(1, sizeof(*v));
+       v->name = (char *) strdup((const char *) name);
+       v->pointer_level = pl;
+       v->array_size = 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_token_copy(dest->token);
+       }
+       return dest;
+}
+
+static inline void free_decl_var(decl_var *var) {
+       if (var->token) {
+               free(var->token);
+       }
+       free(var->name);
+       free(var);
+}
+
+#endif
diff --git a/src/types/decl_vars.h b/src/types/decl_vars.h
new file mode 100644 (file)
index 0000000..46c65bd
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _PSI_TYPES_DECL_VARS_H
+#define _PSI_TYPES_DECL_VARS_H
+
+typedef struct decl_vars {
+       decl_var **vars;
+       size_t count;
+} decl_vars;
+
+static inline decl_vars *init_decl_vars(decl_var *var) {
+       decl_vars *vars = calloc(1, sizeof(*vars));
+       if (var) {
+               vars->count = 1;
+               vars->vars = calloc(1, sizeof(*vars->vars));
+               vars->vars[0] = var;
+       }
+       return vars;
+}
+
+static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
+       vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
+       vars->vars[vars->count-1] = var;
+       return vars;
+}
+
+static inline void free_decl_vars(decl_vars *vars) {
+       size_t i;
+
+       for (i = 0; i < vars->count; ++i) {
+               free_decl_var(vars->vars[i]);
+       }
+       free(vars->vars);
+       free(vars);
+}
+
+#endif
diff --git a/src/types/decls.h b/src/types/decls.h
new file mode 100644 (file)
index 0000000..7f40b7c
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_DECLS_H
+#define _PSI_TYPES_DECLS_H
+
+typedef struct decls {
+       size_t count;
+       decl **list;
+} decls;
+
+static inline decls *add_decl(decls *decls, decl *decl) {
+       if (!decls) {
+               decls = calloc(1, sizeof(*decls));
+       }
+       decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
+       decls->list[decls->count-1] = decl;
+       return decls;
+}
+
+static inline void free_decls(decls *decls) {
+       size_t i;
+
+       for (i = 0; i < decls->count; ++i) {
+               free_decl(decls->list[i]);
+       }
+       free(decls->list);
+       free(decls);
+}
+
+#endif
diff --git a/src/types/free_call.h b/src/types/free_call.h
new file mode 100644 (file)
index 0000000..fec0daa
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _PSI_TYPES_FREE_CALL_H
+#define _PSI_TYPES_FREE_CALL_H
+
+typedef struct free_call {
+       struct psi_token *token;
+       char *func;
+       decl_vars *vars;
+       decl *decl;
+} free_call;
+
+static inline free_call *init_free_call(const char *func, decl_vars *vars) {
+       free_call *f = calloc(1, sizeof(*f));
+       f->func = strdup(func);
+       f->vars = vars;
+       return f;
+}
+
+static inline void free_free_call(free_call *f) {
+       if (f->token) {
+               free(f->token);
+       }
+       free(f->func);
+       free_decl_vars(f->vars);
+       free(f);
+}
+
+#endif
diff --git a/src/types/free_calls.h b/src/types/free_calls.h
new file mode 100644 (file)
index 0000000..7d4f575
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _PSI_TYPES_FREE_CALLS_H
+#define _PSI_TYPES_FREE_CALLS_H
+
+typedef struct free_calls {
+       free_call **list;
+       size_t count;
+} free_calls;
+
+static inline free_calls *init_free_calls(free_call *f) {
+       free_calls *fcs = calloc(1, sizeof(*fcs));
+       if (f) {
+               fcs->count = 1;
+               fcs->list = calloc(1, sizeof(*fcs->list));
+               fcs->list[0] = f;
+       }
+       return fcs;
+}
+
+static inline void free_free_calls(free_calls *fcs) {
+       size_t i;
+
+       for (i = 0; i < fcs->count; ++i) {
+               free_free_call(fcs->list[i]);
+       }
+       free(fcs->list);
+       free(fcs);
+}
+
+static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
+       fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
+       fcs->list[fcs->count-1] = f;
+       return fcs;
+}
+
+#endif
diff --git a/src/types/free_stmt.h b/src/types/free_stmt.h
new file mode 100644 (file)
index 0000000..a5eceb8
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _PSI_TYPES_FREE_STMT_H
+#define _PSI_TYPES_FREE_STMT_H
+
+typedef struct free_stmt {
+       free_calls *calls;
+} free_stmt;
+
+static inline free_stmt *init_free_stmt(free_calls *calls) {
+       free_stmt *f = calloc(1, sizeof(*f));
+       f->calls = calls;
+       return f;
+}
+
+static inline void free_free_stmt(free_stmt *f) {
+       free_free_calls(f->calls);
+       free(f);
+}
+
+#endif
diff --git a/src/types/impl.h b/src/types/impl.h
new file mode 100644 (file)
index 0000000..11270fa
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _PSI_TYPES_IMPL_H
+#define _PSI_TYPES_IMPL_H
+
+typedef struct impl {
+       impl_func *func;
+       impl_stmts *stmts;
+       decl *decl;
+} impl;
+
+static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
+       impl *i = calloc(1, sizeof(*i));
+       i->func = func;
+       i->stmts = stmts;
+       return i;
+}
+
+static inline void free_impl(impl *impl) {
+       free_impl_func(impl->func);
+       free_impl_stmts(impl->stmts);
+       free(impl);
+}
+
+#endif
diff --git a/src/types/impl_arg.h b/src/types/impl_arg.h
new file mode 100644 (file)
index 0000000..4f870e0
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _PSI_TYPES_IMPL_ARG_H
+#define _PSI_TYPES_IMPL_ARG_H
+
+typedef struct impl_arg {
+       impl_type *type;
+       impl_var *var;
+       impl_def_val *def;
+       impl_val val;
+       zval *_zv;
+} impl_arg;
+
+typedef struct impl_vararg {
+       impl_arg *name;
+       struct impl_args *args;
+       token_t *types;
+       impl_val *values;
+       void **free_list;
+} impl_vararg;
+
+static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
+       impl_arg *arg = calloc(1, sizeof(*arg));
+       arg->type = type;
+       arg->var = var;
+       arg->var->arg = arg;
+       arg->def = def;
+       return arg;
+}
+
+static inline void free_impl_arg(impl_arg *arg) {
+       free_impl_type(arg->type);
+       free_impl_var(arg->var);
+       if (arg->def) {
+               free_impl_def_val(arg->def);
+       }
+       free(arg);
+}
+
+#endif
diff --git a/src/types/impl_args.h b/src/types/impl_args.h
new file mode 100644 (file)
index 0000000..3894405
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _PSI_TYPES_IMPL_ARGS_H
+#define _PSI_TYPES_IMPL_ARGS_H
+
+typedef struct impl_args {
+       impl_arg **args;
+       size_t count;
+       impl_vararg vararg;
+} impl_args;
+
+static inline impl_args *init_impl_args(impl_arg *arg) {
+       impl_args *args = calloc(1, sizeof(*args));
+       if (arg) {
+               args->count = 1;
+               args->args = calloc(1, sizeof(*args->args));
+               args->args[0] = arg;
+       }
+       return args;
+}
+
+static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
+       args->args = realloc(args->args, ++args->count * sizeof(*args->args));
+       args->args[args->count-1] = arg;
+       return args;
+}
+
+static inline void free_impl_args(impl_args *args) {
+       size_t i;
+
+       for (i = 0; i < args->count; ++i) {
+               free_impl_arg(args->args[i]);
+       }
+       if (args->vararg.name) {
+               free_impl_arg(args->vararg.name);
+       }
+       free(args->args);
+       free(args);
+}
+
+#endif
diff --git a/src/types/impl_def_val.h b/src/types/impl_def_val.h
new file mode 100644 (file)
index 0000000..189e349
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _PSI_TYPES_IMPL_DEF_VAL_H
+#define _PSI_TYPES_IMPL_DEF_VAL_H
+
+typedef struct impl_def_val {
+       token_t type;
+       char *text;
+} impl_def_val;
+
+static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
+       impl_def_val *def = calloc(1, sizeof(*def));
+       def->type = t;
+       def->text = strdup(text);
+       return def;
+}
+
+static inline void free_impl_def_val(impl_def_val *def) {
+       free(def->text);
+       free(def);
+}
+
+#endif
diff --git a/src/types/impl_func.h b/src/types/impl_func.h
new file mode 100644 (file)
index 0000000..a9d6270
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _PSI_TYPES_IMPL_FUNC_H
+#define _PSI_TYPES_IMPL_FUNC_H
+
+typedef struct impl_func {
+       struct psi_token *token;
+       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, int ret_reference) {
+       impl_func *func = calloc(1, 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;
+}
+
+static inline void free_impl_func(impl_func *f) {
+       if (f->token) {
+               free(f->token);
+       }
+       free_impl_type(f->return_type);
+       free_impl_args(f->args);
+       free(f->name);
+       free(f);
+}
+
+#endif
diff --git a/src/types/impl_stmt.h b/src/types/impl_stmt.h
new file mode 100644 (file)
index 0000000..c110ddd
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _PSI_TYPES_IMPL_STMT_H
+#define _PSI_TYPES_IMPL_STMT_H
+
+typedef struct impl_stmt {
+       token_t type;
+       union {
+               let_stmt *let;
+               set_stmt *set;
+               return_stmt *ret;
+               free_stmt *fre;
+               void *ptr;
+       } s;
+} impl_stmt;
+
+static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
+       impl_stmt *stmt = calloc(1, sizeof(*stmt));
+       stmt->type = type;
+       stmt->s.ptr = ptr;
+       return stmt;
+}
+
+static inline void free_impl_stmt(impl_stmt *stmt) {
+       switch (stmt->type) {
+       case PSI_T_LET:
+               free_let_stmt(stmt->s.let);
+               break;
+       case PSI_T_SET:
+               free_set_stmt(stmt->s.set);
+               break;
+       case PSI_T_RETURN:
+               free_return_stmt(stmt->s.ret);
+               break;
+       case PSI_T_FREE:
+               free_free_stmt(stmt->s.fre);
+               break;
+       }
+       free(stmt);
+}
+
+#endif
diff --git a/src/types/impl_stmts.h b/src/types/impl_stmts.h
new file mode 100644 (file)
index 0000000..f7b980d
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _PSI_TYPES_IMPL_STMTS_H
+#define _PSI_TYPES_IMPL_STMTS_H
+
+typedef struct impl_stmts {
+       struct {
+               return_stmt **list;
+               size_t count;
+       } ret;
+       struct {
+               let_stmt **list;
+               size_t count;
+       } let;
+       struct {
+               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) {
+       list = realloc(list, count * sizeof(list));
+       ((void **)list)[count-1] = stmt;
+       return list;
+}
+
+static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
+       switch (stmt->type) {
+       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:
+               stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
+               break;
+       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;
+}
+
+static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
+       impl_stmts *stmts = calloc(1, sizeof(*stmts));
+       return add_impl_stmt(stmts, stmt);
+}
+
+static inline void free_impl_stmts(impl_stmts *stmts) {
+       size_t i;
+
+       for (i = 0; i < stmts->let.count; ++i) {
+               free_let_stmt(stmts->let.list[i]);
+       }
+       free(stmts->let.list);
+       for (i = 0; i < stmts->ret.count; ++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);
+}
+
+#endif
diff --git a/src/types/impl_type.h b/src/types/impl_type.h
new file mode 100644 (file)
index 0000000..9f7e894
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _PSI_TYPES_IMPL_TYPE_H
+#define _PSI_TYPES_IMPL_TYPE_H
+
+typedef struct impl_type {
+       char *name;
+       token_t type;
+} impl_type;
+
+static inline impl_type *init_impl_type(token_t type, const char *name) {
+       impl_type *t = calloc(1, sizeof(*t));
+
+       t->type = type;
+       t->name = strdup(name);
+       return t;
+}
+
+static inline void free_impl_type(impl_type *type) {
+       free(type->name);
+       free(type);
+}
+
+#endif
diff --git a/src/types/impl_val.h b/src/types/impl_val.h
new file mode 100644 (file)
index 0000000..4434690
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _PSI_TYPES_IMPL_VAL_H
+#define _PSI_TYPES_IMPL_VAL_H
+
+#include "Zend/zend_types.h"
+
+typedef union impl_val {
+       char cval;
+       int8_t i8;
+       uint8_t u8;
+       short sval;
+       int16_t i16;
+       uint16_t u16;
+       int ival;
+       int32_t i32;
+       uint32_t u32;
+       long lval;
+       int64_t i64;
+       uint64_t u64;
+       float fval;
+       double dval;
+#ifdef HAVE_LONG_DOUBLE
+       long double ldval;
+#endif
+       union {
+               zend_bool bval;
+               zend_long lval;
+               zend_string *str;
+               zend_fcall *cb;
+       } zend;
+       void *ptr;
+} impl_val;
+
+
+#endif
diff --git a/src/types/impl_var.h b/src/types/impl_var.h
new file mode 100644 (file)
index 0000000..9b8b39b
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _PSI_TYPES_IMPL_VAR_H
+#define _PSI_TYPES_IMPL_VAR_H
+
+typedef struct impl_var {
+       struct psi_token *token;
+       char *name;
+       struct impl_arg *arg;
+       unsigned reference:1;
+} impl_var;
+
+static inline impl_var *init_impl_var(const char *name, int is_reference) {
+       impl_var *var = calloc(1, sizeof(*var));
+       var->name = strdup(name);
+       var->reference = 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_token_copy(cpy->token);
+       }
+       return cpy;
+}
+
+static inline void free_impl_var(impl_var *var) {
+       if (var->token) {
+               free(var->token);
+       }
+       free(var->name);
+       free(var);
+}
+
+#endif
diff --git a/src/types/impls.h b/src/types/impls.h
new file mode 100644 (file)
index 0000000..8bf17fb
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_IMPLS_H
+#define _PSI_TYPES_IMPLS_H
+
+typedef struct impls {
+       size_t count;
+       impl **list;
+} impls;
+
+static inline impls *add_impl(impls *impls, impl *impl) {
+       if (!impls) {
+               impls = calloc(1, sizeof(*impls));
+       }
+       impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
+       impls->list[impls->count-1] = impl;
+       return impls;
+}
+
+static inline void free_impls(impls *impls) {
+       size_t i;
+
+       for (i = 0; i < impls->count; ++i) {
+               free_impl(impls->list[i]);
+       }
+       free(impls->list);
+       free(impls);
+}
+
+#endif
diff --git a/src/types/let_callback.h b/src/types/let_callback.h
new file mode 100644 (file)
index 0000000..0653b3d
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _PSI_TYPES_LET_CALLBACK_H
+#define _PSI_TYPES_LET_CALLBACK_H
+
+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);
+}
+
+#endif
diff --git a/src/types/let_calloc.h b/src/types/let_calloc.h
new file mode 100644 (file)
index 0000000..e6d3f91
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _PSI_TYPES_LET_CALLOC_H
+#define _PSI_TYPES_LET_CALLOC_H
+
+typedef struct let_calloc {
+       num_exp *nmemb;
+       num_exp *size;
+} let_calloc;
+
+static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
+       let_calloc *alloc = calloc(1, sizeof(*alloc));
+       alloc->nmemb = nmemb;
+       alloc->size = size;
+       return alloc;
+}
+
+static inline void free_let_calloc(let_calloc *alloc) {
+       free_num_exp(alloc->nmemb);
+       free_num_exp(alloc->size);
+       free(alloc);
+}
+
+#endif
diff --git a/src/types/let_func.h b/src/types/let_func.h
new file mode 100644 (file)
index 0000000..526265b
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _PSI_TYPES_LET_FUNC_H
+#define _PSI_TYPES_LET_FUNC_H
+
+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;
+       let_func_handler handler;
+} let_func;
+
+static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
+       let_func *func = calloc(1, sizeof(*func));
+       func->type = type;
+       func->name = strdup(name);
+       func->var = var;
+       return func;
+}
+
+static inline void free_let_func(let_func *func) {
+       free_impl_var(func->var);
+       free(func->name);
+       free(func);
+}
+
+#endif
diff --git a/src/types/let_stmt.h b/src/types/let_stmt.h
new file mode 100644 (file)
index 0000000..8415e49
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _PSI_TYPES_LET_STMT_H
+#define _PSI_TYPES_LET_STMT_H
+
+typedef struct let_stmt {
+       decl_var *var;
+       let_val *val;
+} let_stmt;
+
+static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
+       let_stmt *let = calloc(1, sizeof(*let));
+       let->var = var;
+       let->val = val;
+       return let;
+}
+
+static inline void free_let_stmt(let_stmt *stmt) {
+       if (stmt->val) {
+               if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
+                       free_decl_arg(stmt->var->arg);
+               }
+               free_let_val(stmt->val);
+       }
+       free_decl_var(stmt->var);
+       free(stmt);
+}
+
+#endif
diff --git a/src/types/let_val.h b/src/types/let_val.h
new file mode 100644 (file)
index 0000000..7d5acfd
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef _PSI_TYPES_LET_VAL_H
+#define _PSI_TYPES_LET_VAL_H
+
+
+enum let_val_kind {
+       PSI_LET_NULL,
+       PSI_LET_NUMEXP,
+       PSI_LET_CALLOC,
+       PSI_LET_CALLBACK,
+       PSI_LET_FUNC,
+       PSI_LET_TMP,
+};
+#define PSI_LET_REFERENCE 0x1;
+typedef struct let_val {
+       enum let_val_kind kind;
+       union {
+               num_exp *num;
+               let_calloc *alloc;
+               let_callback *callback;
+               let_func *func;
+               decl_var *var;
+       } data;
+       union {
+               struct {
+                       unsigned is_reference:1;
+               } one;
+               unsigned all;
+       } flags;
+} let_val;
+
+static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
+       let_val *let = calloc(1, sizeof(*let));
+       switch (let->kind = kind) {
+       case PSI_LET_NULL:
+               break;
+       case PSI_LET_NUMEXP:
+               let->data.num = data;
+               break;
+       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;
+       case PSI_LET_TMP:
+               let->data.var = data;
+               break;
+       EMPTY_SWITCH_DEFAULT_CASE();
+       }
+       return let;
+}
+
+static inline void free_let_val(let_val *let) {
+       switch (let->kind) {
+       case PSI_LET_NULL:
+               break;
+       case PSI_LET_NUMEXP:
+               free_num_exp(let->data.num);
+               break;
+       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;
+       case PSI_LET_TMP:
+               free_decl_var(let->data.var);
+               break;
+       EMPTY_SWITCH_DEFAULT_CASE();
+       }
+       free(let);
+}
+
+#endif
diff --git a/src/types/num_exp.h b/src/types/num_exp.h
new file mode 100644 (file)
index 0000000..c54a5af
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef _PSI_TYPES_NUM_EXP
+#define _PSI_TYPES_NUM_EXP
+
+typedef struct num_exp {
+       struct psi_token *token;
+       token_t t;
+       union {
+               char *numb;
+               constant *cnst;
+               decl_var *dvar;
+               struct decl_enum_item *enm;
+       } u;
+       token_t operator;
+       int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
+       struct num_exp *operand;
+} num_exp;
+
+static inline num_exp *init_num_exp(token_t t, void *num) {
+       num_exp *exp = calloc(1, sizeof(*exp));
+       switch (exp->t = t) {
+       case PSI_T_NUMBER:
+       case PSI_T_NSNAME:
+               exp->u.numb = strdup(num);
+               break;
+       case PSI_T_NAME:
+               exp->u.dvar = num;
+               break;
+       EMPTY_SWITCH_DEFAULT_CASE();
+       }
+       return exp;
+}
+
+static inline num_exp *copy_num_exp(num_exp *exp) {
+       decl_var *dvar;
+       num_exp *num = calloc(1, sizeof(*num));
+
+       memcpy(num, exp, sizeof(*num));
+
+       if (num->token) {
+               num->token = psi_token_copy(num->token);
+       }
+       if (num->operand) {
+               num->operand = copy_num_exp(num->operand);
+       }
+       switch (num->t) {
+       case PSI_T_NUMBER:
+       case PSI_T_NSNAME:
+               num->u.numb = strdup(num->u.numb);
+               break;
+       case PSI_T_NAME:
+               dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size);
+               dvar->arg = num->u.dvar->arg;
+               if (num->u.dvar->token) {
+                       dvar->token = psi_token_copy(num->u.dvar->token);
+               }
+               num->u.dvar = dvar;
+               break;
+       }
+       return num;
+}
+
+static inline void free_num_exp(num_exp *exp) {
+       if (exp->token) {
+               free(exp->token);
+       }
+       switch (exp->t) {
+       case PSI_T_NUMBER:
+               free(exp->u.numb);
+               break;
+       case PSI_T_NSNAME:
+               break;
+       case PSI_T_NAME:
+               free_decl_var(exp->u.dvar);
+               break;
+       case PSI_T_ENUM:
+               break;
+       EMPTY_SWITCH_DEFAULT_CASE();
+       }
+       if (exp->operand) {
+               free_num_exp(exp->operand);
+       }
+       free(exp);
+}
+
+#endif
diff --git a/src/types/return_stmt.h b/src/types/return_stmt.h
new file mode 100644 (file)
index 0000000..12e371e
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _PSI_TYPES_RETURN_STMT_H
+#define _PSI_TYPES_RETURN_STMT_H
+
+typedef struct return_stmt {
+       struct psi_token *token;
+       set_value *set;
+       decl_arg *decl;
+} return_stmt;
+
+static inline return_stmt *init_return_stmt(set_value *val) {
+       return_stmt *ret = calloc(1, sizeof(*ret));
+       ret->set = val;
+       return ret;
+}
+
+static inline void free_return_stmt(return_stmt *ret) {
+       if (ret->token) {
+               free(ret->token);
+       }
+       free_set_value(ret->set);
+       free(ret);
+}
+
+#endif
diff --git a/src/types/set_func.h b/src/types/set_func.h
new file mode 100644 (file)
index 0000000..54d61d3
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _PSI_TYPES_SET_FUNC_H
+#define _PSI_TYPES_SET_FUNC_H
+
+struct set_value;
+
+typedef struct set_func {
+       struct psi_token *token;
+       token_t type;
+       char *name;
+       void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
+} set_func;
+
+static inline set_func *init_set_func(token_t type, const char *name) {
+       set_func *func = calloc(1, sizeof(*func));
+       func->type = type;
+       func->name = strdup(name);
+       return func;
+}
+
+static inline void free_set_func(set_func *func) {
+       if (func->token) {
+               free(func->token);
+       }
+       free(func->name);
+       free(func);
+}
+
+#endif
diff --git a/src/types/set_stmt.h b/src/types/set_stmt.h
new file mode 100644 (file)
index 0000000..360b324
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _PSI_TYPES_SET_STMT_H
+#define _PSI_TYPES_SET_STMT_H
+
+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) {
+       set_stmt *set = calloc(1, sizeof(*set));
+       set->var = var;
+       set->val = val;
+       return set;
+}
+
+static inline void free_set_stmt(set_stmt *set) {
+       free_impl_var(set->var);
+       free_set_value(set->val);
+       free(set);
+}
+
+#endif
diff --git a/src/types/set_value.h b/src/types/set_value.h
new file mode 100644 (file)
index 0000000..0b6b269
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _PSI_TYPES_SET_VALUE_H
+#define _PSI_TYPES_SET_VALUE_H
+
+typedef struct set_value {
+       set_func *func;
+       decl_vars *vars;
+       num_exp *num;
+       struct {
+               struct set_value *set;
+               impl_val *val;
+       } outer;
+       struct set_values *inner;
+} set_value;
+
+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 struct set_values *add_set_value(struct set_values *vals, struct set_value *val);
+static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
+       val->inner = add_set_value(val->inner, inner);
+       inner->outer.set = val;
+       return val;
+}
+
+static inline void free_set_value(set_value *val) {
+       if (val->func) {
+               free_set_func(val->func);
+       }
+       if (val->vars) {
+               free_decl_vars(val->vars);
+       }
+       if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) {
+               free_set_values(val->inner);
+       }
+       if (val->num) {
+               free_num_exp(val->num);
+       }
+       free(val);
+}
+
+#endif
diff --git a/src/types/set_values.h b/src/types/set_values.h
new file mode 100644 (file)
index 0000000..b089372
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _PSI_TYPES_SET_VALUES_H
+#define _PSI_TYPES_SET_VALUES_H
+
+typedef struct set_values {
+       struct set_value **vals;
+       size_t count;
+} set_values;
+
+static inline set_values *init_set_values(struct 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, struct 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);
+}
+
+#endif