X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=798f2dd9e606d9b73a56628b787b02e0ac6d6d3f;hb=0e3bc87c757c31e4b77010d8f64642aa8656dbf1;hp=1ee5cadf2cb030d47fb50ef8808c10ad34c57c0d;hpb=d4587e5667ac0f8f30fd0a6bde4ec0dd4bc96a54;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index 1ee5cad..798f2dd 100644 --- a/parser.c +++ b/parser.c @@ -517,12 +517,12 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy) case opid1(','): if (blocks[0]) { - if (!ast_block_add_expr(blocks[0], exprs[1])) + if (!ast_block_exprs_add(blocks[0], exprs[1])) return false; } else { blocks[0] = ast_block_new(ctx); - if (!ast_block_add_expr(blocks[0], exprs[0]) || - !ast_block_add_expr(blocks[0], exprs[1])) + if (!ast_block_exprs_add(blocks[0], exprs[0]) || + !ast_block_exprs_add(blocks[0], exprs[1])) { return false; } @@ -900,7 +900,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) if (!params) { /* 1 param */ paramcount = 1; - if (!ast_call_add_param(call, sy->out[sy->out_count].out)) { + if (!ast_call_params_add(call, sy->out[sy->out_count].out)) { ast_delete(sy->out[sy->out_count].out); parseerror(parser, "out of memory"); return false; @@ -1698,7 +1698,7 @@ static ast_block* parser_parse_block(parser_t *parser) } if (!expr) continue; - if (!ast_block_add_expr(block, expr)) { + if (!ast_block_exprs_add(block, expr)) { ast_delete(expr); ast_block_delete(block); block = NULL; @@ -1740,10 +1740,14 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) varentry_t varent; ast_expression *olddecl; + bool hadproto; + int basetype = parser_token(parser)->constval.t; while (true) { + hadproto = false; + if (!parser_next(parser)) { /* skip basetype or comma */ parseerror(parser, "expected variable declaration"); return false; @@ -1842,8 +1846,9 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) } ast_function_delete(func); ast_value_delete(fval); - var = proto; - func = var->constval.vfunc; + fval = proto; + func = proto->constval.vfunc; + hadproto = true; } else { @@ -1857,54 +1862,68 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) var = fval; } - varent.name = util_strdup(var->name); - varent.var = (ast_expression*)var; - if (var->expression.vtype == TYPE_VECTOR) - { - size_t len = strlen(varent.name); - varentry_t vx, vy, vz; - vx.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 0); - vy.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 1); - vz.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 2); - vx.name = (char*)mem_a(len+3); - vy.name = (char*)mem_a(len+3); - vz.name = (char*)mem_a(len+3); - memcpy(vx.name, varent.name, len); - memcpy(vy.name, varent.name, len); - memcpy(vz.name, varent.name, len); - vx.name[len] = vy.name[len] = vz.name[len] = '_'; - vx.name[len+1] = 'x'; - vy.name[len+1] = 'y'; - vz.name[len+1] = 'z'; - vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0; - - if (!localblock) { - (void)!parser_t_globals_add(parser, varent); - (void)!parser_t_globals_add(parser, vx); - (void)!parser_t_globals_add(parser, vy); - (void)!parser_t_globals_add(parser, vz); - } else { - (void)!parser_t_locals_add(parser, varent); - (void)!parser_t_locals_add(parser, vx); - (void)!parser_t_locals_add(parser, vy); - (void)!parser_t_locals_add(parser, vz); + if (!hadproto) { + varent.name = util_strdup(var->name); + varent.var = (ast_expression*)var; + if (var->expression.vtype == TYPE_VECTOR) + { + size_t len = strlen(varent.name); + varentry_t vx, vy, vz; + vx.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 0); + vy.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 1); + vz.var = (ast_expression*)ast_member_new(var->expression.node.context, (ast_expression*)var, 2); + vx.name = (char*)mem_a(len+3); + vy.name = (char*)mem_a(len+3); + vz.name = (char*)mem_a(len+3); + memcpy(vx.name, varent.name, len); + memcpy(vy.name, varent.name, len); + memcpy(vz.name, varent.name, len); + vx.name[len] = vy.name[len] = vz.name[len] = '_'; + vx.name[len+1] = 'x'; + vy.name[len+1] = 'y'; + vz.name[len+1] = 'z'; + vx.name[len+2] = vy.name[len+2] = vz.name[len+2] = 0; + + if (!localblock) { + (void)!parser_t_globals_add(parser, varent); + (void)!parser_t_globals_add(parser, vx); + (void)!parser_t_globals_add(parser, vy); + (void)!parser_t_globals_add(parser, vz); + } else { + (void)!parser_t_locals_add(parser, varent); + (void)!parser_t_locals_add(parser, vx); + (void)!parser_t_locals_add(parser, vy); + (void)!parser_t_locals_add(parser, vz); + if (!ast_block_locals_add(localblock, var) || + !ast_block_collect(localblock, vx.var) || + !ast_block_collect(localblock, vy.var) || + !ast_block_collect(localblock, vz.var)) + { + parser_pop_local(parser); + parser_pop_local(parser); + parser_pop_local(parser); + parser_pop_local(parser); + ast_value_delete(var); + return false; + } + } } - } - else - { - if ( (!localblock && !parser_t_globals_add(parser, varent)) || - ( localblock && !parser_t_locals_add(parser, varent)) ) + else { - ast_value_delete(var); - return false; + if ( (!localblock && !parser_t_globals_add(parser, varent)) || + ( localblock && !parser_t_locals_add(parser, varent)) ) + { + ast_value_delete(var); + return false; + } + if (localblock && !ast_block_locals_add(localblock, var)) + { + parser_pop_local(parser); + ast_value_delete(var); + return false; + } } } - if (localblock && !ast_block_locals_add(localblock, var)) - { - parser_pop_local(parser); - ast_value_delete(var); - return false; - } if (!parser_next(parser)) { ast_value_delete(var); @@ -2030,6 +2049,7 @@ static bool parser_do(parser_t *parser) else if (parser->tok == '.') { ast_value *var; + ast_value *typevar; ast_value *fld; ast_expression *oldex; bool isfunc = false; @@ -2053,11 +2073,12 @@ static bool parser_do(parser_t *parser) } /* parse the field type fully */ - var = parser_parse_type(parser, basetype, &isfunc); + typevar = var = parser_parse_type(parser, basetype, &isfunc); if (!var) return false; while (true) { + var = ast_value_copy(typevar); /* now the field name */ if (parser->tok != TOKEN_IDENT) { parseerror(parser, "expected field name"); @@ -2167,6 +2188,7 @@ nextfield: return false; } } + ast_delete(typevar); /* skip the semicolon */ if (!parser_next(parser)) @@ -2222,13 +2244,14 @@ bool parser_compile(const char *filename) else if (!parser->errors) parseerror(parser, "parse error\n"); lex_close(parser->lex); - mem_d(parser); + parser->lex = NULL; return false; } } } lex_close(parser->lex); + parser->lex = NULL; return !parser->errors; }