| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- #include <errno.h>
- #include "func.h"
- #include "node.h"
- #include "ply.h"
- #include "sym.h"
- #include "type.h"
- static int func_validate_expr(const struct func *func, struct node *n, int strict)
- {
- struct tfield *f;
- struct node *arg;
- int fargs, nargs = 0;
- for (f = func->type->func.args, arg = n->expr.args;
- f && f->type && arg; f++, arg = arg->next, nargs++) {
- if ((!strict && (f->type->ttype == T_VOID))
- || (!strict && !arg->sym->type)
- || (!strict && (arg->sym->type->ttype == T_VOID))
- || type_compatible(arg->sym->type, f->type))
- continue;
- _e("%#N: %O argument is of type '%T', expected '%T'.\n",
- n, nargs, arg->sym->type, f->type);
- }
- if ((!f || !f->type) && !arg)
- return 0;
- nargs = node_nargs(n);
- fargs = type_nargs(func->type);
- if (f && f->type) {
- _e("%#N: too few arguments to %N; expected%s %d, got %d.\n",
- n, n, func->type->func.vargs? " at least" : "", fargs, nargs);
- return -EINVAL;
- }
- if (func->type->func.vargs)
- return 0;
- _e("%#N: too many arguments to %N; expected %d, got %d.\n",
- n, n, fargs, nargs);
- return -EINVAL;
- }
- int func_static_validate(const struct func *func, struct node *n)
- {
- int err = 0;
- if (!func->type)
- goto check_callback;
- switch (n->ntype) {
- case N_EXPR:
- if (func->type->ttype != T_FUNC) {
- _e("%#N: %N is not callable.\n", n, n);
- return -EINVAL;
- }
- err = func_validate_expr(func, n, 0);
- break;
- case N_IDENT:
- if (func->type->ttype == T_FUNC) {
- _e("%#N: %N is a function.\n", n, n);
- return -EINVAL;
- }
- break;
- default:
- /* num, str. nothing to validate. */
- break;
- }
- check_callback:
- if (!err && func->static_validate)
- err = func->static_validate(func, n);
- return err;
- }
- struct type *func_return_type(const struct func *func)
- {
- if (!func->type)
- return NULL;
- if (func->type->ttype == T_FUNC)
- return func->type->func.type;
- return func->type;
- }
|