struct matrix_expr *e = xmalloc (sizeof *e);
*e = (struct matrix_expr) { .op = f->op, .subs = NULL };
- size_t allocated_subs = 0;
- do
+ if (lex_token (s->lexer) != T_RPAREN)
{
- struct matrix_expr *sub = matrix_parse_expr (s);
- if (!sub)
- goto error;
+ size_t allocated_subs = 0;
+ do
+ {
+ struct matrix_expr *sub = matrix_parse_expr (s);
+ if (!sub)
+ goto error;
- if (e->n_subs >= allocated_subs)
- e->subs = x2nrealloc (e->subs, &allocated_subs, sizeof *e->subs);
- e->subs[e->n_subs++] = sub;
+ if (e->n_subs >= allocated_subs)
+ e->subs = x2nrealloc (e->subs, &allocated_subs, sizeof *e->subs);
+ e->subs[e->n_subs++] = sub;
+ }
+ while (lex_match (s->lexer, T_COMMA));
}
- while (lex_match (s->lexer, T_COMMA));
if (!lex_force_match (s->lexer, T_RPAREN))
goto error;
+ if (e->n_subs < f->min_args || e->n_subs > f->max_args)
+ {
+ if (f->min_args == f->max_args)
+ msg (SE, ngettext ("Matrix function %s requires %zu argument.",
+ "Matrix function %s requires %zu arguments.",
+ f->min_args),
+ f->name, f->min_args);
+ else if (f->min_args == 1 && f->max_args == 2)
+ msg (SE, ngettext ("Matrix function %s requires 1 or 2 arguments, "
+ "but %zu was provided.",
+ "Matrix function %s requires 1 or 2 arguments, "
+ "but %zu were provided.",
+ e->n_subs),
+ f->name, e->n_subs);
+ else if (f->min_args == 1 && f->max_args == INT_MAX)
+ msg (SE, _("Matrix function %s requires at least one argument."),
+ f->name);
+ else
+ NOT_REACHED ();
+
+ goto error;
+ }
+
*exprp = e;
return true;