mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
Allocate space for defs and handle basic initializations.
Block initializers (arrays and structs) are still broken.
This commit is contained in:
parent
30701980bc
commit
726f293d0d
3 changed files with 92 additions and 56 deletions
|
@ -70,9 +70,16 @@ typedef enum storage_class_e {
|
||||||
} storage_class_t;
|
} storage_class_t;
|
||||||
|
|
||||||
def_t *new_def (const char *name, struct type_s *type,
|
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 free_def (def_t *def);
|
||||||
|
|
||||||
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);
|
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
|
#endif//__def_h
|
||||||
|
|
|
@ -57,6 +57,7 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
#include "strpool.h"
|
#include "strpool.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
|
#include "symtab.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
static def_t *free_defs;
|
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->ofs = def->offset;
|
||||||
ddef->s_name = ReuseString (def->name);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -163,8 +163,9 @@ int yylex (void);
|
||||||
%type <symbol> fdef_name cfunction_def func_def
|
%type <symbol> fdef_name cfunction_def func_def
|
||||||
%type <param> function_decl
|
%type <param> function_decl
|
||||||
%type <param> param param_list
|
%type <param> param param_list
|
||||||
%type <symbol> opt_initializer methoddef var_initializer
|
%type <symbol> methoddef
|
||||||
%type <expr> opt_expr fexpr expr element_list element_list1 element
|
%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> opt_state_expr think opt_step array_decl texpr
|
||||||
%type <expr> statement statements statement_block
|
%type <expr> statement statements statement_block
|
||||||
%type <expr> label break_label continue_label
|
%type <expr> label break_label continue_label
|
||||||
|
@ -192,7 +193,6 @@ int yylex (void);
|
||||||
|
|
||||||
function_t *current_func;
|
function_t *current_func;
|
||||||
param_t *current_params;
|
param_t *current_params;
|
||||||
expr_t *current_init;
|
|
||||||
class_type_t *current_class;
|
class_type_t *current_class;
|
||||||
expr_t *local_expr;
|
expr_t *local_expr;
|
||||||
vis_e current_visibility;
|
vis_e current_visibility;
|
||||||
|
@ -508,10 +508,8 @@ def_list
|
||||||
def_item
|
def_item
|
||||||
: def_name opt_initializer
|
: def_name opt_initializer
|
||||||
{
|
{
|
||||||
$1 = check_redefined ($1);
|
initialize_def ($1, $<type>0, $2, pr.near_data, //FIXME right space
|
||||||
$1->type = $<type>0;
|
current_storage);
|
||||||
$1->visibility = current_visibility;
|
|
||||||
symtab_addsymbol (current_symtab, $1);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -583,35 +581,24 @@ def_name
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_initializer
|
opt_initializer
|
||||||
: /*empty*/
|
: /*empty*/ { $$ = 0; }
|
||||||
{
|
|
||||||
}
|
|
||||||
| var_initializer { $$ = $1; }
|
| var_initializer { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
var_initializer
|
var_initializer
|
||||||
: '=' expr // don't bother folding twice
|
: '=' fexpr { $$ = $2; }
|
||||||
{
|
| '=' '{' element_list opt_comma '}' { $$ = $3; }
|
||||||
}
|
|
||||||
| '=' '{' { } element_list '}'
|
|
||||||
{
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_state_expr
|
opt_state_expr
|
||||||
: /* emtpy */
|
: /* emtpy */ { $$ = 0; }
|
||||||
{
|
| '[' fexpr ',' think opt_step ']' { $$ = build_state_expr ($2, $4, $5); }
|
||||||
$$ = 0;
|
|
||||||
}
|
|
||||||
| '[' fexpr ',' think opt_step ']'
|
|
||||||
{
|
|
||||||
$$ = build_state_expr ($2, $4, $5);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
think
|
think
|
||||||
: def_name
|
: def_name
|
||||||
{
|
{
|
||||||
|
internal_error (0, "FIXME");
|
||||||
}
|
}
|
||||||
| '(' fexpr ')'
|
| '(' fexpr ')'
|
||||||
{
|
{
|
||||||
|
@ -625,45 +612,20 @@ opt_step
|
||||||
;
|
;
|
||||||
|
|
||||||
element_list
|
element_list
|
||||||
: /* empty */
|
|
||||||
{
|
|
||||||
$$ = new_block_expr ();
|
|
||||||
}
|
|
||||||
| element_list1 opt_comma
|
|
||||||
{
|
|
||||||
$$ = current_init;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
element_list1
|
|
||||||
: element
|
: 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
|
element
|
||||||
: '{'
|
: '{' element_list opt_comma '}' { $$ = $2; }
|
||||||
{
|
| fexpr { $$ = $1; }
|
||||||
$<expr>$ = current_init;
|
|
||||||
current_init = new_block_expr ();
|
|
||||||
}
|
|
||||||
element_list
|
|
||||||
{
|
|
||||||
current_init = $<expr>2;
|
|
||||||
}
|
|
||||||
'}'
|
|
||||||
{
|
|
||||||
$$ = $3;
|
|
||||||
}
|
|
||||||
| fexpr
|
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_comma
|
opt_comma
|
||||||
|
|
Loading…
Reference in a new issue