mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-30 15:41:12 +00:00
let ast_node have a use-counter, helpful for the parser to delete unused fields which otherwise get lost in the void
This commit is contained in:
parent
a67110410b
commit
25ffd11aa6
3 changed files with 65 additions and 5 deletions
51
ast.c
51
ast.c
|
@ -57,6 +57,7 @@ static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype)
|
||||||
self->node.context = ctx;
|
self->node.context = ctx;
|
||||||
self->node.destroy = &_ast_node_destroy;
|
self->node.destroy = &_ast_node_destroy;
|
||||||
self->node.keep = false;
|
self->node.keep = false;
|
||||||
|
self->node.uses = 0;
|
||||||
self->node.nodetype = nodetype;
|
self->node.nodetype = nodetype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +256,9 @@ ast_binary* ast_binary_new(lex_ctx ctx, int op,
|
||||||
else
|
else
|
||||||
self->expression.vtype = left->expression.vtype;
|
self->expression.vtype = left->expression.vtype;
|
||||||
|
|
||||||
|
ast_use(left);
|
||||||
|
ast_use(right);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +292,10 @@ ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
|
||||||
else
|
else
|
||||||
self->expression.next = NULL;
|
self->expression.next = NULL;
|
||||||
|
|
||||||
|
ast_use(left);
|
||||||
|
ast_use(right);
|
||||||
|
ast_use(left);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +316,8 @@ ast_unary* ast_unary_new(lex_ctx ctx, int op,
|
||||||
self->op = op;
|
self->op = op;
|
||||||
self->operand = expr;
|
self->operand = expr;
|
||||||
|
|
||||||
|
ast_use(expr);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,6 +335,8 @@ ast_return* ast_return_new(lex_ctx ctx, ast_expression *expr)
|
||||||
|
|
||||||
self->operand = expr;
|
self->operand = expr;
|
||||||
|
|
||||||
|
ast_use(expr);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +373,9 @@ ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expressi
|
||||||
self->entity = entity;
|
self->entity = entity;
|
||||||
self->field = field;
|
self->field = field;
|
||||||
|
|
||||||
|
ast_use(entity);
|
||||||
|
ast_use(field);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +415,8 @@ ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int fiel
|
||||||
self->owner = owner;
|
self->owner = owner;
|
||||||
self->field = field;
|
self->field = field;
|
||||||
|
|
||||||
|
ast_use(owner);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +441,10 @@ ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *on
|
||||||
self->on_true = ontrue;
|
self->on_true = ontrue;
|
||||||
self->on_false = onfalse;
|
self->on_false = onfalse;
|
||||||
|
|
||||||
|
ast_use(cond);
|
||||||
|
if (ontrue) ast_use(ontrue);
|
||||||
|
if (onfalse) ast_use(onfalse);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,6 +474,10 @@ ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *
|
||||||
self->on_false = onfalse;
|
self->on_false = onfalse;
|
||||||
self->phi_out = NULL;
|
self->phi_out = NULL;
|
||||||
|
|
||||||
|
ast_use(cond);
|
||||||
|
ast_use(ontrue);
|
||||||
|
ast_use(onfalse);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +506,12 @@ ast_loop* ast_loop_new(lex_ctx ctx,
|
||||||
self->increment = increment;
|
self->increment = increment;
|
||||||
self->body = body;
|
self->body = body;
|
||||||
|
|
||||||
|
if (initexpr) ast_use(initexpr);
|
||||||
|
if (precond) ast_use(precond);
|
||||||
|
if (postcond) ast_use(postcond);
|
||||||
|
if (increment) ast_use(increment);
|
||||||
|
if (body) ast_use(body);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,11 +540,20 @@ ast_call* ast_call_new(lex_ctx ctx,
|
||||||
MEM_VECTOR_INIT(self, params);
|
MEM_VECTOR_INIT(self, params);
|
||||||
|
|
||||||
self->func = funcexpr;
|
self->func = funcexpr;
|
||||||
|
ast_use(funcexpr);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
MEM_VEC_FUNCTIONS(ast_call, ast_expression*, params)
|
MEM_VEC_FUNCTIONS(ast_call, ast_expression*, params)
|
||||||
|
|
||||||
|
bool ast_call_add_param(ast_call *self, ast_expression *expr)
|
||||||
|
{
|
||||||
|
if (!ast_call_params_add(self, expr))
|
||||||
|
return false;
|
||||||
|
ast_use(expr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ast_call_delete(ast_call *self)
|
void ast_call_delete(ast_call *self)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -538,6 +578,9 @@ ast_store* ast_store_new(lex_ctx ctx, int op,
|
||||||
self->dest = dest;
|
self->dest = dest;
|
||||||
self->source = source;
|
self->source = source;
|
||||||
|
|
||||||
|
ast_use(dest);
|
||||||
|
ast_use(source);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +606,14 @@ ast_block* ast_block_new(lex_ctx ctx)
|
||||||
MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
|
MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
|
||||||
MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
|
MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
|
||||||
|
|
||||||
|
bool ast_block_add_expr(ast_block *self, ast_expression *expr)
|
||||||
|
{
|
||||||
|
if (!ast_block_exprs_add(self, expr))
|
||||||
|
return false;
|
||||||
|
ast_use(expr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ast_block_delete(ast_block *self)
|
void ast_block_delete(ast_block *self)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
9
ast.h
9
ast.h
|
@ -81,8 +81,13 @@ typedef struct
|
||||||
* prevents its dtor from destroying this node as well.
|
* prevents its dtor from destroying this node as well.
|
||||||
*/
|
*/
|
||||||
bool keep;
|
bool keep;
|
||||||
|
/* usecount - so we can delete unused _x,_y and _z nodes... */
|
||||||
|
size_t uses;
|
||||||
} ast_node_common;
|
} ast_node_common;
|
||||||
|
|
||||||
|
#define ast_use(n) ((ast_node*)(n))->node.uses++
|
||||||
|
#define ast_unuse(n) ((ast_node*)(n))->node.uses--
|
||||||
|
|
||||||
#define ast_delete(x) ( ( (ast_node*)(x) ) -> node.destroy )((ast_node*)(x))
|
#define ast_delete(x) ( ( (ast_node*)(x) ) -> node.destroy )((ast_node*)(x))
|
||||||
#define ast_unref(x) do \
|
#define ast_unref(x) do \
|
||||||
{ \
|
{ \
|
||||||
|
@ -418,6 +423,8 @@ bool ast_call_codegen(ast_call*, ast_function*, bool lvalue, ir_value**);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO(ast_call, ast_expression*, params);
|
MEM_VECTOR_PROTO(ast_call, ast_expression*, params);
|
||||||
|
|
||||||
|
bool ast_call_add_param(ast_call*, ast_expression*);
|
||||||
|
|
||||||
/* Blocks
|
/* Blocks
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -435,6 +442,8 @@ bool ast_block_set_type(ast_block*, ast_expression *from);
|
||||||
MEM_VECTOR_PROTO(ast_block, ast_value*, locals);
|
MEM_VECTOR_PROTO(ast_block, ast_value*, locals);
|
||||||
MEM_VECTOR_PROTO(ast_block, ast_expression*, exprs);
|
MEM_VECTOR_PROTO(ast_block, ast_expression*, exprs);
|
||||||
|
|
||||||
|
bool ast_block_add_expr(ast_block*, ast_expression *expr);
|
||||||
|
|
||||||
bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**);
|
bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**);
|
||||||
|
|
||||||
/* Function
|
/* Function
|
||||||
|
|
10
parser.c
10
parser.c
|
@ -517,12 +517,12 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
|
||||||
|
|
||||||
case opid1(','):
|
case opid1(','):
|
||||||
if (blocks[0]) {
|
if (blocks[0]) {
|
||||||
if (!ast_block_exprs_add(blocks[0], exprs[1]))
|
if (!ast_block_add_expr(blocks[0], exprs[1]))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
blocks[0] = ast_block_new(ctx);
|
blocks[0] = ast_block_new(ctx);
|
||||||
if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
|
if (!ast_block_add_expr(blocks[0], exprs[0]) ||
|
||||||
!ast_block_exprs_add(blocks[0], exprs[1]))
|
!ast_block_add_expr(blocks[0], exprs[1]))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -900,7 +900,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
|
||||||
if (!params) {
|
if (!params) {
|
||||||
/* 1 param */
|
/* 1 param */
|
||||||
paramcount = 1;
|
paramcount = 1;
|
||||||
if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
|
if (!ast_call_add_param(call, sy->out[sy->out_count].out)) {
|
||||||
ast_delete(sy->out[sy->out_count].out);
|
ast_delete(sy->out[sy->out_count].out);
|
||||||
parseerror(parser, "out of memory");
|
parseerror(parser, "out of memory");
|
||||||
return false;
|
return false;
|
||||||
|
@ -1698,7 +1698,7 @@ static ast_block* parser_parse_block(parser_t *parser)
|
||||||
}
|
}
|
||||||
if (!expr)
|
if (!expr)
|
||||||
continue;
|
continue;
|
||||||
if (!ast_block_exprs_add(block, expr)) {
|
if (!ast_block_add_expr(block, expr)) {
|
||||||
ast_delete(expr);
|
ast_delete(expr);
|
||||||
ast_block_delete(block);
|
ast_block_delete(block);
|
||||||
block = NULL;
|
block = NULL;
|
||||||
|
|
Loading…
Reference in a new issue