Allocate space for defs and handle basic initializations.

Block initializers (arrays and structs) are still broken.
This commit is contained in:
Bill Currie 2011-01-25 12:07:02 +09:00
parent 30701980bc
commit 726f293d0d
3 changed files with 92 additions and 56 deletions

View file

@ -70,9 +70,16 @@ typedef enum storage_class_e {
} storage_class_t;
def_t *new_def (const char *name, struct type_s *type,
struct defspace_s *scope, storage_class_t storage);
struct defspace_s *space, storage_class_t storage);
void free_def (def_t *def);
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);
struct symbol_s;
struct expr_s;
void initialize_def (struct symbol_s *sym, struct type_s *type,
struct expr_s *init, struct defspace_s *space,
storage_class_t storage);
#endif//__def_h

View file

@ -57,6 +57,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "reloc.h"
#include "strpool.h"
#include "struct.h"
#include "symtab.h"
#include "type.h"
static def_t *free_defs;
@ -149,3 +150,69 @@ def_to_ddef (def_t *def, ddef_t *ddef, int aux)
ddef->ofs = def->offset;
ddef->s_name = ReuseString (def->name);
}
void
initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
storage_class_t storage)
{
if (sym->table == current_symtab) {
if (sym->sy_type != sy_var || sym->type != type) {
error (0, "%s redefined", sym->name);
sym = new_symbol (sym->name);
} else {
// is var and same type
if (!sym->s.def)
internal_error (0, "half defined var");
if (storage == st_extern) {
if (init)
warning (0, "initializing external variable");
return;
}
if (init && sym->s.def->initialized) {
error (0, "%s redefined", sym->name);
return;
}
}
} else if (sym->table) {
sym = new_symbol (sym->name);
}
sym->type = type;
symtab_addsymbol (current_symtab, sym);
if (storage == st_global && init) {
sym->sy_type = sy_const;
memset (&sym->s.value, 0, sizeof (&sym->s.value));
if (init->type != ex_value) { //FIXME arrays/structs
error (0, "non-constant initializier");
} else {
sym->s.value = init->e.value;
}
return;
}
if (sym->s.def && sym->s.def->external) {
free_def (sym->s.def);
sym->s.def = 0;
}
if (!sym->s.def)
sym->s.def = new_def (sym->name, type, space, storage);
if (storage == st_extern) {
if (init)
warning (0, "initializing external variable");
return;
}
if (!init)
return;
if (!type_assignable (type, get_type (init))) {
error (init, "type mismatch in initializer");
return;
}
if (local_expr) {
append_expr (local_expr, assign_expr (new_symbol_expr (sym), init));
} else {
if (init->type != ex_value) { //FIXME arrays/structs
error (0, "non-constant initializier");
return;
}
memcpy (D_POINTER (void, sym->s.def), &init->e.value,
type_size (type) * sizeof (pr_type_t));
}
}

View file

@ -163,8 +163,9 @@ int yylex (void);
%type <symbol> fdef_name cfunction_def func_def
%type <param> function_decl
%type <param> param param_list
%type <symbol> opt_initializer methoddef var_initializer
%type <expr> opt_expr fexpr expr element_list element_list1 element
%type <symbol> methoddef
%type <expr> opt_initializer var_initializer
%type <expr> opt_expr fexpr expr element_list element
%type <expr> opt_state_expr think opt_step array_decl texpr
%type <expr> statement statements statement_block
%type <expr> label break_label continue_label
@ -192,7 +193,6 @@ int yylex (void);
function_t *current_func;
param_t *current_params;
expr_t *current_init;
class_type_t *current_class;
expr_t *local_expr;
vis_e current_visibility;
@ -508,10 +508,8 @@ def_list
def_item
: def_name opt_initializer
{
$1 = check_redefined ($1);
$1->type = $<type>0;
$1->visibility = current_visibility;
symtab_addsymbol (current_symtab, $1);
initialize_def ($1, $<type>0, $2, pr.near_data, //FIXME right space
current_storage);
}
;
@ -583,35 +581,24 @@ def_name
;
opt_initializer
: /*empty*/
{
}
: /*empty*/ { $$ = 0; }
| var_initializer { $$ = $1; }
;
var_initializer
: '=' expr // don't bother folding twice
{
}
| '=' '{' { } element_list '}'
{
}
: '=' fexpr { $$ = $2; }
| '=' '{' element_list opt_comma '}' { $$ = $3; }
;
opt_state_expr
: /* emtpy */
{
$$ = 0;
}
| '[' fexpr ',' think opt_step ']'
{
$$ = build_state_expr ($2, $4, $5);
}
: /* emtpy */ { $$ = 0; }
| '[' fexpr ',' think opt_step ']' { $$ = build_state_expr ($2, $4, $5); }
;
think
: def_name
{
internal_error (0, "FIXME");
}
| '(' fexpr ')'
{
@ -625,45 +612,20 @@ opt_step
;
element_list
: /* empty */
{
$$ = new_block_expr ();
}
| element_list1 opt_comma
{
$$ = current_init;
}
;
element_list1
: element
{
append_expr (current_init, $1);
$$ = new_block_expr ();
append_expr ($$, $1);
}
| element_list1 ',' element
| element_list ',' element
{
append_expr (current_init, $3);
append_expr ($$, $3);
}
;
element
: '{'
{
$<expr>$ = current_init;
current_init = new_block_expr ();
}
element_list
{
current_init = $<expr>2;
}
'}'
{
$$ = $3;
}
| fexpr
{
$$ = $1;
}
: '{' element_list opt_comma '}' { $$ = $2; }
| fexpr { $$ = $1; }
;
opt_comma