- "ai": Restrict a to integer values.
- - "a>0", "a<0", "a>=0", "a<=0".
+ - "a>0", "a<0", "a>=0", "a<=0", "a!=0".
- - "a<b", "a>b", "a<=b", "a>=b".
+ - "a<b", "a>b", "a<=b", "a>=b", "b!=0".
*/
#define MATRIX_FUNCTIONS \
F(ABS, "ABS", m_e, NULL) \
F(ARSIN, "ARSIN", m_e, "a[-1,1]") \
F(ARTAN, "ARTAN", m_e, NULL) \
F(BLOCK, "BLOCK", m_any, NULL) \
- F(CHOL, "CHOL", m_m, NULL) \
+ F(CHOL, "CHOL", m_me, NULL) \
F(CMIN, "CMIN", m_m, NULL) \
F(CMAX, "CMAX", m_m, NULL) \
F(COS, "COS", m_e, NULL) \
F(GINV, "GINV", m_m, NULL) \
F(GRADE, "GRADE", m_m, NULL) \
F(GSCH, "GSCH", m_m, NULL) \
- F(IDENT, "IDENT", IDENT, NULL) \
+ F(IDENT, "IDENT", IDENT, "ai>=0 bi>=0") \
F(INV, "INV", m_m, NULL) \
F(KRONEKER, "KRONEKER", m_mm, NULL) \
F(LG10, "LG10", m_e, "a>0") \
F(LN, "LN", m_e, "a>0") \
F(MAGIC, "MAGIC", m_d, "ai>=3") \
- F(MAKE, "MAKE", m_ddd, NULL) \
+ F(MAKE, "MAKE", m_ddd, "ai>=0 bi>=0") \
F(MDIAG, "MDIAG", m_v, NULL) \
F(MMAX, "MMAX", d_m, NULL) \
F(MMIN, "MMIN", d_m, NULL) \
- F(MOD, "MOD", m_md, NULL) \
+ F(MOD, "MOD", m_md, "b!=0") \
F(MSSQ, "MSSQ", d_m, NULL) \
F(MSUM, "MSUM", d_m, NULL) \
F(NCOL, "NCOL", d_m, NULL) \
enum { m_dd_MIN_ARGS = 2, m_dd_MAX_ARGS = 2 };
enum { m_ddd_MIN_ARGS = 3, m_ddd_MAX_ARGS = 3 };
enum { m_m_MIN_ARGS = 1, m_m_MAX_ARGS = 1 };
+enum { m_me_MIN_ARGS = 1, m_me_MAX_ARGS = 1 };
enum { m_e_MIN_ARGS = 1, m_e_MAX_ARGS = 1 };
enum { m_md_MIN_ARGS = 2, m_md_MAX_ARGS = 2 };
enum { m_ed_MIN_ARGS = 2, m_ed_MAX_ARGS = 2 };
typedef gsl_matrix *matrix_proto_m_dd (double, double);
typedef gsl_matrix *matrix_proto_m_ddd (double, double, double);
typedef gsl_matrix *matrix_proto_m_m (gsl_matrix *);
+typedef gsl_matrix *matrix_proto_m_me (gsl_matrix *, const struct matrix_expr *);
typedef double matrix_proto_m_e (double);
typedef gsl_matrix *matrix_proto_m_md (gsl_matrix *, double);
typedef double matrix_proto_m_ed (double, double);
.n_subs = n_subs
};
- for (size_t i = 0; i < n_subs; i++)
- msg_location_merge (&e->location, subs[i]->location);
return e;
}
}
static struct matrix_expr *
-matrix_expr_create_number (double number)
+matrix_expr_create_number (struct lexer *lexer, double number)
{
struct matrix_expr *e = xmalloc (sizeof *e);
- *e = (struct matrix_expr) { .op = MOP_NUMBER, .number = number };
+ *e = (struct matrix_expr) {
+ .op = MOP_NUMBER,
+ .number = number,
+ .location = lex_get_location (lexer, 0, 0),
+ };
+ lex_get (lexer);
return e;
}
matrix_parse_curly_semi (struct matrix_state *s)
{
if (lex_token (s->lexer) == T_RCURLY)
- return matrix_expr_create_0 (MOP_EMPTY);
+ {
+ struct matrix_expr *e = matrix_expr_create_0 (MOP_EMPTY);
+ e->location = lex_get_location (s->lexer, -1, 0);
+ return e;
+ }
struct matrix_expr *lhs = matrix_parse_curly_comma (s);
if (!lhs)
}
static gsl_matrix *
-matrix_eval_CHOL (gsl_matrix *m)
+matrix_eval_CHOL (gsl_matrix *m, const struct matrix_expr *e)
{
if (!gsl_linalg_cholesky_decomp1 (m))
{
}
else
{
- msg (SE, _("Input to CHOL function is not positive-definite."));
+ msg_at (SE, e->location,
+ _("Input to CHOL function is not positive-definite."));
return NULL;
}
}
static gsl_matrix *
matrix_eval_IDENT (double s1, double s2)
{
- if (s1 < 0 || s1 > SIZE_MAX || s2 < 0 || s2 > SIZE_MAX)
- {
- msg (SE, _("Arguments to IDENT must be non-negative integers."));
- return NULL;
- }
-
gsl_matrix *m = gsl_matrix_alloc (s1, s2);
MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
*d = x == y;
static gsl_matrix *
matrix_eval_MAKE (double r, double c, double value)
{
- if (r < 0 || r >= SIZE_MAX || c < 0 || c >= SIZE_MAX)
- {
- msg (SE, _("Size arguments to MAKE must be integers."));
- return NULL;
- }
-
gsl_matrix *m = gsl_matrix_alloc (r, c);
MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
*d = value;
static gsl_matrix *
matrix_eval_MOD (gsl_matrix *m, double divisor)
{
- if (divisor == 0.0)
- {
- msg (SE, _("Divisor argument to MOD function must be nonzero."));
- return NULL;
- }
-
MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
*d = fmod (*d, divisor);
return m;
}
if (!sub->location)
{
- lex_extend_location (s->lexer, 0, arg_location);
+ //lex_extend_location (s->lexer, 0, arg_location);
sub->location = arg_location;
}
else
if (lex_is_number (s->lexer))
{
double number = lex_number (s->lexer);
- lex_get (s->lexer);
- return matrix_expr_create_number (number);
+ return matrix_expr_create_number (s->lexer, number);
}
else if (lex_is_string (s->lexer))
{
char string[sizeof (double)];
buf_copy_str_rpad (string, sizeof string, lex_tokcstr (s->lexer), ' ');
- lex_get (s->lexer);
double number;
memcpy (&number, string, sizeof number);
- return matrix_expr_create_number (number);
+ return matrix_expr_create_number (s->lexer, number);
}
else if (lex_match (s->lexer, T_LPAREN))
{
return dm;
}
-#define F(ENUM, STRING, PROTO, CONSTRAINTS) \
- static gsl_matrix *matrix_expr_evaluate_##PROTO ( \
- const struct matrix_function_properties *, gsl_matrix *[], size_t, \
- matrix_proto_##PROTO *);
+#define F(ENUM, STRING, PROTO, CONSTRAINTS) \
+ static gsl_matrix *matrix_expr_evaluate_##PROTO ( \
+ const struct matrix_function_properties *, gsl_matrix *[], \
+ const struct matrix_expr *, matrix_proto_##PROTO *);
MATRIX_FUNCTIONS
#undef F
gsl_matrix_get (a, y, x));
}
+enum matrix_argument_relop
+ {
+ MRR_GT, /* > */
+ MRR_GE, /* >= */
+ MRR_LT, /* < */
+ MRR_LE, /* <= */
+ MRR_NE, /* <> */
+ };
+
static void
argument_inequality_error (const struct matrix_function_properties *props,
size_t a_index, gsl_matrix *a, size_t y, size_t x,
size_t b_index, double b,
- bool greater, bool equal)
+ enum matrix_argument_relop relop)
{
struct string s = DS_EMPTY_INITIALIZER;
argument_invalid (props, a_index, a, y, x, &s);
ds_put_cstr (&s, " ");
- if (greater && equal)
- ds_put_format (&s, _("This argument must be greater than or "
- "equal to argument %zu, but that has value %g."),
- b_index, b);
- else if (greater && !equal)
- ds_put_format (&s, _("This argument must be greater than argument %zu, "
- "but that has value %g."),
- b_index, b);
- else if (equal)
- ds_put_format (&s, _("This argument must be less than or "
- "equal to argument %zu, but that has value %g."),
- b_index, b);
- else
- ds_put_format (&s, _("This argument must be less than argument %zu, "
- "but that has value %g."),
- b_index, b);
+ switch (relop)
+ {
+ case MRR_GE:
+ ds_put_format (&s, _("This argument must be greater than or "
+ "equal to argument %zu, but that has value %g."),
+ b_index, b);
+ break;
+
+ case MRR_GT:
+ ds_put_format (&s, _("This argument must be greater than argument %zu, "
+ "but that has value %g."),
+ b_index, b);
+ break;
+
+ case MRR_LE:
+ ds_put_format (&s, _("This argument must be less than or "
+ "equal to argument %zu, but that has value %g."),
+ b_index, b);
+ break;
+
+ case MRR_LT:
+ ds_put_format (&s, _("This argument must be less than argument %zu, "
+ "but that has value %g."),
+ b_index, b);
+ break;
+
+ case MRR_NE:
+ ds_put_format (&s,
+ _("This argument must not be the same as argument %zu."),
+ b_index);
+ break;
+ }
+
msg (ME, ds_cstr (&s));
ds_destroy (&s);
}
argument_value_error (const struct matrix_function_properties *props,
size_t a_index, gsl_matrix *a, size_t y, size_t x,
double b,
- bool greater, bool equal)
+ enum matrix_argument_relop relop)
{
struct string s = DS_EMPTY_INITIALIZER;
argument_invalid (props, a_index, a, y, x, &s);
ds_put_cstr (&s, " ");
- if (greater && equal)
- ds_put_format (&s, _("This argument must be greater than or equal to %g."),
- b);
- else if (greater && !equal)
- ds_put_format (&s, _("This argument must be greater than %g."), b);
- else if (equal)
- ds_put_format (&s, _("This argument must be less than or equal to %g."), b);
- else
- ds_put_format (&s, _("This argument must be less than %g."), b);
+ switch (relop)
+ {
+ case MRR_GE:
+ ds_put_format (&s,
+ _("This argument must be greater than or equal to %g."),
+ b);
+ break;
+
+ case MRR_GT:
+ ds_put_format (&s, _("This argument must be greater than %g."), b);
+ break;
+
+ case MRR_LE:
+ ds_put_format (&s, _("This argument must be less than or equal to %g."),
+ b);
+ break;
+
+ case MRR_LT:
+ ds_put_format (&s, _("This argument must be less than %g."), b);
+ break;
+
+ case MRR_NE:
+ ds_put_format (&s, _("This argument may not be %g."), b);
+ break;
+ }
+
msg (ME, ds_cstr (&s));
ds_destroy (&s);
}
+static bool
+matrix_argument_relop_is_satisfied (double a, double b,
+ enum matrix_argument_relop relop)
+{
+ switch (relop)
+ {
+ case MRR_GE: return a >= b;
+ case MRR_GT: return a > b;
+ case MRR_LE: return a <= b;
+ case MRR_LT: return a < b;
+ case MRR_NE: return a != b;
+ }
+
+ NOT_REACHED ();
+}
+
+static enum matrix_argument_relop
+matrix_argument_relop_flip (enum matrix_argument_relop relop)
+{
+ switch (relop)
+ {
+ case MRR_GE: return MRR_LE;
+ case MRR_GT: return MRR_LT;
+ case MRR_LE: return MRR_GE;
+ case MRR_LT: return MRR_GT;
+ case MRR_NE: return MRR_NE;
+ }
+
+ NOT_REACHED ();
+}
+
static bool
check_constraints (const struct matrix_function_properties *props,
gsl_matrix *args[], size_t n_args)
return false;
}
}
- else if (*constraints == '>' || *constraints == '<')
+ else if (*constraints == '>'
+ || *constraints == '<'
+ || *constraints == '!')
{
- bool greater = *constraints++ == '>';
- bool equal;
- if (*constraints == '=')
+ enum matrix_argument_relop relop;
+ switch (*constraints++)
{
- equal = true;
+ case '>':
+ if (*constraints == '=')
+ {
+ constraints++;
+ relop = MRR_GE;
+ }
+ else
+ relop = MRR_GT;
+ break;
+
+ case '<':
+ if (*constraints == '=')
+ {
+ constraints++;
+ relop = MRR_LE;
+ }
+ else
+ relop = MRR_LT;
+ break;
+
+ case '!':
+ assert (*constraints == '=');
constraints++;
+ relop = MRR_NE;
}
- else
- equal = false;
if (*constraints >= 'a' && *constraints <= 'd')
{
size_t tmp_index = a_index;
a_index = b_index;
b_index = tmp_index;
-
- greater = !greater;
+ relop = matrix_argument_relop_flip (relop);
}
double b = to_scalar (args[b_index]);
MATRIX_FOR_ALL_ELEMENTS (a, y, x, args[a_index])
- if (greater
- ? (equal ? !(*a >= b) : !(*a > b))
- : (equal ? !(*a <= b) : !(*a < b)))
+ if (!matrix_argument_relop_is_satisfied (*a, b, relop))
{
argument_inequality_error (props,
a_index + 1, args[a_index], y, x,
b_index + 1, b,
- greater, equal);
+ relop);
return false;
}
}
int comparand = parse_constraint_value (&constraints);
MATRIX_FOR_ALL_ELEMENTS (d, y, x, args[arg_index])
- if (greater
- ? (equal ? !(*d >= comparand) : !(*d > comparand))
- : (equal ? !(*d <= comparand) : !(*d < comparand)))
+ if (!matrix_argument_relop_is_satisfied (*d, comparand, relop))
{
argument_value_error (props,
arg_index + 1, args[arg_index], y, x,
comparand,
- greater, equal);
+ relop);
return false;
}
}
static gsl_matrix *
matrix_expr_evaluate_d_none (
const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[] UNUSED, size_t n_subs,
+ gsl_matrix *subs[] UNUSED, const struct matrix_expr *e,
matrix_proto_d_none *f)
{
- assert (n_subs == 0);
+ assert (e->n_subs == 0);
gsl_matrix *m = gsl_matrix_alloc (1, 1);
gsl_matrix_set (m, 0, 0, f ());
static gsl_matrix *
matrix_expr_evaluate_d_d (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_d_d *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
double d;
- if (!to_scalar_args (props->name, subs, n_subs, &d))
+ if (!to_scalar_args (props->name, subs, e->n_subs, &d))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
gsl_matrix *m = gsl_matrix_alloc (1, 1);
static gsl_matrix *
matrix_expr_evaluate_d_dd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_d_dd *f)
{
- assert (n_subs == 2);
+ assert (e->n_subs == 2);
double d[2];
- if (!to_scalar_args (props->name, subs, n_subs, d))
+ if (!to_scalar_args (props->name, subs, e->n_subs, d))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
gsl_matrix *m = gsl_matrix_alloc (1, 1);
static gsl_matrix *
matrix_expr_evaluate_d_ddd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_d_ddd *f)
{
- assert (n_subs == 3);
+ assert (e->n_subs == 3);
double d[3];
- if (!to_scalar_args (props->name, subs, n_subs, d))
+ if (!to_scalar_args (props->name, subs, e->n_subs, d))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
gsl_matrix *m = gsl_matrix_alloc (1, 1);
static gsl_matrix *
matrix_expr_evaluate_m_d (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_d *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
double d;
- return to_scalar_args (props->name, subs, n_subs, &d) ? f (d) : NULL;
+ return to_scalar_args (props->name, subs, e->n_subs, &d) ? f (d) : NULL;
}
static gsl_matrix *
matrix_expr_evaluate_m_dd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_dd *f)
{
- assert (n_subs == 2);
+ assert (e->n_subs == 2);
double d[2];
- return to_scalar_args (props->name, subs, n_subs, d) ? f(d[0], d[1]) : NULL;
+ return to_scalar_args (props->name, subs, e->n_subs, d) ? f(d[0], d[1]) : NULL;
}
static gsl_matrix *
matrix_expr_evaluate_m_ddd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_ddd *f)
{
- assert (n_subs == 3);
+ assert (e->n_subs == 3);
double d[3];
- return to_scalar_args (props->name, subs, n_subs, d) ? f(d[0], d[1], d[2]) : NULL;
+ return to_scalar_args (props->name, subs, e->n_subs, d) ? f(d[0], d[1], d[2]) : NULL;
}
static gsl_matrix *
matrix_expr_evaluate_m_m (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_m *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
return f (subs[0]);
}
+static gsl_matrix *
+matrix_expr_evaluate_m_me (const struct matrix_function_properties *props UNUSED,
+ gsl_matrix *subs[], const struct matrix_expr *e,
+ matrix_proto_m_me *f)
+{
+ assert (e->n_subs == 1);
+ return f (subs[0], e);
+}
+
static gsl_matrix *
matrix_expr_evaluate_m_e (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
- matrix_proto_m_e *f)
+ gsl_matrix *subs[], const struct matrix_expr *e,
+ matrix_proto_m_e *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
MATRIX_FOR_ALL_ELEMENTS (a, y, x, subs[0])
static gsl_matrix *
matrix_expr_evaluate_m_md (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_md *f)
{
- assert (n_subs == 2);
+ assert (e->n_subs == 2);
if (!check_scalar_arg (props->name, subs, 1))
return NULL;
return f (subs[0], to_scalar (subs[1]));
static gsl_matrix *
matrix_expr_evaluate_m_ed (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_ed *f)
{
- assert (n_subs == 2);
+ assert (e->n_subs == 2);
if (!check_scalar_arg (props->name, subs, 1))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
double b = to_scalar (subs[1]);
static gsl_matrix *
matrix_expr_evaluate_m_mdd (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_mdd *f)
{
- assert (n_subs == 3);
+ assert (e->n_subs == 3);
if (!check_scalar_arg (props->name, subs, 1) || !check_scalar_arg (props->name, subs, 2))
return NULL;
return f (subs[0], to_scalar (subs[1]), to_scalar (subs[2]));
static gsl_matrix *
matrix_expr_evaluate_m_edd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_edd *f)
{
- assert (n_subs == 3);
+ assert (e->n_subs == 3);
if (!check_scalar_arg (props->name, subs, 1) || !check_scalar_arg (props->name, subs, 2))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
double b = to_scalar (subs[1]);
static gsl_matrix *
matrix_expr_evaluate_m_eddd (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_eddd *f)
{
- assert (n_subs == 4);
+ assert (e->n_subs == 4);
for (size_t i = 1; i < 4; i++)
if (!check_scalar_arg (props->name, subs, i))
return NULL;
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
double b = to_scalar (subs[1]);
static gsl_matrix *
matrix_expr_evaluate_m_eed (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_eed *f)
{
- assert (n_subs == 3);
+ assert (e->n_subs == 3);
if (!check_scalar_arg (props->name, subs, 2))
return NULL;
return NULL;
}
- if (!check_constraints (props, subs, n_subs))
+ if (!check_constraints (props, subs, e->n_subs))
return NULL;
double c = to_scalar (subs[2]);
static gsl_matrix *
matrix_expr_evaluate_m_mm (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_mm *f)
{
- assert (n_subs == 2);
+ assert (e->n_subs == 2);
return f (subs[0], subs[1]);
}
static gsl_matrix *
matrix_expr_evaluate_m_v (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_m_v *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
if (!check_vector_arg (props->name, subs, 0))
return NULL;
gsl_vector v = to_vector (subs[0]);
static gsl_matrix *
matrix_expr_evaluate_d_m (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_d_m *f)
{
- assert (n_subs == 1);
+ assert (e->n_subs == 1);
gsl_matrix *m = gsl_matrix_alloc (1, 1);
gsl_matrix_set (m, 0, 0, f (subs[0]));
static gsl_matrix *
matrix_expr_evaluate_m_any (const struct matrix_function_properties *props UNUSED,
- gsl_matrix *subs[], size_t n_subs,
- matrix_proto_m_any *f)
+ gsl_matrix *subs[], const struct matrix_expr *e,
+ matrix_proto_m_any *f)
{
- return f (subs, n_subs);
+ return f (subs, e->n_subs);
}
static gsl_matrix *
matrix_expr_evaluate_IDENT (const struct matrix_function_properties *props,
- gsl_matrix *subs[], size_t n_subs,
+ gsl_matrix *subs[], const struct matrix_expr *e,
matrix_proto_IDENT *f)
{
- assert (n_subs <= 2);
+ assert (e->n_subs <= 2);
double d[2];
- if (!to_scalar_args (props->name, subs, n_subs, d))
+ if (!to_scalar_args (props->name, subs, e->n_subs, d))
return NULL;
- return f (d[0], d[n_subs - 1]);
+ return f (d[0], d[e->n_subs - 1]);
}
static gsl_matrix *
.name = STRING, \
.constraints = CONSTRAINTS, \
}; \
- result = matrix_expr_evaluate_##PROTO (&props, subs, e->n_subs, \
+ result = matrix_expr_evaluate_##PROTO (&props, subs, e, \
matrix_eval_##ENUM); \
} \
break;
struct matrix_lvalue
{
struct matrix_var *var;
- struct msg_location *var_location;
struct matrix_expr *indexes[2];
size_t n_indexes;
+
+ struct msg_location *var_location; /* Variable name. */
+ struct msg_location *index_location; /* Variable name plus indexing. */
};
static void
{
if (lvalue)
{
+ msg_location_destroy (lvalue->var_location);
+ msg_location_destroy (lvalue->index_location);
for (size_t i = 0; i < lvalue->n_indexes; i++)
matrix_expr_destroy (lvalue->indexes[i]);
free (lvalue);
}
if (!lex_force_match (s->lexer, T_RPAREN))
goto error;
+
+ lvalue->index_location = msg_location_dup (lvalue->var_location);
+ lex_extend_location (s->lexer, -1, lvalue->index_location);
}
else
{
struct msg_location *location = xmalloc (sizeof *location);
*location = (struct msg_location) {
.file_name = intern_new (dfm_get_file_name (reader)),
- .first_line = line_number,
- .last_line = line_number + 1,
- .first_column = first_column,
- .last_column = last_column,
+ .p[0] = { .line = line_number, .column = first_column },
+ .p[1] = { .line = line_number, .column = last_column },
};
struct msg *m = xmalloc (sizeof *m);
*m = (struct msg) {
if (error)
{
int c1 = utf8_count_columns (line_start, p.string - line_start) + 1;
- int c2 = c1 + ss_utf8_count_columns (p) - 1;
+ int c2 = c1 + ss_utf8_count_columns (p);
parse_error (reader, read->format, p, y, x, c1, c2, error);
}
else