X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fparser_proc_grammar.y;h=1b40555e3fa9e777039cf1010ab48c8c13d9b020;hp=9970c40c3d4de0d9308222283d535fa1fe1a04d2;hb=2559f07a178b681dc240e20153ff5abdff54cb34;hpb=6ec1a060415f860bc3eb4c74fbce1c43f5aa7e55 diff --git a/src/parser_proc_grammar.y b/src/parser_proc_grammar.y index 9970c40..1b40555 100644 --- a/src/parser_proc_grammar.y +++ b/src/parser_proc_grammar.y @@ -39,12 +39,37 @@ static inline void psi_parser_proc_add_enum(struct psi_parser *P, struct psi_dec } P->enums = psi_plist_add(P->enums, &e); } +static inline void psi_parser_proc_deanon_typedef(struct psi_decl_arg *def) +{ + switch (def->type->type) { + case PSI_T_STRUCT: + if (!psi_decl_type_is_anon(def->type->name, "struct")) { + return; + } + break; + case PSI_T_UNION: + if (!psi_decl_type_is_anon(def->type->name, "union")) { + return; + } + break; + case PSI_T_ENUM: + if (!psi_decl_type_is_anon(def->type->name, "enum")) { + return; + } + break; + default: + return; + } + zend_string_release(def->type->name); + def->type->name = zend_string_copy(def->var->name); +} static inline void psi_parser_proc_add_typedef(struct psi_parser *P, struct psi_decl_arg *def) { assert(def); if (!P->types) { P->types = psi_plist_init((psi_plist_dtor) psi_decl_arg_free); } + //psi_parser_proc_deanon_typedef(def); P->types = psi_plist_add(P->types, &def); } static inline void psi_parser_proc_add_const(struct psi_parser *P, struct psi_const *cnst) { @@ -58,7 +83,7 @@ static inline void psi_parser_proc_add_const(struct psi_parser *P, struct psi_co static inline void psi_parser_proc_add_decl(struct psi_parser *P, struct psi_decl *decl) { assert(decl); - if (psi_decl_is_blacklisted(decl->func->var->name)) { + if (psi_decl_is_blacklisted(decl->func->var->name->val)) { psi_decl_free(&decl); return; } @@ -68,6 +93,14 @@ static inline void psi_parser_proc_add_decl(struct psi_parser *P, struct psi_dec } P->decls = psi_plist_add(P->decls, &decl); } +static inline void psi_parser_proc_add_decl_extvars(struct psi_parser *P, struct psi_plist *list) { + assert(list); + if (!P->vars) { + P->vars = psi_plist_init((psi_plist_dtor) psi_decl_extvar_free); + } + P->vars = psi_plist_add_r(P->vars, psi_plist_count(list), psi_plist_eles(list)); + free(list); +} static inline void psi_parser_proc_add_impl(struct psi_parser *P, struct psi_impl *impl) { assert(impl); if (!P->impls) { @@ -83,6 +116,11 @@ static inline void psi_parser_proc_add_impl(struct psi_parser *P, struct psi_imp #include "plist.h" #include "types/layout.h" +#define yytokentype psi_token_type + +#define PSI_T_CAST PSI_T_EQUALS +#define PSI_T_POINTER PSI_T_ASTERISK + struct psi_parser; } @@ -237,6 +275,21 @@ struct psi_parser; %token CPP_RESTRICT %token CPP_ASM +/* virtual tokens */ +%token BSLASH +%token LONG_DOUBLE +%token INT8 +%token UINT8 +%token INT16 +%token UINT16 +%token INT32 +%token UINT32 +%token INT64 +%token UINT64 +%token INT128 +%token UINT128 + + %precedence IIF COLON %precedence OR %precedence AND @@ -255,8 +308,8 @@ struct psi_parser; %type lib optional_name enum_name struct_name union_name %destructor {psi_token_free(&$$);} lib optional_name enum_name struct_name union_name -%type cpp_message_token cpp_include_token cpp_header_token cpp_no_arg_token cpp_name_arg_token cpp_exp_arg_token cpp_special_name_token -%destructor {} cpp_message_token cpp_include_token cpp_header_token cpp_no_arg_token cpp_name_arg_token cpp_exp_arg_token cpp_special_name_token +%type cpp_message_token cpp_include_token cpp_header_token cpp_no_arg_token cpp_name_arg_token cpp_exp_arg_token +%destructor {} cpp_message_token cpp_include_token cpp_header_token cpp_no_arg_token cpp_name_arg_token cpp_exp_arg_token %type name_token any_noeol_token binary_op_token unary_op_token %destructor {} name_token any_noeol_token binary_op_token unary_op_token @@ -276,25 +329,26 @@ struct psi_parser; %type cpp_macro_exp %destructor {psi_num_exp_free(&$$);} cpp_macro_exp -%type constant_type_token impl_def_val_token -%destructor {} constant_type_token impl_def_val_token +%type impl_def_val_token +%destructor {} impl_def_val_token %type constant %destructor {psi_const_free(&$$);} constant -%type constant_type -%destructor {psi_const_type_free(&$$);} constant_type %type impl_def_val %destructor {psi_impl_def_val_free(&$$);} impl_def_val %type decl_real_type decl_int_type decl_type_simple %destructor {psi_token_free(&$$);} decl_real_type decl_int_type decl_type_simple +%type decl_asm quoted_strings +%destructor {psi_token_free(&$$);} decl_asm quoted_strings + %type decl_type qualified_decl_type decl_type_complex %destructor {psi_decl_type_free(&$$);} decl_type qualified_decl_type decl_type_complex -%type decl_stmt decl decl_body decl_func_body decl_functor_body -%destructor {psi_decl_free(&$$);} decl_stmt decl decl_body decl_func_body decl_functor_body -%type decl_typedef decl_func decl_functor decl_arg decl_anon_arg typedef typedef_decl typedef_anon typedef_anon_decl -%destructor {psi_decl_arg_free(&$$);} decl_typedef decl_func decl_functor decl_arg decl_anon_arg typedef typedef_decl typedef_anon typedef_anon_decl +%type decl_stmt decl decl_body decl_func_body decl_functor_body decl_anon_functor_body ignored_decl +%destructor {psi_decl_free(&$$);} decl_stmt decl decl_body decl_func_body decl_functor_body decl_anon_functor_body ignored_decl +%type decl_typedef decl_func decl_functor decl_anon_functor decl_arg decl_anon_arg typedef typedef_decl typedef_anon typedef_anon_decl +%destructor {psi_decl_arg_free(&$$);} decl_typedef decl_func decl_functor decl_anon_functor decl_arg decl_anon_arg typedef typedef_decl typedef_anon typedef_anon_decl %type decl_var %destructor {psi_decl_var_free(&$$);} decl_var %type decl_struct @@ -305,8 +359,8 @@ struct psi_parser; %destructor {psi_decl_enum_free(&$$);} decl_enum %type decl_enum_item %destructor {psi_decl_enum_item_free(&$$);} decl_enum_item -%type decl_args decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout call_decl_vars -%destructor {psi_plist_free($$);} decl_args decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout call_decl_vars +%type decl_args decl_arg_list decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout call_decl_vars decl_extvar_stmt decl_extvar_list +%destructor {psi_plist_free($$);} decl_args decl_arg_list decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout call_decl_vars decl_extvar_stmt decl_extvar_list %type align_and_size %destructor {} align_and_size @@ -322,8 +376,8 @@ struct psi_parser; %destructor {psi_impl_func_free(&$$);} impl_func %type impl_arg %destructor {psi_impl_arg_free(&$$);} impl_arg -%type impl_type -%destructor {psi_impl_type_free(&$$);} impl_type +%type impl_type impl_type_restricted +%destructor {psi_impl_type_free(&$$);} impl_type impl_type_restricted %type impl_var %destructor {psi_impl_var_free(&$$);} impl_var @@ -356,8 +410,8 @@ struct psi_parser; %type impl_stmt %destructor {psi_impl_stmt_free(&$$);} impl_stmt -%type impl_type_token callback_rval let_func_token set_func_token assert_stmt_token -%destructor {psi_token_free(&$$);} impl_type_token callback_rval let_func_token set_func_token assert_stmt_token +%type impl_type_token impl_type_restricted_token impl_type_extended_token callback_rval let_func_token set_func_token assert_stmt_token +%destructor {psi_token_free(&$$);} impl_type_token impl_type_restricted_token impl_type_extended_token callback_rval let_func_token set_func_token assert_stmt_token %type impl_args impl_stmts let_exps let_func_exps callback_arg_list callback_args set_exps set_func_exps free_exps %destructor {psi_plist_free($$);} impl_args impl_stmts let_exps let_func_exps callback_arg_list callback_args set_exps set_func_exps free_exps @@ -402,12 +456,8 @@ block: } } | lib { - if (P->file.ln) { - P->error(PSI_DATA(P), $lib, PSI_WARNING, - "Extra 'lib \"%s\"' statement has no effect", $lib->text); - } else { - P->file.ln = strndup($lib->text, $lib->size); - } + char *libname = strdup($lib->text->val); + P->file.libnames = psi_plist_add(P->file.libnames, &libname); } | constant { psi_parser_proc_add_const(P, $constant); @@ -415,8 +465,15 @@ block: | decl_stmt { psi_parser_proc_add_decl(P, $decl_stmt); } -| ignored_decl -| decl_ext_var_stmt +| decl_extvar_stmt[list] { + psi_parser_proc_add_decl_extvars(P, $list); +} +| ignored_decl { + if (P->flags & PSI_DEBUG) { + P->error(PSI_DATA(P), $ignored_decl->func->token, PSI_NOTICE, "Ignored decl: %s", $ignored_decl->func->var->name->val); + } + psi_decl_free(&$ignored_decl); +} | decl_typedef[def] { psi_parser_proc_add_typedef(P, $def); } @@ -462,7 +519,7 @@ cpp_exp[exp]: while (psi_plist_get($tokens, index++, &next)) { struct psi_token *old = msg; msg = psi_token_cat(" ", 2, msg, next); - free(old); + psi_token_free(&old); } } psi_plist_free($tokens); @@ -481,7 +538,7 @@ cpp_exp[exp]: $exp = psi_cpp_exp_init($cpp_no_arg_token->type, NULL); $exp->token = psi_token_copy($cpp_no_arg_token); } -| cpp_name_arg_token cpp_special_name_token[name_token] { +| cpp_name_arg_token any_noeol_token[name_token] { $name_token->type = PSI_T_NAME; $exp = psi_cpp_exp_init($cpp_name_arg_token->type, psi_token_copy($name_token)); $exp->token = psi_token_copy($cpp_name_arg_token); @@ -541,25 +598,26 @@ cpp_exp_arg_token: | ELIF ; -cpp_special_name_token: - name_token -| NULL -| TRUE -| FALSE -| CPP_RESTRICT -| CPP_EXTENSION -| CPP_INLINE -; - cpp_macro_decl[macro]: - name_token NO_WHITESPACE LPAREN cpp_macro_sig RPAREN cpp_macro_decl_tokens { + any_noeol_token[name_token] cpp_macro_decl_tokens %dprec 1 { + $name_token->type = PSI_T_NAME; + $macro = psi_cpp_macro_decl_init(NULL, $cpp_macro_decl_tokens, NULL); + $macro->token = psi_token_copy($name_token); +} +| name_token NO_WHITESPACE LPAREN cpp_macro_sig RPAREN cpp_macro_decl_tokens %dprec 2 { $name_token->type = PSI_T_NAME; $macro = psi_cpp_macro_decl_init($cpp_macro_sig, $cpp_macro_decl_tokens, NULL); $macro->token = psi_token_copy($name_token); } -| cpp_special_name_token[name_token] cpp_macro_decl_tokens { +| name_token cpp_macro_exp[num_exp] %dprec 2 { $name_token->type = PSI_T_NAME; - $macro = psi_cpp_macro_decl_init(NULL, $cpp_macro_decl_tokens, NULL); + $macro = psi_cpp_macro_decl_init(NULL, psi_num_exp_tokens($num_exp, NULL), $num_exp); + $macro->token = psi_token_copy($name_token); +} +| name_token quoted_strings[strings] %dprec 2 { + struct psi_plist *list = psi_plist_init((psi_plist_dtor) psi_token_free); + $name_token->type = PSI_T_NAME; + $macro = psi_cpp_macro_decl_init(NULL, psi_plist_add(list, &$strings), NULL); $macro->token = psi_token_copy($name_token); } ; @@ -633,7 +691,8 @@ cpp_macro_exp[exp]: $name_token->type = PSI_T_NAME; exists = psi_cpp_defined(P->preproc, $name_token); $exp = psi_num_exp_init_num(psi_number_init(PSI_T_UINT8, &exists, 0)); - $exp->token = psi_token_copy($name_token); + $exp->token = psi_token_copy($DEFINED); + $exp->data.n->token = psi_token_copy($name_token); } } | DEFINED LPAREN name_token RPAREN { @@ -643,7 +702,8 @@ cpp_macro_exp[exp]: $name_token->type = PSI_T_NAME; exists = psi_cpp_defined(P->preproc, $name_token); $exp = psi_num_exp_init_num(psi_number_init(PSI_T_UINT8, &exists, 0)); - $exp->token = psi_token_copy($name_token); + $exp->token = psi_token_copy($DEFINED); + $exp->data.n->token = psi_token_copy($name_token); } } | NUMBER { @@ -671,6 +731,7 @@ cpp_macro_exp[exp]: $exp = psi_num_exp_init_num(psi_number_init(PSI_T_FUNCTION, psi_cpp_macro_call_init($name_token->text, $cpp_macro_call_args), 0)); $exp->token = psi_token_copy($name_token); + $exp->data.n->token = psi_token_copy($name_token); } ; @@ -692,63 +753,24 @@ cpp_macro_call_arg_list[args]: ; constant[const]: - CONST constant_type NSNAME EQUALS impl_def_val EOS { - $const = psi_const_init($constant_type, $NSNAME->text, $impl_def_val); + CONST impl_type_restricted[type] NSNAME EQUALS impl_def_val EOS { + $const = psi_const_init($type, $NSNAME->text, $impl_def_val); $const->token = psi_token_copy($NSNAME); } ; -constant_type[type]: - constant_type_token[token] { - $type = psi_const_type_init($token->type, $token->text); -} -; - -constant_type_token: - BOOL -| INT -| FLOAT -| STRING -; - impl_def_val[val]: - %empty { - $val = NULL; + impl_def_val_token[token] %dprec 2 { + $val = psi_impl_def_val_init($token->type, $token->text); + $val->token = psi_token_copy($token); } | num_exp[num] %dprec 1 { - if (psi_num_exp_validate(PSI_DATA(P), $num, NULL, NULL, NULL, NULL, NULL)) { - impl_val res = {0}; - token_t type = psi_num_exp_exec($num, &res, NULL, &P->preproc->defs); - - if (type == PSI_T_FLOAT || type == PSI_T_DOUBLE) { - $val = psi_impl_def_val_init(type, NULL); - } else { - $val = psi_impl_def_val_init(PSI_T_INT, NULL); - } - - switch (type) { - case PSI_T_UINT8: $val->ival.zend.lval = res.u8; break; - case PSI_T_UINT16: $val->ival.zend.lval = res.u16; break; - case PSI_T_UINT32: $val->ival.zend.lval = res.u32; break; - case PSI_T_UINT64: $val->ival.zend.lval = res.u64; break; /* FIXME */ - case PSI_T_INT8: $val->ival.zend.lval = res.i8; break; - case PSI_T_INT16: $val->ival.zend.lval = res.i16; break; - case PSI_T_INT32: $val->ival.zend.lval = res.i32; break; - case PSI_T_INT64: $val->ival.zend.lval = res.i64; break; - case PSI_T_FLOAT: $val->ival.dval = res.fval; break; - case PSI_T_DOUBLE: $val->ival.dval = res.dval; break; - default: - assert(0); - - } - } else { - $val = NULL; - } - psi_num_exp_free(&$num); + $val = psi_impl_def_val_init(PSI_T_NUMBER, $num); + $val->token = psi_token_copy($num->token); } -| impl_def_val_token[token] %dprec 2 { +| quoted_strings[token] { $val = psi_impl_def_val_init($token->type, $token->text); - $val->token = psi_token_copy($token); + $val->token = $token; } ; @@ -756,13 +778,13 @@ impl_def_val_token: NULL | TRUE | FALSE -| QUOTED_STRING ; decl_typedef[def]: TYPEDEF typedef[def_] EOS { $def = $def_; } +/* | TYPEDEF VOID name_token EOS { $def = psi_decl_arg_init( psi_decl_type_init(PSI_T_VOID, $VOID->text), @@ -772,6 +794,7 @@ decl_typedef[def]: $def->type->token = psi_token_copy($VOID); $def->var->token = psi_token_copy($name_token); } +*/ | CPP_EXTENSION TYPEDEF typedef[def_] EOS { $def = $def_; } @@ -873,13 +896,18 @@ typedef_anon_decl[def]: ; qualified_decl_type[type]: - CONST decl_type[type_] { + decl_type +| decl_type_qualifier_token decl_type[type_] { $type = $type_; } -| VOLATILE decl_type[type_] { +| qualified_decl_type[type_] decl_type_qualifier_token { $type = $type_; } -| decl_type +; + +decl_type_qualifier_token: + CONST +| VOLATILE ; decl_type[type]: @@ -914,9 +942,12 @@ decl_type_simple[type]: | NAME[type_] { $type = psi_token_copy($type_); } +| VOID[type_] { + $type = psi_token_copy($type_); +} ; -decl_real_type[type]: +decl_real_type[type]: /* allocated, so free, if set */ FLOAT[type_] { $type = psi_token_copy($type_); } @@ -933,7 +964,7 @@ int_signed[i]: | UNSIGNED ; -int_width[i]: +int_width[i]: /* allocated, so free, if set */ SHORT { $i = psi_token_copy($SHORT); } @@ -945,7 +976,7 @@ int_width[i]: } ; -decl_int_type[type]: +decl_int_type[type]: /* allocated, so free, if set */ CHAR { $type = psi_token_copy($CHAR); } @@ -955,7 +986,7 @@ decl_int_type[type]: | int_signed int_signed_types { if ($2) { $type = psi_token_cat(" ", 2, $1, $2); - free($2); + psi_token_free(&$2); } else { $type = psi_token_copy($1); } @@ -963,15 +994,15 @@ decl_int_type[type]: | int_width int_width_types { if ($2) { $type = psi_token_cat(" ", 2, $1, $2); - free($1); - free($2); + psi_token_free(&$1); + psi_token_free(&$2); } else { $type = $1; } } ; -int_signed_types[type]: +int_signed_types[type]: /* allocated, so free, if set */ %empty { $type = NULL; } @@ -1015,7 +1046,7 @@ signed_long_types[type]: | LONG INT ; -int_width_types[type]: +int_width_types[type]: /* allocated, so free, if set */ %empty { $type = NULL; } @@ -1025,7 +1056,7 @@ int_width_types[type]: | int_signed int_signed_types { if ($2) { $type = psi_token_cat(" ", 2, $1, $2); - free($2); + psi_token_free(&$2); } else { $type = psi_token_copy($1); } @@ -1035,36 +1066,76 @@ int_width_types[type]: decl_stmt: decl decl_asm EOS { $decl_stmt = $decl; + if ($decl_asm) { + $decl->redir = zend_string_copy($decl_asm->text); + psi_token_free(&$decl_asm); + } } | CPP_EXTENSION decl decl_asm EOS { $decl_stmt = $decl; + if ($decl_asm) { + $decl->redir = zend_string_copy($decl_asm->text); + psi_token_free(&$decl_asm); + } } ; decl_asm: - %empty -| CPP_ASM LPAREN ignored_quoted_strings RPAREN -; - -ignored_quoted_strings: - QUOTED_STRING -| ignored_quoted_strings QUOTED_STRING + %empty { + $decl_asm = NULL; +} +| CPP_ASM LPAREN quoted_strings RPAREN { + $decl_asm = $quoted_strings; +} ; -decl_ext_var_stmt: - decl_ext_var EOS +quoted_strings[strings]: + QUOTED_STRING { + $strings = psi_token_copy($QUOTED_STRING); +} +| quoted_strings[strings_] QUOTED_STRING { + $strings = psi_token_cat("", 2, $strings_, $QUOTED_STRING); + psi_token_free(&$strings_); +} ; -decl_ext_var: - NAME decl_arg decl_ext_var_list { - psi_decl_arg_free(&$decl_arg); +decl_extvar_stmt[list]: + NAME decl_arg decl_extvar_list[vars] EOS { + struct psi_plist *list = psi_plist_init((psi_plist_dtor) psi_decl_extvar_free); + + if ($vars) { + size_t i = 0; + struct psi_decl_var *var; + + while (psi_plist_get($vars, i++, &var)) { + if (psi_decl_extvar_is_blacklisted(var->name->val)) { + psi_decl_var_free(&var); + } else { + struct psi_decl_extvar *evar = psi_decl_extvar_init( + psi_decl_arg_init(psi_decl_type_copy($decl_arg->type), var)); + list = psi_plist_add(list, &evar); + } + } + free($vars); + } + + if (psi_decl_extvar_is_blacklisted($decl_arg->var->name->val)) { + psi_decl_arg_free(&$decl_arg); + } else { + struct psi_decl_extvar *evar = psi_decl_extvar_init($decl_arg); + list = psi_plist_add(list, &evar); + } + + $list = list; } ; -decl_ext_var_list: - %empty +decl_extvar_list[list]: + %empty { + $list = NULL; +} | COMMA decl_vars { - psi_plist_free($decl_vars); + $list = $decl_vars; } ; @@ -1078,17 +1149,20 @@ decl_vars[vars]: ; ignored_decl: - STATIC decl_body ignored_decl_body { - psi_decl_free(&$decl_body); -} -| CPP_INLINE decl_body ignored_decl_body { - psi_decl_free(&$decl_body); -} -| STATIC CPP_INLINE decl_body ignored_decl_body { - psi_decl_free(&$decl_body); + ignored_decl_qualifiers decl_body ignored_decl_body { + $ignored_decl = $decl_body; } ; +ignored_decl_qualifiers: + STATIC +| STATIC CPP_INLINE +| CPP_EXTENSION CPP_INLINE +| CPP_EXTENSION STATIC CPP_INLINE +| CPP_INLINE +| NAME CPP_INLINE +; + ignored_decl_body: LBRACE ignored_decl_body_stmts RBRACE ; @@ -1150,6 +1224,74 @@ decl_functor_body[decl]: $decl->func->var->array_size = $as; } } +| qualified_decl_type[rval_type] indirection[i] LPAREN indirection[unused1] name_token[NAME] LPAREN decl_args[args] RPAREN RPAREN LPAREN decl_args[rval_args] RPAREN array_size[as] { + (void) $unused1; + $NAME->type = PSI_T_NAME; + + struct psi_token *type_token = psi_token_append("@", psi_token_copy($NAME), 1, "rval"); + struct psi_decl_arg *rval_func = psi_decl_arg_init($rval_type, psi_decl_var_init(type_token->text, $i, 0)); + struct psi_decl *rval_decl = psi_decl_init(rval_func, $rval_args); + + rval_func->var->token = psi_token_copy(type_token); + rval_func->token = psi_token_copy(type_token); + if ($as) { + rval_func->var->pointer_level += 1; + rval_func->var->array_size = $as; + } + + struct psi_decl_type *type = psi_decl_type_init(PSI_T_FUNCTION, type_token->text); + struct psi_decl_arg *func = psi_decl_arg_init(type, psi_decl_var_init($NAME->text, 1, 0)); + + type->real.func = rval_decl; + func->var->token = psi_token_copy($NAME); + func->token = psi_token_copy($NAME); + + $decl = psi_decl_init(func, $args); +} +| qualified_decl_type[rval_type] indirection[i] LPAREN indirection[unused1] LPAREN indirection[unused2] name_token[NAME] RPAREN LPAREN decl_args[args] RPAREN RPAREN LPAREN decl_args[rval_args] RPAREN array_size[as] { + (void) $unused1; + (void) $unused2; + $NAME->type = PSI_T_NAME; + + struct psi_token *type_token = psi_token_append("@", psi_token_copy($NAME), 1, "rval"); + struct psi_decl_arg *rval_func = psi_decl_arg_init($rval_type, psi_decl_var_init(type_token->text, $i, 0)); + struct psi_decl *rval_decl = psi_decl_init(rval_func, $rval_args); + + rval_func->var->token = psi_token_copy(type_token); + rval_func->token = psi_token_copy(type_token); + if ($as) { + rval_func->var->pointer_level += 1; + rval_func->var->array_size = $as; + } + + struct psi_decl_type *type = psi_decl_type_init(PSI_T_FUNCTION, type_token->text); + struct psi_decl_arg *func = psi_decl_arg_init(type, psi_decl_var_init($NAME->text, 1, 0)); + + type->real.func = rval_decl; + func->var->token = psi_token_copy($NAME); + func->token = psi_token_copy($NAME); + type->token = type_token; + + $decl = psi_decl_init(func, $args); +} +; + +decl_anon_functor_body[decl]: + decl_anon_functor[func] LPAREN decl_args[args] RPAREN array_size[as] { + $decl = psi_decl_init($func, $args); + if ($as) { + $decl->func->var->pointer_level += 1; + $decl->func->var->array_size = $as; + } +} +| decl_anon_functor[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] { + $decl = psi_decl_init($func, $args); + $decl->varargs = 1; + if ($as) { + $decl->func->var->pointer_level += 1; + $decl->func->var->array_size = $as; + } +} ; decl_functor[arg]: @@ -1160,6 +1302,8 @@ decl_functor[arg]: $arg->var->token = psi_token_copy($NAME); $arg->token = psi_token_copy($NAME); } + +/* | CONST VOID pointers LPAREN indirection[unused1] name_token[NAME] RPAREN { (void) $unused1; $NAME->type = PSI_T_NAME; @@ -1193,10 +1337,53 @@ decl_functor[arg]: $arg->var->token = psi_token_copy($NAME); $arg->token = psi_token_copy($NAME); } +*/ +; + +decl_anon_functor[arg]: + qualified_decl_type[type] indirection[i] LPAREN indirection[unused1] RPAREN { + (void) $unused1; + $arg = psi_decl_arg_init($type, psi_decl_var_init(NULL, $i, 0)); + $arg->var->token = psi_token_copy($LPAREN); + $arg->token = psi_token_copy($LPAREN); +} +/* +| CONST VOID pointers LPAREN indirection[unused1] RPAREN { + (void) $unused1; + $arg = psi_decl_arg_init( + psi_decl_type_init($VOID->type, $VOID->text), + psi_decl_var_init(NULL, $pointers, 0) + ); + $arg->type->token = psi_token_copy($VOID); + $arg->var->token = psi_token_copy($VOID); + $arg->token = psi_token_copy($VOID); +} +| VOID pointers LPAREN indirection[unused1] RPAREN { + (void) $unused1; + $arg = psi_decl_arg_init( + psi_decl_type_init($VOID->type, $VOID->text), + psi_decl_var_init(NULL, $pointers, 0) + ); + $arg->type->token = psi_token_copy($VOID); + $arg->var->token = psi_token_copy($VOID); + $arg->token = psi_token_copy($VOID); +} +| VOID LPAREN indirection[unused1] RPAREN { + (void) $unused1; + $arg = psi_decl_arg_init( + psi_decl_type_init($VOID->type, $VOID->text), + psi_decl_var_init(NULL, 0, 0) + ); + $arg->type->token = psi_token_copy($VOID); + $arg->var->token = psi_token_copy($VOID); + $arg->token = psi_token_copy($VOID); +} +*/ ; decl_func[func]: decl_arg + /* | VOID name_token[NAME] { $func = psi_decl_arg_init( psi_decl_type_init($VOID->type, $VOID->text), @@ -1206,26 +1393,47 @@ decl_func[func]: $func->var->token = psi_token_copy($NAME); $func->token = psi_token_copy($NAME); } +*/ ; decl_args[args]: %empty { $args = NULL; } -| VOID { +| VOID %dprec 2 { $args = NULL; } -| decl_anon_arg[arg] { +| decl_arg_list[args_] %dprec 1 { + $args = $args_; +} +; + +decl_arg_list[args]: + decl_anon_arg[arg] { $args = psi_plist_add(psi_plist_init((psi_plist_dtor) psi_decl_arg_free), &$arg); } -| decl_args[args_] COMMA decl_anon_arg[arg] { +| decl_arg_list[args_] COMMA decl_anon_arg[arg] { $args = psi_plist_add($args_, &$arg); } ; decl_anon_arg[arg]: -/* FIXME decl_functor_body_anon */ - decl_arg %dprec 2 { + decl_anon_functor_body[decl] { + char digest[17]; + struct psi_token *name; + + psi_token_hash($decl->func->token, digest); + name = psi_token_append("@", psi_token_copy($decl->func->token), 2, "funct", digest); + + $arg = psi_decl_arg_init( + psi_decl_type_init(PSI_T_FUNCTION, name->text), + psi_decl_var_copy($decl->func->var) + ); + $arg->token = name; + $arg->type->token = psi_token_copy($decl->func->token); + $arg->type->real.func = $decl; +} +| decl_arg %dprec 2 { $arg = $decl_arg; } | qualified_decl_type[type] indirection %dprec 1 { @@ -1234,6 +1442,7 @@ decl_anon_arg[arg]: psi_decl_var_init(NULL, $indirection, 0) ); } +/* | CONST VOID pointers { $arg = psi_decl_arg_init( psi_decl_type_init($VOID->type, $VOID->text), @@ -1252,6 +1461,7 @@ decl_anon_arg[arg]: $arg->var->token = psi_token_copy($VOID); $arg->token = psi_token_copy($VOID); } +*/ ; decl_arg[arg]: @@ -1266,6 +1476,7 @@ decl_arg[arg]: | qualified_decl_type[type] decl_var[var] { $arg = psi_decl_arg_init($type, $var); } +/* | CONST VOID pointers name_token[NAME] { $NAME->type = PSI_T_NAME; $arg = psi_decl_arg_init( @@ -1286,6 +1497,7 @@ decl_arg[arg]: $arg->var->token = psi_token_copy($NAME); $arg->token = psi_token_copy($NAME); } +*/ ; decl_var[var]: @@ -1392,7 +1604,7 @@ decl_vars_with_layout[vars]: ; decl_enum[enum]: - enum_name LBRACE decl_enum_items[list] RBRACE { + enum_name LBRACE decl_enum_items[list] optional_comma RBRACE { $enum = psi_decl_enum_init($enum_name->text, $list); $enum->token = $enum_name; } @@ -1492,6 +1704,7 @@ sizeof_body[sizeof]: if ($indirection) { int8_t sizeof_void_p = sizeof(void *); $sizeof = psi_number_init(PSI_T_INT8, &sizeof_void_p, 0); + psi_decl_type_free(&$decl_type); } else { $sizeof = psi_number_init(PSI_T_SIZEOF, $decl_type, 0); } @@ -1508,7 +1721,8 @@ sizeof_body_notypes[sizeof]: $sizeof = psi_number_init(PSI_T_INT8, &sizeof_a, 0); } | QUOTED_STRING { - $sizeof = psi_number_init(PSI_T_INT64, &$QUOTED_STRING->size, 0); + uint64_t len = $QUOTED_STRING->text->len + 1; + $sizeof = psi_number_init(PSI_T_UINT64, &len, 0); } ; @@ -1561,18 +1775,23 @@ optional_name[name]: } ; +optional_comma: + %empty +| COMMA +; + decl_layout[l]: %empty { $l = NULL; } | COLON NUMBER[width] { - $l = psi_layout_init(0, 0, psi_layout_init(0, atol($width->text), NULL)); + $l = psi_layout_init(0, 0, psi_layout_init(0, atol($width->text->val), NULL)); } | COLON COLON LPAREN NUMBER[align] COMMA NUMBER[size] RPAREN { - $l = psi_layout_init(atol($align->text), atol($size->text), NULL); + $l = psi_layout_init(atol($align->text->val), atol($size->text->val), NULL); } | COLON NUMBER[width] COLON COLON LPAREN NUMBER[align] COMMA NUMBER[size] RPAREN { - $l = psi_layout_init(atol($align->text), atol($size->text), psi_layout_init(0, atol($width->text), NULL)); + $l = psi_layout_init(atol($align->text->val), atol($size->text->val), psi_layout_init(0, atol($width->text->val), NULL)); } ; @@ -1582,8 +1801,8 @@ align_and_size[as]: $as.len = 0; } | COLON COLON LPAREN NUMBER[align] COMMA NUMBER[size] RPAREN { - $as.pos = atol($align->text); - $as.len = atol($size->text); + $as.pos = atol($align->text->val); + $as.len = atol($size->text->val); } ; @@ -1591,18 +1810,30 @@ array_size[as]: %empty { $as = 0; } -| LBRACKET RBRACKET { +| LBRACKET array_qualifier_token RBRACKET { $as = 0; } | LBRACKET num_exp RBRACKET { - if (psi_num_exp_validate(PSI_DATA(P), $num_exp, NULL, NULL, NULL, NULL, NULL)) { - $as = psi_long_num_exp($num_exp, NULL, &P->preproc->defs); + struct psi_validate_scope scope = {0}; + psi_validate_scope_ctor(&scope); + scope.defs = &P->preproc->defs; + if (psi_num_exp_validate(PSI_DATA(P), $num_exp, &scope)) { + $as = psi_num_exp_get_long($num_exp, NULL, &P->preproc->defs); } else { $as = 0; } + psi_num_exp_free(&$num_exp); + psi_validate_scope_dtor(&scope); } ; +array_qualifier_token: + %empty +| CPP_RESTRICT +| VOLATILE +| CONST +; + indirection[i]: %empty { $i = 0; @@ -1630,7 +1861,12 @@ asterisks[a]: asterisk: ASTERISK -| ASTERISK CONST +| ASTERISK pointer_qualifier_token +; + +pointer_qualifier_token: + CONST +| VOLATILE ; /* @@ -1701,13 +1937,28 @@ impl_type[type]: } ; +impl_type_restricted[type]: + impl_type_restricted_token[token] { + $type = psi_impl_type_init($token->type, $token->text); + $type->token = psi_token_copy($token); +} +; + impl_type_token: - VOID -| MIXED -| BOOL + impl_type_restricted_token +| impl_type_extended_token +; + +impl_type_restricted_token: + BOOL | INT | FLOAT | STRING +; + +impl_type_extended_token: + VOID +| MIXED | ARRAY | OBJECT | CALLABLE @@ -1807,7 +2058,12 @@ let_calloc[calloc]: let_callback[callback]: CALLBACK callback_rval[func] LPAREN impl_var[var] LPAREN callback_arg_list[args] RPAREN RPAREN { - $callback = psi_let_callback_init(psi_let_func_init($func->type, $func->text, $var), $args); + $callback = psi_let_callback_init(psi_let_func_init($func->type, $func->text, $var), $args, NULL); + $callback->func->token = psi_token_copy($func); + $callback->token = psi_token_copy($CALLBACK); +} +| CALLBACK LPAREN call_decl_vars[cb_args] RPAREN AS callback_rval[func] LPAREN impl_var[var] LPAREN callback_arg_list[args] RPAREN RPAREN { + $callback = psi_let_callback_init(psi_let_func_init($func->type, $func->text, $var), $args, $cb_args); $callback->func->token = psi_token_copy($func); $callback->token = psi_token_copy($CALLBACK); }