MEM_VEC_FUNCTIONS(ast_expression_common, ast_value*, params)
-static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex);
ast_value* ast_value_copy(const ast_value *self)
{
size_t i;
return cp;
}
-#define ast_type_adopt(a, b) ast_type_adopt_impl((ast_expression*)(a), (ast_expression*)(b))
-static bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
+bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
{
size_t i;
const ast_expression_common *fromex;
return self;
}
-static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
+ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
{
size_t i;
const ast_expression_common *fromex;
bool GMQCC_WARN ast_value_params_add(ast_value*, ast_value*);
bool ast_compare_type(ast_expression *a, ast_expression *b);
+ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex);
+#define ast_type_adopt(a, b) ast_type_adopt_impl((ast_expression*)(a), (ast_expression*)(b))
+bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other);
/* Binary
*
* self.nextthink = time + 0.1;
* self.think = nextthink;
*/
+ nextthink = NULL;
+
fld_think = parser_find_field(parser, "think");
fld_nextthink = parser_find_field(parser, "nextthink");
fld_frame = parser_find_field(parser, "frame");
return false;
}
- nextthink = parser_expression_leave(parser, true);
- if (!nextthink) {
- ast_unref(framenum);
- parseerror(parser, "expected a think-function in [frame,think] notation");
- return false;
+ if (parser->tok == TOKEN_IDENT && !parser_find_var(parser, parser_tokval(parser)))
+ {
+ /* qc allows the use of not-yet-declared functions here
+ * - this automatically creates a prototype */
+ varentry_t varent;
+ ast_value *thinkfunc;
+ ast_expression *functype = fld_think->expression.next;
+
+ thinkfunc = ast_value_new(parser_ctx(parser), parser_tokval(parser), functype->expression.vtype);
+ if (!thinkfunc || !ast_type_adopt(nextthink, functype)) {
+ ast_unref(framenum);
+ parseerror(parser, "failed to create implicit prototype for `%s`", parser_tokval(parser));
+ return false;
+ }
+
+ if (!parser_next(parser)) {
+ ast_unref(framenum);
+ return false;
+ }
+
+ varent.var = (ast_expression*)thinkfunc;
+ varent.name = util_strdup(thinkfunc->name);
+ if (nextthink->expression.vtype == TYPE_FUNCTION)
+ {
+ ast_function *func;
+
+ func = ast_function_new(parser_ctx(parser), thinkfunc->name, thinkfunc);
+ if (!func) {
+ ast_delete(nextthink);
+ ast_unref(framenum);
+ parseerror(parser, "failed to create function for implicit prototype for `%s`",
+ thinkfunc->name);
+ return false;
+ }
+ (void)!parser_t_functions_add(parser, func);
+ (void)!parser_t_globals_add(parser, varent);
+ }
+ else
+ (void)!parser_t_globals_add(parser, varent);
+ nextthink = (ast_expression*)thinkfunc;
+
+ } else {
+ nextthink = parser_expression_leave(parser, true);
+ if (!nextthink) {
+ ast_unref(framenum);
+ parseerror(parser, "expected a think-function in [frame,think] notation");
+ return false;
+ }
}
if (!ast_istype(nextthink, ast_value) || !( (ast_value*)nextthink )->isconst) {