Declaration of type-restricted varargs

This commit is contained in:
Wolfgang Bumiller 2013-01-12 11:03:17 +01:00
parent 2f9db8972e
commit ca947d782c
3 changed files with 20 additions and 6 deletions

1
ast.c
View file

@ -75,6 +75,7 @@ static void ast_expression_init(ast_expression *self,
self->expression.params = NULL;
self->expression.count = 0;
self->expression.flags = 0;
self->expression.varparam = NULL;
}
static void ast_expression_delete(ast_expression *self)

5
ast.h
View file

@ -132,6 +132,10 @@ typedef struct
size_t count;
ast_value* *params;
uint32_t flags;
/* void foo(string...) gets varparam set as a restriction
* for variadic parameters
*/
ast_expression *varparam;
/* The codegen functions should store their output values
* so we can call it multiple times without re-evaluating.
* Store lvalue and rvalue seperately though. So that
@ -146,6 +150,7 @@ typedef struct
#define AST_FLAG_INITIALIZED (1<<3)
#define AST_FLAG_DEPRECATED (1<<4)
#define AST_FLAG_INCLUDE_DEF (1<<5)
#define AST_FLAG_VARARG_COUNT (1<<6)
#define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN)
/* Value

View file

@ -4291,6 +4291,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
ast_value *fval;
bool first = true;
bool variadic = false;
ast_value *varparam = NULL;
ctx = parser_ctx(parser);
@ -4320,11 +4321,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
if (parser->tok == TOKEN_DOTS) {
/* '...' indicates a varargs function */
variadic = true;
if (!parser_next(parser)) {
parseerror(parser, "expected parameter");
return NULL;
}
if (parser->tok != ')') {
if (!parser_next(parser) || parser->tok != ')') {
parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
goto on_error;
}
@ -4342,6 +4339,16 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
parseerror(parser, "type not supported as part of a parameter list: %s", tname);
goto on_error;
}
/* type-restricted varargs */
if (parser->tok == TOKEN_DOTS) {
variadic = true;
varparam = vec_last(params);
vec_pop(params);
if (!parser_next(parser) || parser->tok != ')') {
parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
goto on_error;
}
}
}
}
@ -4365,7 +4372,8 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
fval->expression.flags |= AST_FLAG_VARIADIC;
var = fval;
var->expression.params = params;
var->expression.params = params;
var->expression.varparam = (ast_expression*)varparam;
params = NULL;
return var;