-
- if (has_frame_think) {
- lex_ctx ctx;
- ast_expression *self_frame;
- ast_expression *self_nextthink;
- ast_expression *self_think;
- ast_expression *time_plus_1;
- ast_store *store_frame;
- ast_store *store_nextthink;
- ast_store *store_think;
-
- ctx = parser_ctx(parser);
- self_frame = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_frame);
- self_nextthink = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_nextthink);
- self_think = (ast_expression*)ast_entfield_new(ctx, gbl_self, fld_think);
-
- time_plus_1 = (ast_expression*)ast_binary_new(ctx, INSTR_ADD_F,
- gbl_time, (ast_expression*)parser_const_float(parser, 0.1));
-
- store_frame = ast_store_new(ctx, INSTR_STOREP_F, self_frame, framenum);
- store_nextthink = ast_store_new(ctx, INSTR_STOREP_F, self_nextthink, time_plus_1);
- store_think = ast_store_new(ctx, INSTR_STOREP_FNC, self_think, nextthink);
-
- if (!ast_block_exprs_add(block, (ast_expression*)store_frame) ||
- !ast_block_exprs_add(block, (ast_expression*)store_nextthink) ||
- !ast_block_exprs_add(block, (ast_expression*)store_think) )
- {
- parseerror(parser, "failed to generate code for [frame,think]");
- ast_block_delete(block);
- ast_value_delete(typevar);
- return false;
- }
- }
-
- for (parami = 0; parami < var->expression.params_count; ++parami) {
- ast_value *param = var->expression.params[parami];
- varentry_t vx, vy, vz;
-
- if (param->expression.vtype != TYPE_VECTOR &&
- (param->expression.vtype != TYPE_FIELD ||
- param->expression.next->expression.vtype != TYPE_VECTOR))
- {
- continue;
- }
-
- if (!create_vector_members(parser, param, &vx, &vy, &vz)) {
- ast_block_delete(block);
- ast_value_delete(typevar);
- return false;
- }
-
- (void)!parser_t_locals_add(parser, vx);
- (void)!parser_t_locals_add(parser, vy);
- (void)!parser_t_locals_add(parser, vz);
- if (!ast_block_collect(block, vx.var) ||
- !ast_block_collect(block, vy.var) ||
- !ast_block_collect(block, vz.var) )
- {
- parser_pop_local(parser);
- parser_pop_local(parser);
- parser_pop_local(parser);
- ast_block_delete(block);
- ast_value_delete(typevar);
- return false;
- }
- }
-
- func = ast_function_new(ast_ctx(var), var->name, var);
- if (!func) {
- parseerror(parser, "failed to allocate function for `%s`", var->name);
- ast_block_delete(block);
- parser->function = old;
- ast_value_delete(typevar);
- return false;
- }
- if (!parser_t_functions_add(parser, func)) {
- parseerror(parser, "failed to allocate slot for function `%s`", var->name);
- ast_function_delete(func);
- var->constval.vfunc = NULL;
- ast_value_delete(typevar);
- ast_block_delete(block);
- parser->function = old;
- return false;
- }
-
- parser->function = func;
- if (!parser_parse_block_into(parser, block, true)) {
- ast_block_delete(block);
- parser->function = old;
- ast_value_delete(typevar);
- return false;
- }
- parser->function = old;
-
- if (!block) {
- ast_value_delete(typevar);
- return false;
- }
-
- if (!ast_function_blocks_add(func, block)) {
- ast_block_delete(block);
- ast_value_delete(typevar);
- return false;
- }
-
- if (parser->tok == ';')
- return parser_next(parser) || parser->tok == TOKEN_EOF;
- else if (opts_standard == COMPILER_QCC)
- parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
- ast_value_delete(typevar);