From 6a459a08a40a2c243b0211ceb0cb263d29302627 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 27 Jan 2016 18:17:10 +0100 Subject: [PATCH] enums --- Makefile.frag | 2 +- config.m4 | 3 +- src/calc.c | 5 ++ src/context.c | 33 +++++-- src/context_dump.c | 37 ++++++++ src/context_validate.c | 127 ++++++++++++++++++++++++--- src/module.c | 2 +- src/parser.h | 190 +++++++++++++++++++++++++++++++++-------- src/parser.re | 1 + src/parser_proc.h | 111 ++++++++++++------------ src/parser_proc.y | 39 +++++++++ 11 files changed, 440 insertions(+), 110 deletions(-) diff --git a/Makefile.frag b/Makefile.frag index 1917557..38fe137 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -25,7 +25,7 @@ lemon.c: ./lemon: lemon.c | lempar.c $(CC) -o $@ $< -$(PHP_PSI_SRCDIR)/src/parser_proc.h: $(PHP_PSI_SRCDIR)/src/parser_proc.y +$(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 $@ diff --git a/config.m4 b/config.m4 index 16db302..ade6f45 100644 --- a/config.m4 +++ b/config.m4 @@ -105,10 +105,11 @@ if test "$PHP_PSI" != no; then PHP_ADD_BUILD_DIR($PHP_PSI_BUILDDIR/src) PHP_PSI_HEADERS=`(cd $PHP_PSI_SRCDIR/src && echo *.h)` - PHP_PSI_SOURCES=`(cd $PHP_PSI_SRCDIR && echo src/context*.c)` + 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_NEW_EXTENSION(psi, $PHP_PSI_SOURCES, $ext_shared) PHP_INSTALL_HEADERS(ext/psi, php_psi.h $PHP_PSI_HEADERS) diff --git a/src/calc.c b/src/calc.c index fc3e043..efea900 100644 --- a/src/calc.c +++ b/src/calc.c @@ -4,6 +4,7 @@ #include "php.h" #include "php_psi.h" +#include "calc.h" static inline int psi_calc_num_exp_value(num_exp *exp, impl_val *strct, impl_val *res) { impl_val *ref, *tmp = NULL; @@ -31,6 +32,10 @@ static inline int psi_calc_num_exp_value(num_exp *exp, impl_val *strct, impl_val } break; + case PSI_T_ENUM: + return psi_calc_num_exp(exp->u.enm->num ?: &exp->u.enm->inc, NULL, res); + break; + case PSI_T_NAME: if (strct) { ref = struct_member_ref(exp->u.dvar->arg, strct, &tmp); diff --git a/src/context.c b/src/context.c index de72810..3fe6c3f 100644 --- a/src/context.c +++ b/src/context.c @@ -26,7 +26,7 @@ #include "php.h" #include "php_scandir.h" #include "php_psi.h" - +#include "calc.h" #include "libjit.h" #include "libffi.h" @@ -220,13 +220,12 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) zend_function_entry *PSI_ContextCompile(PSI_Context *C) { size_t i; + zend_constant zc; - if (C->consts) { - zend_constant zc; - - zc.flags = CONST_PERSISTENT|CONST_CS; - zc.module_number = EG(current_module)->module_number; + zc.flags = CONST_PERSISTENT|CONST_CS; + zc.module_number = EG(current_module)->module_number; + if (C->consts) { for (i = 0; i < C->consts->count; ++i) { constant *c = C->consts->list[i]; @@ -247,6 +246,22 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *C) zend_register_constant(&zc); } } + if (C->enums) { + for (i = 0; i < C->enums->count; ++i) { + decl_enum *e = C->enums->list[i]; + size_t j; + + for (j = 0; j < e->items->count; ++j) { + decl_enum_item *i = e->items->list[j]; + zend_string *name = strpprintf(0, "psi\\%s\\%s", e->name, i->name); + + zc.name = zend_string_dup(name, 1); + ZVAL_LONG(&zc.value, psi_long_num_exp(i->num, NULL)); + zend_register_constant(&zc); + zend_string_release(name); + } + } + } return C->closures = C->ops->compile(C); } @@ -301,6 +316,12 @@ void PSI_ContextDtor(PSI_Context *C) } free(C->structs); } + if (C->enums) { + if (C->enums->list) { + free(C->enums->list); + } + free(C->enums); + } if (C->decls) { if (C->decls->list) { free(C->decls->list); diff --git a/src/context_dump.c b/src/context_dump.c index 93b8f32..cb1825f 100644 --- a/src/context_dump.c +++ b/src/context_dump.c @@ -46,6 +46,9 @@ static inline void dump_num_exp(int fd, num_exp *exp) { case PSI_T_NAME: dump_decl_var(fd, exp->u.dvar); break; + case PSI_T_ENUM: + dprintf(fd, "%s", exp->u.enm->name); + break; EMPTY_SWITCH_DEFAULT_CASE(); } if (exp->operand) { @@ -144,6 +147,7 @@ static inline void dump_struct(int fd, decl_struct *strct) { dprintf(fd, ";"); } } + static inline void dump_structs(int fd, decl_structs *structs) { size_t i; @@ -155,6 +159,35 @@ static inline void dump_structs(int fd, decl_structs *structs) { } } +static inline void dump_enum(int fd, decl_enum *e) { + size_t j; + + dprintf(fd, "enum %s {\n", e->name); + for (j = 0; j < e->items->count; ++j) { + decl_enum_item *i = e->items->list[j]; + + if (j) { + dprintf(fd, ",\n"); + } + dprintf(fd, "\t%s", i->name); + if (i->num && i->num != &i->inc) { + dprintf(fd, " = "); + dump_num_exp(fd, i->num); + } + } + dprintf(fd, "\n}"); +} + +static inline void dump_enums(int fd, decl_enums *enums) { + size_t i; + + for (i = 0; i < enums->count; ++i) { + decl_enum *e = enums->list[i]; + + dump_enum(fd, e); + dprintf(fd, "\n"); + } +} static inline void dump_constant(int fd, constant *cnst) { dprintf(fd, "const %s %s = ", cnst->type->name, cnst->name); if (cnst->val->type == PSI_T_QUOTED_STRING) { @@ -376,6 +409,10 @@ void PSI_ContextDump(PSI_Context *C, int fd) dump_structs(fd, C->structs); dprintf(fd, "\n"); } + if (C->enums) { + dump_enums(fd, C->enums); + dprintf(fd, "\n"); + } if (C->consts) { dump_constants(fd, C->consts); dprintf(fd, "\n"); diff --git a/src/context_validate.c b/src/context_validate.c index 38e0f84..66b2a77 100644 --- a/src/context_validate.c +++ b/src/context_validate.c @@ -1,4 +1,4 @@ -#ifdef HAVE_CONFIG_H + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -65,6 +65,7 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { return 0; } + static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type) { size_t i; @@ -80,6 +81,21 @@ static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type return 0; } +static inline int locate_decl_type_enum(decl_enums *enums, decl_type *type) { + size_t i; + + if (type->enm) { + return 1; + } + for (i = 0; i < enums->count; ++i) { + if (!strcmp(enums->list[i]->name, type->name)) { + type->enm = enums->list[i]; + return 1; + } + } + return 0; +} + static inline int validate_decl_type(PSI_Data *data, decl_type *type) { switch (type->type) { case PSI_T_CHAR: @@ -99,6 +115,10 @@ static inline int validate_decl_type(PSI_Data *data, decl_type *type) { return 0; } break; + case PSI_T_ENUM: + if (!data->enums || !locate_decl_type_enum(data->enums, type)) { + return 0; + } } return 1; } @@ -300,7 +320,7 @@ static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) { static inline decl_arg *locate_decl_var_arg(decl_var *var, decl_args *args, decl_arg *func) { size_t i; - for (i = 0; i < args->count; ++i) { + if (args) for (i = 0; i < args->count; ++i) { decl_arg *arg = args->args[i]; if (!strcmp(var->name, arg->var->name)) { @@ -335,7 +355,35 @@ static inline constant *locate_num_exp_constant(num_exp *exp, constants *consts) return NULL; } -static inline int validate_num_exp(PSI_Data *data, decl_args *dargs, decl_arg *func, num_exp *exp) { +static inline decl_enum_item *locate_num_exp_enum_item_ex(num_exp *exp, decl_enum *e) { + size_t k; + + if (e) for (k = 0; k < e->items->count; ++k) { + decl_enum_item *i = e->items->list[k]; + + if (!strcmp(i->name, exp->u.dvar->name)) { + free_decl_var(exp->u.dvar); + exp->t = PSI_T_ENUM; + exp->u.enm = i; + return i; + } + } + return NULL; +} +static inline decl_enum_item *locate_num_exp_enum_item(num_exp *exp, decl_enums *enums) { + size_t j; + + if (enums) for (j = 0; j < enums->count; ++j) { + decl_enum *e = enums->list[j]; + decl_enum_item *i = locate_num_exp_enum_item_ex(exp, e); + + if (i) { + return i; + } + } + return NULL; +} +static inline int validate_num_exp(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: @@ -352,16 +400,18 @@ static inline int validate_num_exp(PSI_Data *data, decl_args *dargs, decl_arg *f break; EMPTY_SWITCH_DEFAULT_CASE(); } - if (!validate_num_exp(data, dargs, func, exp->operand)) { + if (!validate_num_exp(data, exp->operand, dargs, func, enm)) { return 0; } } switch (exp->t) { case PSI_T_NAME: if (!locate_decl_var_arg(exp->u.dvar, dargs, func)) { - data->error(exp->token, PSI_WARNING, "Unknown variable '%s' in numeric expression", - exp->u.dvar->name); - return 0; + if (!locate_num_exp_enum_item(exp, data->enums) && !locate_num_exp_enum_item_ex(exp, enm)) { + data->error(exp->token, PSI_WARNING, "Unknown variable '%s' in numeric expression", + exp->u.dvar->name); + return 0; + } } return 1; case PSI_T_NSNAME: @@ -372,11 +422,45 @@ static inline int validate_num_exp(PSI_Data *data, decl_args *dargs, decl_arg *f } return 1; case PSI_T_NUMBER: + case PSI_T_ENUM: return 1; default: return 0; } } + +static inline int validate_decl_enum(PSI_Data *data, decl_enum *e) { + size_t j; + + if (!e->items || !e->items->count) { + data->error(e->token, PSI_WARNING, "Empty enum '%s'", e->name); + return 0; + } + + for (j = 0; j < e->items->count; ++j) { + decl_enum_item *i = e->items->list[j]; + + if (!i->num) { + if (j) { + i->inc.t = PSI_T_NUMBER; + i->inc.u.numb = "1"; + i->inc.operator = PSI_T_PLUS; + i->inc.operand = i->prev->num ?: &i->prev->inc; + i->num = &i->inc; + } else { + i->inc.t = PSI_T_NUMBER; + i->inc.u.numb = "0"; + i->num = &i->inc; + } + } + if (!validate_num_exp(data, i->num, NULL, NULL, e)) { + return 0; + } + } + + return 1; +} + static inline int validate_set_value_handler(set_value *set) { switch (set->func->type) { case PSI_T_TO_BOOL: @@ -460,7 +544,7 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg } } if (set->num) { - if (!validate_num_exp(data, ref_list, ref, set->num)) { + if (!validate_num_exp(data, set->num, ref_list, ref, NULL)) { return 0; } } @@ -605,15 +689,15 @@ static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { let->var->array_size)); break; case PSI_LET_NUMEXP: - if (!validate_num_exp(data, impl->decl->args, impl->decl->func, let->val->data.num)) { + if (!validate_num_exp(data, let->val->data.num, impl->decl->args, impl->decl->func, NULL)) { return 0; } break; case PSI_LET_CALLOC: - if (!validate_num_exp(data, impl->decl->args, impl->decl->func, let->val->data.alloc->nmemb)) { + if (!validate_num_exp(data, let->val->data.alloc->nmemb, impl->decl->args, impl->decl->func, NULL)) { return 0; } - if (!validate_num_exp(data, impl->decl->args, impl->decl->func, let->val->data.alloc->size)) { + if (!validate_num_exp(data, let->val->data.alloc->size, impl->decl->args, impl->decl->func, NULL)) { return 0; } break; @@ -881,6 +965,15 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) } } } + if (D->enums) { + size_t i; + + for (i = 0; i < D->enums->count; ++i) { + if (validate_decl_enum(PSI_DATA(C), D->enums->list[i])) { + C->enums = add_decl_enum(C->enums, D->enums->list[i]); + } + } + } if (D->consts) { size_t i; @@ -960,6 +1053,18 @@ int PSI_ContextValidateData(PSI_Data *dest, PSI_Data *source) } } + if (source->enums) for (i = 0; i < source->enums->count; ++i) { + decl_enum *denum = source->enums->list[i]; + + if (validate_decl_enum(source, denum)) { + if (dest) { + dest->enums = add_decl_enum(dest->enums, denum); + } + } else { + ++errors; + } + } + if (source->decls) for (i = 0; i < source->decls->count; ++i) { decl *decl = source->decls->list[i]; diff --git a/src/module.c b/src/module.c index c3728a7..f71975b 100644 --- a/src/module.c +++ b/src/module.c @@ -50,7 +50,7 @@ void psi_error_wrapper(PSI_Token *t, int type, const char *msg, ...) fn = zend_get_executed_filename(); ln = zend_get_executed_lineno(); } else if (zend_is_compiling()) { - fn = zend_get_compiled_filename(); + fn = zend_get_compiled_filename()->val; ln = zend_get_compiled_lineno(); } diff --git a/src/parser.h b/src/parser.h index 5582922..daf99dc 100644 --- a/src/parser.h +++ b/src/parser.h @@ -17,7 +17,6 @@ typedef int token_t; -/* in php_psi.h */ size_t psi_t_alignment(token_t); size_t psi_t_size(token_t); @@ -61,6 +60,7 @@ typedef struct decl_type { token_t type; struct decl_type *real; struct decl_struct *strct; + struct decl_enum *enm; } decl_type; static inline decl_type *init_decl_type(token_t type, const char *name) { @@ -70,40 +70,6 @@ static inline decl_type *init_decl_type(token_t type, const char *name) { return t; } -static inline decl_type *init_decl_type_ex(token_t type, int argc, ...) { - va_list argv; - char *ptr, *arg; - unsigned i; - size_t len, pos = 0, all = 0; - decl_type *t = calloc(1, sizeof(*t)); - - va_start(argv, argc); - for (i = 0; i < argc; ++i) { - arg = va_arg(argv, char *); - len = va_arg(argv, size_t); - - if (len) { - if (all) { - pos = all; - ptr = realloc(ptr, 1 + (all += len)); - } else { - ptr = malloc(1 + (all = len)); - } - memcpy(ptr + pos, arg, len); - } - } - va_end(argv); - - if (!all) { - ptr = calloc(1, 1); - } else { - ptr[all] = 0; - } - t->type = type; - t->name = ptr; - return t; -} - static inline decl_type *real_decl_type(decl_type *type) { while (type->real) { type = type->real; @@ -375,6 +341,7 @@ static inline void free_decls(decls *decls) { free(decls); } + typedef struct decl_struct { PSI_Token *token; char *name; @@ -651,6 +618,7 @@ typedef struct num_exp { 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); @@ -672,6 +640,36 @@ static inline num_exp *init_num_exp(token_t t, void *num) { return exp; } +static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); +static inline num_exp *copy_num_exp(num_exp *exp) { + decl_var *dvar; + num_exp *num = calloc(1, sizeof(*num)); + + 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); @@ -685,6 +683,8 @@ static inline void free_num_exp(num_exp *exp) { case PSI_T_NAME: free_decl_var(exp->u.dvar); break; + case PSI_T_ENUM: + break; EMPTY_SWITCH_DEFAULT_CASE(); } if (exp->operand) { @@ -693,6 +693,122 @@ static inline void free_num_exp(num_exp *exp) { 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; + +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; @@ -1250,6 +1366,7 @@ typedef void (*psi_error_cb)(PSI_Token *token, int type, const char *msg, ...); constants *consts; \ decl_typedefs *defs; \ decl_structs *structs; \ + decl_enums *enums; \ decls *decls; \ impls *impls; \ union { \ @@ -1280,6 +1397,9 @@ static inline void PSI_DataDtor(PSI_Data *data) { if (data->structs) { free_decl_structs(data->structs); } + if (data->enums) { + free_decl_enums(data->enums); + } if (data->decls) { free_decls(data->decls); } diff --git a/src/parser.re b/src/parser.re index 7ab169e..50d15aa 100644 --- a/src/parser.re +++ b/src/parser.re @@ -284,6 +284,7 @@ token_t PSI_ParserScan(PSI_Parser *P) 'FUNCTION' {RETURN(PSI_T_FUNCTION);} 'TYPEDEF' {RETURN(PSI_T_TYPEDEF);} 'STRUCT' {RETURN(PSI_T_STRUCT);} + 'ENUM' {RETURN(PSI_T_ENUM);} 'CONST' {RETURN(PSI_T_CONST);} 'LIB' {RETURN(PSI_T_LIB);} 'LET' {RETURN(PSI_T_LET);} diff --git a/src/parser_proc.h b/src/parser_proc.h index 7e8a7fe..c6fe15a 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -13,60 +13,61 @@ #define PSI_T_EOF 13 #define PSI_T_EOS 14 #define PSI_T_QUOTED_STRING 15 -#define PSI_T_STRUCT 16 +#define PSI_T_ENUM 16 #define PSI_T_LBRACE 17 #define PSI_T_RBRACE 18 -#define PSI_T_COLON 19 -#define PSI_T_LPAREN 20 -#define PSI_T_NUMBER 21 -#define PSI_T_RPAREN 22 -#define PSI_T_BOOL 23 -#define PSI_T_INT 24 -#define PSI_T_FLOAT 25 -#define PSI_T_CONST 26 -#define PSI_T_NSNAME 27 -#define PSI_T_EQUALS 28 -#define PSI_T_TYPEDEF 29 -#define PSI_T_VOID 30 -#define PSI_T_LBRACKET 31 -#define PSI_T_RBRACKET 32 -#define PSI_T_COMMA 33 -#define PSI_T_ELLIPSIS 34 -#define PSI_T_CHAR 35 -#define PSI_T_SHORT 36 -#define PSI_T_LONG 37 -#define PSI_T_DOUBLE 38 -#define PSI_T_UNSIGNED 39 -#define PSI_T_SIGNED 40 -#define PSI_T_INT8 41 -#define PSI_T_UINT8 42 -#define PSI_T_INT16 43 -#define PSI_T_UINT16 44 -#define PSI_T_INT32 45 -#define PSI_T_UINT32 46 -#define PSI_T_INT64 47 -#define PSI_T_UINT64 48 -#define PSI_T_FUNCTION 49 -#define PSI_T_NULL 50 -#define PSI_T_TRUE 51 -#define PSI_T_FALSE 52 -#define PSI_T_DOLLAR 53 -#define PSI_T_CALLOC 54 -#define PSI_T_OBJVAL 55 -#define PSI_T_ARRVAL 56 -#define PSI_T_PATHVAL 57 -#define PSI_T_STRLEN 58 -#define PSI_T_STRVAL 59 -#define PSI_T_FLOATVAL 60 -#define PSI_T_INTVAL 61 -#define PSI_T_BOOLVAL 62 -#define PSI_T_TO_OBJECT 63 -#define PSI_T_TO_ARRAY 64 -#define PSI_T_TO_STRING 65 -#define PSI_T_TO_INT 66 -#define PSI_T_TO_FLOAT 67 -#define PSI_T_TO_BOOL 68 -#define PSI_T_MIXED 69 -#define PSI_T_ARRAY 70 -#define PSI_T_OBJECT 71 -#define PSI_T_AMPERSAND 72 +#define PSI_T_COMMA 19 +#define PSI_T_EQUALS 20 +#define PSI_T_STRUCT 21 +#define PSI_T_COLON 22 +#define PSI_T_LPAREN 23 +#define PSI_T_NUMBER 24 +#define PSI_T_RPAREN 25 +#define PSI_T_BOOL 26 +#define PSI_T_INT 27 +#define PSI_T_FLOAT 28 +#define PSI_T_CONST 29 +#define PSI_T_NSNAME 30 +#define PSI_T_TYPEDEF 31 +#define PSI_T_VOID 32 +#define PSI_T_LBRACKET 33 +#define PSI_T_RBRACKET 34 +#define PSI_T_ELLIPSIS 35 +#define PSI_T_CHAR 36 +#define PSI_T_SHORT 37 +#define PSI_T_LONG 38 +#define PSI_T_DOUBLE 39 +#define PSI_T_UNSIGNED 40 +#define PSI_T_SIGNED 41 +#define PSI_T_INT8 42 +#define PSI_T_UINT8 43 +#define PSI_T_INT16 44 +#define PSI_T_UINT16 45 +#define PSI_T_INT32 46 +#define PSI_T_UINT32 47 +#define PSI_T_INT64 48 +#define PSI_T_UINT64 49 +#define PSI_T_FUNCTION 50 +#define PSI_T_NULL 51 +#define PSI_T_TRUE 52 +#define PSI_T_FALSE 53 +#define PSI_T_DOLLAR 54 +#define PSI_T_CALLOC 55 +#define PSI_T_OBJVAL 56 +#define PSI_T_ARRVAL 57 +#define PSI_T_PATHVAL 58 +#define PSI_T_STRLEN 59 +#define PSI_T_STRVAL 60 +#define PSI_T_FLOATVAL 61 +#define PSI_T_INTVAL 62 +#define PSI_T_BOOLVAL 63 +#define PSI_T_TO_OBJECT 64 +#define PSI_T_TO_ARRAY 65 +#define PSI_T_TO_STRING 66 +#define PSI_T_TO_INT 67 +#define PSI_T_TO_FLOAT 68 +#define PSI_T_TO_BOOL 69 +#define PSI_T_MIXED 70 +#define PSI_T_ARRAY 71 +#define PSI_T_OBJECT 72 +#define PSI_T_AMPERSAND 73 diff --git a/src/parser_proc.y b/src/parser_proc.y index 1cc466f..328bd10 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -67,6 +67,40 @@ block ::= constant(constant). { block ::= decl_struct(strct). { P->structs = add_decl_struct(P->structs, strct); } +block ::= decl_enum(e). { + P->enums = add_decl_enum(P->enums, e); +} + +enum_name(n) ::= ENUM NAME(N). { + n = N; +} + +%type decl_enum {decl_enum *} +%destructor decl_enum {free_decl_enum($$);} +decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. { + e = init_decl_enum(N->text, list); + e->token = N; +} + +%type decl_enum_items {decl_enum_items*} +%destructor decl_enum_items {free_decl_enum_items($$);} +decl_enum_items(l) ::= decl_enum_item(i). { + l = init_decl_enum_items(i); +} +decl_enum_items(l) ::= decl_enum_items(l_) COMMA decl_enum_item(i). { + l = add_decl_enum_item(l_, i); +} + +%type decl_enum_item {decl_enum_item*} +%destructor decl_enum_item {free_decl_enum_item($$);} +decl_enum_item(i) ::= NAME(N) EQUALS num_exp(num). { + i = init_decl_enum_item(N->text, num); + i->token = N; +} +decl_enum_item(i) ::= NAME(N). { + i = init_decl_enum_item(N->text, NULL); + i->token = N; +} struct_name(n) ::= STRUCT NAME(N). { n = N; @@ -332,6 +366,11 @@ decl_type(type_) ::= STRUCT(S) NAME(T). { type_->token = T; free(S); } +decl_type(type_) ::= ENUM(E) NAME(T). { + type_ = init_decl_type(E->type, T->text); + type_->token = T; + free(E); +} %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME. %type decl_type {decl_type*} %destructor decl_type {free_decl_type($$);} -- 2.30.2