From: Ben Pfaff Date: Sun, 1 Dec 2024 19:25:31 +0000 (-0800) Subject: move descriptives into its own module X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df06d4aa635e3478da78914338990df00ed2c95f;p=pspp move descriptives into its own module --- diff --git a/rust/pspp/src/command/descriptives.rs b/rust/pspp/src/command/descriptives.rs new file mode 100644 index 0000000000..0d33fccb8b --- /dev/null +++ b/rust/pspp/src/command/descriptives.rs @@ -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 >::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>>, +} + +#[derive(Debug, pspp_derive::FromTokens)] +#[pspp(add_lifetime, required_equals)] +enum DescriptivesSubcommand<'a> { + #[pspp(default)] + Variables(Vec>), + Missing(Vec), + Save, + Statistics(Vec), + Sort(Sort), + Format(Vec), +} + +#[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>, +} + +#[derive(Debug, pspp_derive::FromTokens)] +struct Sort { + key: SortKey, + direction: Option, +} + +#[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. +", + ); + } +} diff --git a/rust/pspp/src/command/mod.rs b/rust/pspp/src/command/mod.rs index 143d60f6aa..2490257f3d 100644 --- a/rust/pspp/src/command/mod.rs +++ b/rust/pspp/src/command/mod.rs @@ -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>>, -} - #[derive(Debug)] struct Subcommand(pub T); @@ -214,42 +211,6 @@ where } } -#[derive(Debug, FromTokens)] -#[pspp(add_lifetime, required_equals)] -enum DescriptivesSubcommand<'a> { - #[pspp(default)] - Variables(Vec>), - Missing(Vec), - Save, - Statistics(Vec), - Sort(Sort), - Format(Vec), -} - -#[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>, -} - #[derive(Debug)] struct InParens(pub T); @@ -342,51 +303,6 @@ impl<'a> FromTokens<'a> for &'a Identifier { } } -#[derive(Debug, FromTokens)] -struct Sort { - key: SortKey, - direction: Option, -} - -#[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> { 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> { fn commands() -> &'static [Command] { fn new_commands() -> Vec { 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 >::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. -"); - } - } -}