return lex_next (lexer, n)->string;
}
+int
+lex_ofs (const struct lexer *lexer)
+{
+ struct lex_source *src = lex_source__ (lexer);
+ return src ? src->parse_ofs : 0;
+}
+
+const struct token *
+lex_ofs_token (const struct lexer *lexer_, int ofs)
+{
+ struct lexer *lexer = CONST_CAST (struct lexer *, lexer_);
+ struct lex_source *src = lex_source__ (lexer);
+
+ if (src != NULL)
+ return &lex_source_next__ (src, ofs - src->parse_ofs)->token;
+ else
+ {
+ static const struct token stop_token = { .type = T_STOP };
+ return &stop_token;
+ }
+}
+
+struct msg_location *
+lex_ofs_location (const struct lexer *lexer, int ofs0, int ofs1)
+{
+ int ofs = lex_ofs (lexer);
+ return lex_get_location (lexer, ofs0 - ofs, ofs1 - ofs);
+}
+
/* Returns the text of the syntax in tokens N0 ahead of the current one,
through N1 ahead of the current one, inclusive. (For example, if N0 and N1
are both zero, this requests the syntax for the current token.) The caller
}
void
-lex_extend_location (const struct lexer *lexer, int n, struct msg_location *loc)
+lex_extend_location (const struct lexer *lexer, int n, struct msg_location **loc)
{
struct msg_location *new = lex_get_location (lexer, n, n);
msg_location_merge (loc, new);
double lex_next_tokval (const struct lexer *, int n);
struct substring lex_next_tokss (const struct lexer *, int n);
+int lex_ofs (const struct lexer *);
+const struct token *lex_ofs_token (const struct lexer *, int ofs);
+struct msg_location *lex_ofs_location (const struct lexer *, int ofs0, int ofs1);
+
/* Token representation. */
char *lex_next_representation (const struct lexer *, int n0, int n1);
bool lex_next_is_from_macro (const struct lexer *, int n);
struct matrix_lvalue *lvalue = xzalloc (sizeof *lvalue);
if (!lex_force_id (s->lexer))
goto error;
+ int start_ofs = lex_ofs (s->lexer);
lvalue->var_location = lex_get_location (s->lexer, 0, 0);
lvalue->var = matrix_var_lookup (s, lex_tokss (s->lexer));
if (lex_next_token (s->lexer, 1) == T_LPAREN)
if (!lvalue->var)
{
msg (SE, _("Undefined variable %s."), lex_tokcstr (s->lexer));
- free (lvalue);
- return NULL;
+ goto error;
}
lex_get_n (s->lexer, 2);
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);
+ lvalue->index_location = lex_ofs_location (s->lexer, start_ofs,
+ lex_ofs (s->lexer) - 1);
}
else
{
}
else if (dm->size1 == 0 || dm->size2 == 0)
{
- msg_at (SE, lvalue->var_location,
+ msg_at (SE, lvalue->index_location,
_("Cannot index %zu×%zu matrix."), dm->size1, dm->size2);
return false;
}
{
if (!is_vector (dm))
{
- msg_at (SE, lvalue->var_location,
+ msg_at (SE, lvalue->index_location,
_("Can't use vector indexing on %zu×%zu matrix %s."),
dm->size1, dm->size2, lvalue->var->name);
return false;
void
msg_location_merge (struct msg_location **dstp, const struct msg_location *src)
{
+ struct msg_location *dst = *dstp;
+ if (!dst)
+ {
+ *dstp = msg_location_dup (src);
+ return;
+ }
+
if (dst->file_name != src->file_name)
{
/* Failure. */
return;
}
-
if (msg_point_compare_3way (&dst->p[0], &src->p[0]) > 0)
dst->p[0] = src->p[0];
if (msg_point_compare_3way (&dst->p[1], &src->p[1]) < 0)
void msg_location_destroy (struct msg_location *);
struct msg_location *msg_location_dup (const struct msg_location *);
-void msg_location_merge (struct msg_location *, const struct msg_location *);
+void msg_location_merge (struct msg_location **, const struct msg_location *);
bool msg_location_is_empty (const struct msg_location *);
void msg_location_format (const struct msg_location *, struct string *);