From: Ben Pfaff Date: Sat, 14 Dec 2024 17:29:35 +0000 (-0800) Subject: work on ctables X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87380e7288bfadfc1bcb9d33c4d5cd2fec33fa89;p=pspp work on ctables --- diff --git a/rust/pspp-derive/src/lib.rs b/rust/pspp-derive/src/lib.rs index afc1f5665f..8934b3d34c 100644 --- a/rust/pspp-derive/src/lib.rs +++ b/rust/pspp-derive/src/lib.rs @@ -152,11 +152,16 @@ fn construct_fields( fn derive_struct(ast: &DeriveInput, s: &DataStruct) -> Result { let struct_attrs = StructAttrs::parse(&ast.attrs)?; let name = &ast.ident; + let syntax = if let Some(syntax) = struct_attrs.syntax.as_ref() { + syntax .clone() + } else { + Literal::string(&name.to_string()) + }; let construction = construct_fields( &s.fields, quote! {#name}, false, - struct_attrs.syntax.as_ref(), + Some(&syntax) ); let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); let output = quote! { diff --git a/rust/pspp/src/command/crosstabs.rs b/rust/pspp/src/command/crosstabs.rs index 7644169f2b..3f6c3ab7f6 100644 --- a/rust/pspp/src/command/crosstabs.rs +++ b/rust/pspp/src/command/crosstabs.rs @@ -37,9 +37,12 @@ pub(super) fn crosstabs_command() -> Command { #[derive(Debug, pspp_derive::FromTokens)] struct Crosstabs(Subcommands); -#[derive(Debug, pspp_derive::FromTokens)] -#[pspp(syntax = "COUNT")] -struct CountKw; +mod keyword { + use crate::command::{FromTokens, ParseResult, TokenSlice}; + + #[derive(Debug, pspp_derive::FromTokens)] + pub struct Count; +} #[derive(Debug, pspp_derive::FromTokens)] enum CrosstabsSubcommand { @@ -47,7 +50,7 @@ enum CrosstabsSubcommand { Tables(Option, Punctuated), Missing(Equals, Missing), Write(Option<(Equals, Write)>), - HideSmallCounts(CountKw, Equals, Integer), + HideSmallCounts(keyword::Count, Equals, Integer), ShowDim(Equals, Integer), Statistics(Equals, Punctuated), Cells(Equals, Punctuated), diff --git a/rust/pspp/src/command/ctables.rs b/rust/pspp/src/command/ctables.rs index 328bac9976..ce6adf5d9a 100644 --- a/rust/pspp/src/command/ctables.rs +++ b/rust/pspp/src/command/ctables.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use either::Either; use flagset::FlagSet; @@ -46,9 +48,15 @@ struct CTables(Subcommands); enum CTablesSubcommand { Table(Table), Format(Seq1), - VLabels(Seq1), + VLabels(Seq1), SMissing(SMissing), PCompute(And, Identifier, Equals, keyword::Expr, InParens), + PProperties(And, Identifier, Seq0), + Weight(keyword::Variable, Equals, Identifier), + HideSmallCounts(keyword::Count, Equals, Integer), + SLabels(Seq1), + CLabels(CLabel), + Categories(Seq1), } #[derive(Debug, pspp_derive::FromTokens)] @@ -64,7 +72,7 @@ enum Axis { Nest(Box, Gt, Box), Stack(Box, Plus, Box), Parens(InParens>), - Annotate(InSquares>), + Summary(InSquares>), } #[derive(Debug, pspp_derive::FromTokens)] @@ -74,7 +82,7 @@ enum Measurement { } #[derive(Debug, pspp_derive::FromTokens)] -struct Annotation { +struct Summary { function: Identifier, percentile: Option, label: Option, @@ -112,7 +120,7 @@ enum Unit { } #[derive(Debug, pspp_derive::FromTokens)] -enum VLabels { +enum VLabel { Variables(Equals, VarList), Display(Display), } @@ -132,15 +140,73 @@ enum SMissing { Listwise, } -#[derive(Debug, pspp_derive::FromTokens)] +#[derive(pspp_derive::FromTokens)] struct Expression(MulExpression, Seq0<(Either, Expression)>); -#[derive(Debug, pspp_derive::FromTokens)] -struct MulExpression(PowExpression, Seq0<(Either, PowExpression)>); +impl Debug for Expression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.1 .0.is_empty() { + self.0.fmt(f) + } else { + write!(f, "(")?; + self.0.fmt(f)?; + for (operator, operand) in &self.1 .0 { + if operator.is_left() { + write!(f, " + ")?; + } else { + write!(f, " - ")?; + } + operand.fmt(f)?; + } + write!(f, ")") + } + } +} -#[derive(Debug, pspp_derive::FromTokens)] +#[derive(pspp_derive::FromTokens)] +struct MulExpression( + PowExpression, + Seq0<(Either, PowExpression)>, +); + +impl Debug for MulExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.1 .0.is_empty() { + self.0.fmt(f) + } else { + write!(f, "(")?; + self.0.fmt(f)?; + for (operator, operand) in &self.1 .0 { + if operator.is_left() { + write!(f, " * ")?; + } else { + write!(f, " / ")?; + } + operand.fmt(f)?; + } + write!(f, ")") + } + } +} + +#[derive(pspp_derive::FromTokens)] struct PowExpression(Terminal, Seq0<(Exp, PowExpression)>); +impl Debug for PowExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.1 .0.is_empty() { + self.0.fmt(f) + } else { + write!(f, "(")?; + self.0.fmt(f)?; + for (_operator, operand) in &self.1 .0 { + write!(f, " ** {operand:?}")?; + } + write!(f, ")") + } + } +} + #[derive(Debug, pspp_derive::FromTokens)] #[pspp(no_selector)] enum Terminal { @@ -168,52 +234,108 @@ enum Value { String(String), } +#[derive(Debug, pspp_derive::FromTokens)] +enum PProperties { + Label(Equals, String), + Format(Equals, Seq1), + HideSourceCats(Equals, Boolean), +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum Boolean { + Yes, + No, +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum SLabel { + Position(Equals, Position), + Visible(Equals, Boolean), +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum Position { + Column, + Row, + Layer, +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum CLabel { + Auto, + RowLabels(Equals, LabelDestination), + ColLabels(Equals, LabelDestination), +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum LabelDestination { + Opposite, + Layer, +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum Category { + Variables(Equals, VarList), + Order(Equals, Direction), + Key(Equals, Key), +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum Direction { + #[pspp(syntax = "A")] + Ascending, + #[pspp(syntax = "D")] + Descending, +} + +#[derive(Debug, pspp_derive::FromTokens)] +enum Key { + Value, + Label, + +} + mod keyword { use crate::command::{FromTokens, ParseResult, TokenSlice}; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "default")] pub struct Default; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "expr")] pub struct Expr; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "zero")] pub struct Zero; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "blank")] pub struct Blank; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "thru")] pub struct Thru; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "hi")] pub struct Hi; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "lo")] pub struct Lo; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "missing")] pub struct Missing; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "othernm")] pub struct OtherNm; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "subtotal")] pub struct Subtotal; #[derive(Debug, pspp_derive::FromTokens)] - #[pspp(syntax = "total")] pub struct Total; + + #[derive(Debug, pspp_derive::FromTokens)] + pub struct Variable; + + #[derive(Debug, pspp_derive::FromTokens)] + pub struct Count; } #[cfg(test)] @@ -237,7 +359,7 @@ mod tests { #[test] fn basics() { test( - "ctables /pcompute &all_drivers =expr([1 thru 2]) + "ctables /pcompute &all_drivers =expr(1+2*3+4) /pcompute &all_drivers =expr(1).", ); } diff --git a/rust/pspp/src/command/mod.rs b/rust/pspp/src/command/mod.rs index a4f84bea9d..b0480be4cb 100644 --- a/rust/pspp/src/command/mod.rs +++ b/rust/pspp/src/command/mod.rs @@ -254,7 +254,6 @@ pub struct Asterisk; pub struct Exp; #[derive(Debug, pspp_derive::FromTokens)] -#[pspp(syntax = "BY")] struct By; pub struct Punctuated> { @@ -648,9 +647,14 @@ fn parse_syntax(input: &TokenSlice, syntax: &str) -> ParseResult<()> { pub type VarList = Punctuated; -#[derive(Debug)] pub struct Number(f64); +impl Debug for Number { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } +} + impl FromTokens for Number { fn from_tokens(input: &TokenSlice) -> ParseResult where