move descriptives into its own module
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 1 Dec 2024 19:25:31 +0000 (11:25 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 1 Dec 2024 19:25:31 +0000 (11:25 -0800)
rust/pspp/src/command/descriptives.rs [new file with mode: 0644]
rust/pspp/src/command/mod.rs

diff --git a/rust/pspp/src/command/descriptives.rs b/rust/pspp/src/command/descriptives.rs
new file mode 100644 (file)
index 0000000..0d33fcc
--- /dev/null
@@ -0,0 +1,188 @@
+use flagset::FlagSet;
+
+use super::{Command, Subcommand};
+use crate::command::{
+    parse_token, FromTokens, Identifier, InParens, MismatchToError, ParseError, ParseResult,
+    Parsed, Punct, Token, TokenSlice, Vars,
+};
+
+pub(super) fn descriptives_command() -> Command {
+    Command {
+        allowed_states: FlagSet::full(),
+        enhanced_only: false,
+        testing_only: false,
+        no_abbrev: false,
+        name: "DESCRIPTIVES",
+        run: Box::new(|context| {
+            let mut input = context.lexer;
+            while !input.is_empty() {
+                match <Subcommand<DescriptivesSubcommand>>::from_tokens(input) {
+                    Ok(Parsed {
+                        value: subcommand,
+                        rest,
+                        diagnostics,
+                    }) => {
+                        println!("\n{subcommand:?}");
+                        //println!("rest: {rest:?}");
+                        println!("warnings: {diagnostics:?}");
+                        //println!("{:?}", DescriptivesSubcommand::from_tokens(subcommand.0));
+                        input = rest;
+                    }
+                    Err(error) => {
+                        println!("{error:?}");
+                        break;
+                    }
+                }
+            }
+        }),
+    }
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+#[pspp(add_lifetime)]
+struct Descriptives<'a> {
+    subcommands: Vec<Subcommand<DescriptivesSubcommand<'a>>>,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+#[pspp(add_lifetime, required_equals)]
+enum DescriptivesSubcommand<'a> {
+    #[pspp(default)]
+    Variables(Vec<DescriptivesVars<'a>>),
+    Missing(Vec<Missing>),
+    Save,
+    Statistics(Vec<Statistic>),
+    Sort(Sort),
+    Format(Vec<Format>),
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+enum Missing {
+    Variable,
+    Listwise,
+    Include,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+enum Format {
+    Labels,
+    NoLabels,
+    Index,
+    NoIndex,
+    Line,
+    Serial,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+#[pspp(add_lifetime)]
+struct DescriptivesVars<'a> {
+    vars: Vars<'a>,
+    z_name: Option<InParens<&'a Identifier>>,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+struct Sort {
+    key: SortKey,
+    direction: Option<Direction>,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+enum SortKey {
+    Mean,
+    SMean,
+    Stddev,
+    Variance,
+    Range,
+    Min,
+    Max,
+    Sum,
+    Skewness,
+    Kurtosis,
+    Name,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+enum Direction {
+    #[pspp(syntax = "(A)")]
+    Ascending,
+    #[pspp(syntax = "(D)")]
+    Descending,
+}
+
+#[derive(Debug, pspp_derive::FromTokens)]
+enum Statistic {
+    Default,
+    Mean,
+    SeMean,
+    Stddev,
+    Variance,
+    Range,
+    Sum,
+    Min,
+    Max,
+    Skewness,
+    Kurtosis,
+    All,
+}
+
+#[cfg(test)]
+mod tests {
+    use std::sync::Arc;
+
+    use encoding_rs::UTF_8;
+
+    use crate::{
+        engine::Engine,
+        lex::lexer::{Source, SourceFile},
+    };
+
+    fn test(syntax: &str) {
+        let mut engine = Engine::new();
+        engine.run(Source::new_default(&Arc::new(
+            SourceFile::for_file_contents(syntax.to_string(), Some("test.sps".to_string()), UTF_8),
+        )));
+    }
+
+    #[test]
+    fn basics() {
+        test("descript a to b (c) all/stat=all/format=serial.");
+    }
+
+    #[test]
+    fn include_missing() {
+        test("descript all/stat=all/format=serial/missing=include.");
+    }
+
+    #[test]
+    fn include_missing_listwise() {
+        test("descript all/stat=all/format=serial/missing=listwise.");
+        test("descript all/stat=all/format=serial/missing=listwise include.");
+    }
+
+    #[test]
+    fn mean_only() {
+        test("descript all/stat=mean.");
+    }
+
+    #[test]
+    fn z_scores() {
+        test("DESCRIPTIVES /VAR=a b /SAVE.");
+    }
+
+    #[test]
+    fn syntax_errors() {
+        test(
+            "\
+DESCRIPTIVES MISSING=**.
+DESCRIPTIVES FORMAT=**.
+DESCRIPTIVES STATISTICS=**.
+DESCRIPTIVES SORT=**.
+DESCRIPTIVES SORT=NAME (**).
+DESCRIPTIVES SORT=NAME (A **).
+DESCRIPTIVES **.
+DESCRIPTIVES x/ **.
+DESCRIPTIVES MISSING=INCLUDE.
+",
+        );
+    }
+}
index 143d60f6aaa518804c347314789f73d0dc498377..2490257f3db5501a3e14f0ccde57db54523def7f 100644 (file)
@@ -1,6 +1,7 @@
 #![allow(dead_code)]
 use std::{fmt::Write, ops::RangeFrom, sync::OnceLock};
 
+use descriptives::descriptives_command;
 use flagset::{flags, FlagSet};
 use pspp_derive::FromTokens;
 
@@ -15,6 +16,8 @@ use crate::{
     message::{Diagnostic, Diagnostics},
 };
 
+pub mod descriptives;
+
 flags! {
     enum State: u8 {
         /// No active dataset yet defined.
@@ -179,12 +182,6 @@ impl<'a> FromTokens<'a> for TokenSlice<'a> {
     }
 }
 
-#[derive(Debug, FromTokens)]
-#[pspp(add_lifetime)]
-struct Descriptives<'a> {
-    subcommands: Vec<Subcommand<DescriptivesSubcommand<'a>>>,
-}
-
 #[derive(Debug)]
 struct Subcommand<T>(pub T);
 
@@ -214,42 +211,6 @@ where
     }
 }
 
-#[derive(Debug, FromTokens)]
-#[pspp(add_lifetime, required_equals)]
-enum DescriptivesSubcommand<'a> {
-    #[pspp(default)]
-    Variables(Vec<DescriptivesVars<'a>>),
-    Missing(Vec<Missing>),
-    Save,
-    Statistics(Vec<Statistic>),
-    Sort(Sort),
-    Format(Vec<Format>),
-}
-
-#[derive(Debug, FromTokens)]
-enum Missing {
-    Variable,
-    Listwise,
-    Include,
-}
-
-#[derive(Debug, FromTokens)]
-enum Format {
-    Labels,
-    NoLabels,
-    Index,
-    NoIndex,
-    Line,
-    Serial,
-}
-
-#[derive(Debug, FromTokens)]
-#[pspp(add_lifetime)]
-struct DescriptivesVars<'a> {
-    vars: Vars<'a>,
-    z_name: Option<InParens<&'a Identifier>>,
-}
-
 #[derive(Debug)]
 struct InParens<T>(pub T);
 
@@ -342,51 +303,6 @@ impl<'a> FromTokens<'a> for &'a Identifier {
     }
 }
 
