From 788282bbfb50e268dd28d13a181c7285f1dd5a41 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 30 Nov 2021 06:50:13 -0800 Subject: [PATCH] working --- src/language/lexer/lexer.c | 31 ++++++++++++++++++++++++++++++- src/language/lexer/lexer.h | 4 ++++ src/language/stats/matrix.c | 12 ++++++------ src/libpspp/message.c | 8 +++++++- src/libpspp/message.h | 2 +- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index cf40dcbe6d..3c46fa70eb 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -1101,6 +1101,35 @@ lex_next_tokss (const struct lexer *lexer, int n) 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 @@ -1376,7 +1405,7 @@ lex_get_lines (const struct lexer *lexer, int n0, int n1) } 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); diff --git a/src/language/lexer/lexer.h b/src/language/lexer/lexer.h index 23dd305179..11a0c60d32 100644 --- a/src/language/lexer/lexer.h +++ b/src/language/lexer/lexer.h @@ -148,6 +148,10 @@ const char *lex_next_tokcstr (const struct lexer *, int n); 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); diff --git a/src/language/stats/matrix.c b/src/language/stats/matrix.c index bcefb94a9c..3e38d5f5bc 100644 --- a/src/language/stats/matrix.c +++ b/src/language/stats/matrix.c @@ -4463,6 +4463,7 @@ matrix_lvalue_parse (struct matrix_state *s) 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) @@ -4470,8 +4471,7 @@ matrix_lvalue_parse (struct matrix_state *s) if (!lvalue->var) { msg (SE, _("Undefined variable %s."), lex_tokcstr (s->lexer)); - free (lvalue); - return NULL; + goto error; } lex_get_n (s->lexer, 2); @@ -4489,8 +4489,8 @@ matrix_lvalue_parse (struct matrix_state *s) 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 { @@ -4633,7 +4633,7 @@ matrix_lvalue_evaluate (struct matrix_lvalue *lvalue, } 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; } @@ -4641,7 +4641,7 @@ matrix_lvalue_evaluate (struct matrix_lvalue *lvalue, { 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; diff --git a/src/libpspp/message.c b/src/libpspp/message.c index 526e19f3a0..9ead3efb3f 100644 --- a/src/libpspp/message.c +++ b/src/libpspp/message.c @@ -151,12 +151,18 @@ msg_point_compare_3way (const struct msg_point *a, const struct msg_point *b) 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) diff --git a/src/libpspp/message.h b/src/libpspp/message.h index d54598b696..508604e60f 100644 --- a/src/libpspp/message.h +++ b/src/libpspp/message.h @@ -94,7 +94,7 @@ void msg_location_uninit (struct msg_location *); 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 *); -- 2.30.2