Build C style var/func/abs decl types from the outside in.

QuakeC style are built from the inside out.
This commit is contained in:
Bill Currie 2011-02-02 15:13:34 +09:00
parent 7fb8c8247e
commit 1fe031e8cb

View file

@ -158,7 +158,7 @@ int yylex (void);
%type <param> function_params var_list param_declaration %type <param> function_params var_list param_declaration
%type <symbol> var_decl function_decl %type <symbol> var_decl function_decl
%type <spec> abstract_decl abs_decl %type <symbol> abstract_decl abs_decl
%type <symbol> tag optional_tag %type <symbol> tag optional_tag
%type <spec> struct_specifier struct_def struct_decl %type <spec> struct_specifier struct_def struct_decl
@ -284,7 +284,7 @@ spec_merge (specifier_t spec, specifier_t new)
%} %}
//%expect 0 %expect 0
%% %%
@ -317,8 +317,11 @@ external_def
function_body function_body
: optional_state_expr : optional_state_expr
{ {
symbol_t *sym = $<symbol>0;
sym->type = append_type (sym->type, $<spec>-1.type);
$<symtab>$ = current_symtab; $<symtab>$ = current_symtab;
current_func = begin_function ($<symbol>0, 0, current_symtab); current_func = begin_function (sym, 0, current_symtab);
current_symtab = current_func->symtab; current_symtab = current_func->symtab;
} }
compound_statement compound_statement
@ -328,7 +331,10 @@ function_body
} }
| '=' '#' expr ';' | '=' '#' expr ';'
{ {
build_builtin_function ($<symbol>0, $3); symbol_t *sym = $<symbol>0;
sym->type = append_type (sym->type, $<spec>-1.type);
build_builtin_function (sym, $3);
} }
; ;
@ -339,6 +345,10 @@ external_decl_list
external_decl external_decl
: var_decl : var_decl
{
$1->type = append_type ($1->type, $<spec>0.type);
print_type ($1->type); puts ("\n");
}
| var_decl '=' var_initializer | var_decl '=' var_initializer
| function_decl | function_decl
; ;
@ -494,51 +504,54 @@ struct_decl
| ':' expr %prec COMMA {} | ':' expr %prec COMMA {}
; ;
//FIXME function overloading
var_decl var_decl
: NAME %prec COMMA : NAME %prec COMMA
{ {
$$ = check_redefined ($1); $$ = check_redefined ($1);
$$->type = $<spec>0.type; $$->type = 0;
} }
| var_decl function_params | var_decl function_params
{ {
$$->type = parse_params ($1->type, $2); $$->type = append_type ($$->type, parse_params (0, $2));
print_type ($$->type);
} }
| var_decl array_decl | var_decl array_decl
{ {
$$->type = array_type ($1->type, $2); $$->type = append_type ($$->type, array_type (0, $2));
} }
| '*' cs var_decl %prec UNARY | '*' var_decl %prec UNARY
{ {
$$ = $3; $$ = $2;
$$->type = pointer_type ($3->type); $$->type = append_type ($$->type, pointer_type (0));
} }
| '(' cs var_decl ')' { $$ = $3; } | '(' var_decl ')' { $$ = $2; }
; ;
//FIXME function overloading
function_decl function_decl
: '*' cs function_decl : '*' function_decl
{ {
$$ = $3; $$ = $2;
$$->type = pointer_type ($<spec>2.type); $$->type = append_type ($$->type, pointer_type (0));
} }
| function_decl array_decl | function_decl array_decl
{ {
$$ = $1; $$ = $1;
$$->type = array_type ($1->type, $2); $$->type = append_type ($$->type, array_type (0, $2));
} }
| '(' cs function_decl ')' { $$ = $3; } | '(' function_decl ')' { $$ = $2; }
| function_decl function_params | function_decl function_params
{ {
$$ = $1; $$ = $1;
$$->params = $2; $$->params = $2;
$$->type = parse_params ($<spec>0.type, $2); $$->type = append_type ($$->type, parse_params (0, $2));
} }
| NAME function_params | NAME function_params
{ {
$$ = check_redefined ($1); $$ = check_redefined ($1);
$$->params = $2; $$->params = $2;
$$->type = parse_params ($<spec>0.type, $2); $$->type = parse_params (0, $2);
$$ = function_symbol ($$, 0, 1); $$ = function_symbol ($$, 0, 1);
} }
; ;
@ -564,41 +577,52 @@ var_list
; ;
param_declaration param_declaration
: type var_decl { $$ = new_param (0, $2->type, $2->name); } : type var_decl
| abstract_decl { $$ = new_param (0, $1.type, 0); } {
$2->type = append_type ($2->type, $1.type);
$$ = new_param (0, $2->type, $2->name);
}
| abstract_decl { $$ = new_param (0, $1->type, 0); }
| ELLIPSIS { $$ = new_param (0, 0, 0); } | ELLIPSIS { $$ = new_param (0, 0, 0); }
; ;
abstract_decl abstract_decl
: type abs_decl { $$ = $2; } : type abs_decl
| TYPE_NAME abs_decl { $$ = $2; } {
$$ = $2;
$$->type = append_type ($$->type, $1.type);
}
| TYPE_NAME abs_decl
{
$$ = $2;
$$->type = append_type ($$->type, $1->type);
}
; ;
//FIXME type construction is inside-out
abs_decl abs_decl
: /* empty */ { $$ = $<spec>0; } : /* empty */ { $$ = new_symbol (""); }
| '(' cs abs_decl ')' function_params | '(' abs_decl ')' function_params
{ {
$$ = $3; $$ = $2;
$$.type = parse_params ($3.type, $5); $$->type = append_type ($$->type, parse_params (0, $4));
} }
| '*' cs abs_decl | '*' abs_decl
{ {
$$ = $3; $$ = $2;
$$.type = pointer_type ($3.type); $$->type = append_type ($$->type, pointer_type (0));
} }
| abs_decl array_decl | abs_decl array_decl
{ {
$$ = $1; $$ = $1;
$$.type = array_type ($1.type, $2); $$->type = append_type ($$->type, array_type (0, $2));
} }
| '(' cs abs_decl ')' | '(' abs_decl ')'
{ {
$$ = $3; $$ = $2;
} }
; ;
cs : { $<spec>$ = $<spec>0; } ;
array_decl array_decl
: '[' fexpr ']' : '[' fexpr ']'
{ {