-#[derive(Debug, FromTokens)]
-struct Sort {
-    key: SortKey,
-    direction: Option<Direction>,
-}
-
-#[derive(Debug, FromTokens)]
-enum SortKey {
-    Mean,
-    SMean,
-    Stddev,
-    Variance,
-    Range,
-    Min,
-    Max,
-    Sum,
-    Skewness,
-    Kurtosis,
-    Name,
-}
-
-#[derive(Debug, FromTokens)]
-enum Direction {
-    #[pspp(syntax = "(A)")]
-    Ascending,
-    #[pspp(syntax = "(D)")]
-    Descending,
-}
-
-#[derive(Debug, FromTokens)]
-enum Statistic {
-    Default,
-    Mean,
-    SeMean,
-    Stddev,
-    Variance,
-    Range,
-    Sum,
-    Min,
-    Max,
-    Skewness,
-    Kurtosis,
-    All,
-}
-
 fn collect_subcommands<'a>(src: &'a TokenSlice) -> Vec<TokenSlice<'a>> {
     src.split(|token| token.token == Token::Punct(Punct::Slash))
         .filter(|slice| !slice.is_empty())
@@ -396,35 +312,7 @@ fn collect_subcommands<'a>(src: &'a TokenSlice) -> Vec<TokenSlice<'a>> {
 fn commands() -> &'static [Command] {
     fn new_commands() -> Vec<Command> {
         vec![
-            Command {
-                allowed_states: FlagSet::full(),
-                enhanced_only: false,
-                testing_only: false,
-                no_abbrev: false,
-                name: "DESCRIPTIVES",
-                run: Box::new(|context| {
-                    let mut input = context.lexer;
-                    while !input.is_empty() {
-                        match <Subcommand<DescriptivesSubcommand>>::from_tokens(input) {
-                            Ok(Parsed {
-                                value: subcommand,
-                                rest,
-                                diagnostics,
-                            }) => {
-                                println!("\n{subcommand:?}");
-                                //println!("rest: {rest:?}");
-                                println!("warnings: {diagnostics:?}");
-                                //println!("{:?}", DescriptivesSubcommand::from_tokens(subcommand.0));
-                                input = rest;
-                            }
-                            Err(error) => {
-                                println!("{error:?}");
-                                break;
-                            }
-                        }
-                    }
-                }),
-            },
+            descriptives_command(),
             Command {
                 allowed_states: FlagSet::full(),
                 enhanced_only: false,
@@ -566,69 +454,3 @@ impl<'a> Context<'a> {
         (self.error)(diagnostic);
     }
 }
-
-#[cfg(test)]
-mod tests {
-    mod descriptives {
-        use std::sync::Arc;
-
-        use encoding_rs::UTF_8;
-
-        use crate::{
-            engine::Engine,
-            lex::lexer::{Source, SourceFile},
-        };
-
-        fn test(syntax: &str) {
-            let mut engine = Engine::new();
-            engine.run(Source::new_default(&Arc::new(
-                SourceFile::for_file_contents(
-                    syntax.to_string(),
-                    Some("test.sps".to_string()),
-                    UTF_8,
-                ),
-            )));
-        }
-
-        #[test]
-        fn basics() {
-            test("descript a to b (c) all/stat=all/format=serial.");
-        }
-
-        #[test]
-        fn include_missing() {
-            test("descript all/stat=all/format=serial/missing=include.");
-        }
-
-        #[test]
-        fn include_missing_listwise() {
-            test("descript all/stat=all/format=serial/missing=listwise.");
-            test("descript all/stat=all/format=serial/missing=listwise include.");
-        }
-
-        #[test]
-        fn mean_only() {
-            test("descript all/stat=mean.");
-        }
-
-        #[test]
-        fn z_scores() {
-            test("DESCRIPTIVES /VAR=a b /SAVE.");
-        }
-
-        #[test]
-        fn syntax_errors() {
-            test("\
-DESCRIPTIVES MISSING=**.
-DESCRIPTIVES FORMAT=**.
-DESCRIPTIVES STATISTICS=**.
-DESCRIPTIVES SORT=**.
-DESCRIPTIVES SORT=NAME (**).
-DESCRIPTIVES SORT=NAME (A **).
-DESCRIPTIVES **.
-DESCRIPTIVES x/ **.
-DESCRIPTIVES MISSING=INCLUDE.
-");
-        }
-    }
-}