working
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 30 Nov 2021 14:50:13 +0000 (06:50 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 30 Nov 2021 14:55:06 +0000 (06:55 -0800)
src/language/lexer/lexer.c
src/language/lexer/lexer.h
src/language/stats/matrix.c
src/libpspp/message.c
src/libpspp/message.h

index cf40dcbe6d0ee76f53a16dbf110c8b34d201d5c1..3c46fa70ebb787689a81244559ec2477f874eec4 100644 (file)
@@ -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);
index 23dd305179be5b3fa41574a62d7946c137689612..11a0c60d32517ff827638fed671f405d72f436bc 100644 (file)
@@ -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);
index bcefb94a9c615df4161af52f0dcc2052b3e6db66..3e38d5f5bc4ffca58dd81e1b7ed48e1486838087 100644 (file)
@@ -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;
index 526e19f3a016619dbd948c1f0c111db22bc3140e..9ead3efb3f953773441a4fd8baf48973d1a436a9 100644 (file)
@@ -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)
index d54598b6960513d7f5b0b2797f8b3528da50879e..508604e60fb1f895ed1a83a24f1fb08725407964 100644 (file)
@@ -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 *);