mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-21 18:30:52 +00:00
Automatic prototyping of frame-functions
This commit is contained in:
parent
9aa86bee16
commit
bd64d7d7b4
4 changed files with 56 additions and 10 deletions
6
ast.c
6
ast.c
|
@ -91,7 +91,6 @@ static void ast_expression_delete_full(ast_expression *self)
|
|||
|
||||
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;
|
||||
|
@ -117,8 +116,7 @@ ast_value* ast_value_copy(const ast_value *self)
|
|||
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;
|
||||
|
@ -149,7 +147,7 @@ static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
|
|||
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;
|
||||
|
|
3
ast.h
3
ast.h
|
@ -162,6 +162,9 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir);
|
|||
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
|
||||
*
|
||||
|
|
|
@ -16,7 +16,7 @@ $frame stand1 stand2 standX
|
|||
entity self;
|
||||
float time;
|
||||
|
||||
void() stand2;
|
||||
// void() stand2; this is auto-prototyped
|
||||
void() stand1 = [ 0, stand2 ] {
|
||||
// expands to:
|
||||
//self.frame = 0;
|
||||
|
|
55
parser.c
55
parser.c
|
@ -2151,6 +2151,8 @@ nextvar:
|
|||
* 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");
|
||||
|
@ -2193,11 +2195,54 @@ nextvar:
|
|||
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) {
|
||||
|
|
Loading…
Reference in a new issue