Work on DEFINE command.
[pspp] / src / language / lexer / token.c
index 89a5cf0102baf5fa77347ef8051469a8fde8dc77..9fa5bbb6ba81804534c809f4a2b90bb552c607cf 100644 (file)
 #include "data/identifier.h"
 #include "libpspp/assertion.h"
 #include "libpspp/cast.h"
+#include "libpspp/misc.h"
 
 #include "gl/ftoastr.h"
 #include "gl/xalloc.h"
 
-/* Initializes TOKEN with an arbitrary type, number 0, and a null string. */
 void
-token_init (struct token *token)
+token_copy (struct token *dst, const struct token *src)
 {
-  token->type = 0;
-  token->number = 0.0;
-  token->string = ss_empty ();
+  *dst = (struct token) {
+    .type = src->type,
+    .number = src->number,
+  };
+  ss_alloc_substring (&dst->string, src->string);
 }
 
 /* Frees the string that TOKEN contains. */
 void
-token_destroy (struct token *token)
+token_uninit (struct token *token)
 {
   if (token != NULL)
-    ss_dealloc (&token->string);
+    {
+      ss_dealloc (&token->string);
+      *token = (struct token) { .type = T_STOP };
+    }
+}
+
+bool
+token_equal (const struct token *a, const struct token *b)
+{
+  if (a->type != b->type)
+    return false;
+
+  switch (a->type)
+    {
+    case T_POS_NUM:
+    case T_NEG_NUM:
+      return a->number == b->number;
+
+    case T_ID:
+    case T_MACRO_ID:
+    case T_MACRO_PUNCT:
+    case T_STRING:
+      return ss_equals (a->string, b->string);
+
+    default:
+      return true;
+    }
 }
 
 static char *
@@ -51,7 +79,7 @@ number_token_to_string (const struct token *token)
 {
   char buffer[DBL_BUFSIZE_BOUND];
 
-  dtoastr (buffer, sizeof buffer, 0, 0, fabs (token->number));
+  c_dtoastr (buffer, sizeof buffer, 0, 0, fabs (token->number));
   return (token->type == T_POS_NUM
           ? xstrdup (buffer)
           : xasprintf ("-%s", buffer));
@@ -133,8 +161,6 @@ string_representation (struct substring ss)
 char *
 token_to_string (const struct token *token)
 {
-  const char *name;
-
   switch (token->type)
     {
     case T_POS_NUM:
@@ -142,14 +168,15 @@ token_to_string (const struct token *token)
       return number_token_to_string (token);
 
     case T_ID:
+    case T_MACRO_ID:
+    case T_MACRO_PUNCT:
       return ss_xstrdup (token->string);
 
     case T_STRING:
       return string_representation (token->string);
 
     default:
-      name = token_type_to_name (token->type);
-      return name != NULL ? xstrdup (name) : NULL;
+      return xstrdup_if_nonnull (token_type_to_string (token->type));
     }
 }
 
@@ -163,7 +190,7 @@ token_print (const struct token *token, FILE *stream)
     {
       char s[DBL_BUFSIZE_BOUND];
 
-      dtoastr (s, sizeof s, 0, 0, token->number);
+      c_dtoastr (s, sizeof s, 0, 0, token->number);
       fprintf (stream, "\t%s", s);
     }
   if (token->type == T_ID || token->type == T_STRING || token->string.length)
@@ -171,3 +198,41 @@ token_print (const struct token *token, FILE *stream)
              (int) token->string.length, token->string.string);
   putc ('\n', stream);
 }
+\f
+void
+tokens_copy (struct tokens *dst, const struct tokens *src)
+{
+  *dst = (struct tokens) {
+    .tokens = xnmalloc (src->n, sizeof *dst->tokens),
+    .n = src->n,
+    .allocated = src->n,
+  };
+
+  for (size_t i = 0; i < src->n; i++)
+    token_copy (&dst->tokens[i], &src->tokens[i]);
+}
+
+void
+tokens_uninit (struct tokens *tokens)
+{
+  for (size_t i = 0; i < tokens->n; i++)
+    token_uninit (&tokens->tokens[i]);
+  free (tokens->tokens);
+}
+
+void
+tokens_add (struct tokens *tokens, const struct token *t)
+{
+  if (tokens->allocated >= tokens->n)
+    tokens->tokens = x2nrealloc (tokens->tokens, &tokens->allocated,
+                                 sizeof *tokens->tokens);
+
+  token_copy (&tokens->tokens[tokens->n++], t);
+}
+
+void
+tokens_print (const struct tokens *tokens, FILE *stream)
+{
+  for (size_t i = 0; i < tokens->n; i++)
+    token_print (&tokens->tokens[i], stream);
+}