segment: Add support for segmenting "snippets".
[pspp] / src / language / lexer / segment.c
index ac88117ff5270e1a8b43cdf38172af5aaf431f16..9728e176f4df9ab6070d7169ebe40d00a4ae4684 100644 (file)
@@ -55,9 +55,6 @@ enum segmenter_state
     S_TITLE_2
   };
 
-/* S_SHBANG is the start state that SEGMENTER_INIT refers to as just 0. */
-verify (S_SHBANG == 0);
-
 #define SS_START_OF_LINE (1u << 0)
 #define SS_START_OF_COMMAND (1u << 1)
 
@@ -1802,15 +1799,28 @@ segment_type_to_string (enum segment_type type)
     }
 }
 
-/* Initializes S as a segmenter with the given syntax MODE.
+/* Returns a segmenter with the given syntax MODE.
+
+   If IS_SNIPPET is false, then the segmenter will parse as if it's being given
+   a whole file.  This means, for example, that it will interpret - or + at the
+   beginning of the syntax as a separator between commands (since - or + at the
+   beginning of a line has this meaning).
+
+   If IS_SNIPPET is true, then the segmenter will parse as if it's being given
+   an isolated piece of syntax.  This means that, for example, that it will
+   interpret - or + at the beginning of the syntax as an operator token or (if
+   followed by a digit) as part of a number.
 
    A segmenter does not contain any external references, so nothing needs to be
    done to destroy one.  For the same reason, segmenters may be copied with
    plain struct assignment (or memcpy). */
-void
-segmenter_init (struct segmenter *s, enum segmenter_mode mode)
+struct segmenter
+segmenter_init (enum segmenter_mode mode, bool is_snippet)
 {
-  *s = (struct segmenter) SEGMENTER_INIT (mode);
+  return (struct segmenter) {
+    .state = is_snippet ? S_GENERAL : S_SHBANG,
+    .mode = mode,
+  };
 }
 
 /* Returns the mode passed to segmenter_init() for S. */