From 8316ea97daf64cfdcbdffcf266a015fd931d6710 Mon Sep 17 00:00:00 2001 From: LucasFA Date: Thu, 11 May 2023 04:52:47 +0200 Subject: [PATCH] =?UTF-8?q?Turn=20SyntaxKind=20into=20a=20wrapper=20?= =?UTF-8?q?=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having SyntaxKind be a unit-only enum repeating all the fields of TokenKind and adding some SyntaxConstructs on top was not ergonomic Now, SyntaxKind holds either a TokenKind or a SyntaxConstruct, which hold what you would expect. Removes the full coverage test as it is no longer needed Some dependencies have been migrated to other crates: num-derive and num-traits have been phased out in favour of num_enum --- crates/ast/src/lib.rs | 59 +++++--- crates/hir/src/database.rs | 12 +- crates/lexer/Cargo.toml | 4 +- crates/lexer/src/token_kind.rs | 13 +- crates/parser/src/grammar.rs | 3 +- crates/parser/src/grammar/expr.rs | 12 +- crates/parser/src/grammar/stmt.rs | 16 +- crates/parser/src/parser.rs | 4 +- crates/syntax/Cargo.toml | 4 +- crates/syntax/src/lib.rs | 244 ++++++++---------------------- docs/graph.svg | Bin 72612 -> 83458 bytes 11 files changed, 134 insertions(+), 237 deletions(-) diff --git a/crates/ast/src/lib.rs b/crates/ast/src/lib.rs index de3fd96..162981b 100644 --- a/crates/ast/src/lib.rs +++ b/crates/ast/src/lib.rs @@ -1,7 +1,6 @@ #![warn(clippy::pedantic)] -use syntax::{SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken}; - +use syntax::{SyntaxConstruct, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TokenKind}; pub mod validation; pub trait TypedSyntaxNode { @@ -21,7 +20,8 @@ mod macros { where Self: Sized, { - if node.kind() == SyntaxKind::$struct_name { + if let SyntaxKind::SyntaxConstruct(SyntaxConstruct::$struct_name) = node.kind() + { Some(Self(node)) } else { None @@ -29,8 +29,8 @@ mod macros { } } const _: () = { - // Simply a check that struct_name is a variant of SyntaxKind - const _: SyntaxKind = SyntaxKind::$struct_name; + // Simply a check that struct_name is a variant of SyntaxConstruct + const _: SyntaxConstruct = SyntaxConstruct::$struct_name; }; }; } @@ -58,7 +58,7 @@ impl Root { #[must_use] pub fn get_variable_references(&self) -> Vec { fn inner_get_variable_references(node: SyntaxNode) -> Vec { - if node.kind() == SyntaxKind::VariableRef { + if node.kind() == SyntaxConstruct::VariableRef.into() { vec![VariableRef::cast(node).unwrap()] } else { node.children() @@ -75,11 +75,11 @@ impl VariableDef { self.0 .children_with_tokens() .filter_map(SyntaxElement::into_node) - .find(|node| node.kind() == SyntaxKind::VariableRef) + .find(|node| node.kind() == SyntaxConstruct::VariableRef.into()) .unwrap() .children_with_tokens() .filter_map(SyntaxElement::into_token) - .find(|token| token.kind() == SyntaxKind::Identifier) + .find(|token| token.kind() == TokenKind::Identifier.into()) } pub fn value(&self) -> Option { @@ -90,14 +90,21 @@ impl VariableDef { impl Expr { #[must_use] pub fn cast(node: SyntaxNode) -> Option { - let result = match node.kind() { - SyntaxKind::InfixExpr => Self::BinaryExpr(BinaryExpr(node)), - SyntaxKind::Literal => Self::Literal(Literal(node)), - SyntaxKind::ParenExpr => Self::ParenExpr(ParenExpr(node)), - SyntaxKind::PrefixExpr => Self::UnaryExpr(UnaryExpr(node)), - SyntaxKind::VariableRef => Self::VariableRef(VariableRef(node)), - _ => return None, - }; + let result; + if let SyntaxKind::SyntaxConstruct(inner) = node.kind() { + result = match inner { + SyntaxConstruct::InfixExpr => Self::BinaryExpr(BinaryExpr(node)), + SyntaxConstruct::Literal => Self::Literal(Literal(node)), + SyntaxConstruct::ParenExpr => Self::ParenExpr(ParenExpr(node)), + SyntaxConstruct::PrefixExpr => Self::UnaryExpr(UnaryExpr(node)), + SyntaxConstruct::VariableRef => Self::VariableRef(VariableRef(node)), + SyntaxConstruct::Error => return None, + SyntaxConstruct::Root => unreachable!(), + SyntaxConstruct::VariableDef => unreachable!(), + }; + } else { + return None; + } Some(result) } @@ -117,10 +124,14 @@ impl BinaryExpr { .children_with_tokens() .filter_map(SyntaxElement::into_token) .find(|token| { - matches!( - token.kind(), - SyntaxKind::Plus | SyntaxKind::Minus | SyntaxKind::Asterisk | SyntaxKind::Slash, - ) + if let SyntaxKind::LexToken(inner) = token.kind() { + matches!( + inner, + TokenKind::Plus | TokenKind::Minus | TokenKind::Asterisk | TokenKind::Slash, + ) + } else { + false + } }) } } @@ -134,7 +145,7 @@ impl UnaryExpr { self.0 .children_with_tokens() .filter_map(SyntaxElement::into_token) - .find(|token| token.kind() == SyntaxKind::Minus) + .find(|token| token.kind() == TokenKind::Minus.into()) } } @@ -152,7 +163,7 @@ impl Literal { #[must_use] pub fn cast(node: SyntaxNode) -> Option { - if node.kind() == SyntaxKind::Literal { + if node.kind() == SyntaxConstruct::Literal.into() { Some(Self(node)) } else { None @@ -177,7 +188,9 @@ impl Stmt { #[must_use] pub fn cast(node: SyntaxNode) -> Option { let result = match node.kind() { - SyntaxKind::VariableDef => Self::VariableDef(VariableDef(node)), + SyntaxKind::SyntaxConstruct(SyntaxConstruct::VariableDef) => { + Self::VariableDef(VariableDef(node)) + } _ => Self::Expr(Expr::cast(node)?), }; diff --git a/crates/hir/src/database.rs b/crates/hir/src/database.rs index 4dde700..68f12fa 100644 --- a/crates/hir/src/database.rs +++ b/crates/hir/src/database.rs @@ -1,6 +1,6 @@ use crate::{BinaryOp, Expr, Stmt, UnaryOp}; use la_arena::Arena; -use syntax::SyntaxKind; +use syntax::{SyntaxKind, TokenKind}; #[derive(Debug, PartialEq, Default)] pub struct Database { @@ -42,10 +42,10 @@ impl Database { fn lower_binary(&mut self, ast: ast::BinaryExpr) -> Expr { let op = match ast.op().unwrap().kind() { - SyntaxKind::Plus => BinaryOp::Add, - SyntaxKind::Minus => BinaryOp::Sub, - SyntaxKind::Asterisk => BinaryOp::Mul, - SyntaxKind::Slash => BinaryOp::Div, + SyntaxKind::LexToken(TokenKind::Plus) => BinaryOp::Add, + SyntaxKind::LexToken(TokenKind::Minus) => BinaryOp::Sub, + SyntaxKind::LexToken(TokenKind::Asterisk) => BinaryOp::Mul, + SyntaxKind::LexToken(TokenKind::Slash) => BinaryOp::Div, _ => unreachable!(), }; @@ -61,7 +61,7 @@ impl Database { fn lower_unary(&mut self, ast: ast::UnaryExpr) -> Expr { let op = match ast.op().unwrap().kind() { - SyntaxKind::Minus => UnaryOp::Neg, + SyntaxKind::LexToken(TokenKind::Minus) => UnaryOp::Neg, _ => unreachable!(), }; diff --git a/crates/lexer/Cargo.toml b/crates/lexer/Cargo.toml index d99569e..cdb9828 100644 --- a/crates/lexer/Cargo.toml +++ b/crates/lexer/Cargo.toml @@ -11,5 +11,5 @@ logos = "0.12.1" text-size = "1.1.0" strum = "0.24.1" strum_macros = "0.24.3" -num-derive = "0.3.3" -num-traits = "0.2.15" \ No newline at end of file +num_enum = "0.6.1" +num_enum_derive = "0.6.1" \ No newline at end of file diff --git a/crates/lexer/src/token_kind.rs b/crates/lexer/src/token_kind.rs index fdcda4e..49817f7 100644 --- a/crates/lexer/src/token_kind.rs +++ b/crates/lexer/src/token_kind.rs @@ -1,7 +1,7 @@ use logos::Logos; -use num_derive::{FromPrimitive, ToPrimitive}; +use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::fmt; -use strum_macros::EnumIter; +use strum_macros::EnumCount; /// The kind of a token produced by the lexer. /// It is called this for consistency with Rowan, the parsing library. @@ -15,13 +15,14 @@ use strum_macros::EnumIter; PartialOrd, Ord, Hash, - EnumIter, - ToPrimitive, - FromPrimitive, + IntoPrimitive, + TryFromPrimitive, + EnumCount, )] -#[repr(u16)] +#[cfg_attr(test, derive(strum_macros::EnumIter))] // #[logos(subpattern close_block_comment = r##"(#|%)\}"##)] // #[logos(subpattern open_block_comment = r##"(#|%)\{"##)] +#[repr(u8)] pub enum TokenKind { // This would be ideal for block comments, but logos doesn't support non-greedy regexes // #[regex(r##"(#|%)\{\s*\n(.|\n)*?(#|%)\}"##)] diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index 86b59f5..031a96a 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs @@ -4,6 +4,7 @@ mod stmt; use crate::parser::marker::CompletedMarker; use crate::parser::Parser; use lexer::TokenKind; +use syntax::SyntaxConstruct; use syntax::SyntaxKind; pub(crate) fn root(p: &mut Parser) -> CompletedMarker { @@ -12,5 +13,5 @@ pub(crate) fn root(p: &mut Parser) -> CompletedMarker { stmt::stmt(p); } - m.complete(p, SyntaxKind::Root) + m.complete(p, SyntaxKind::SyntaxConstruct(SyntaxConstruct::Root)) } diff --git a/crates/parser/src/grammar/expr.rs b/crates/parser/src/grammar/expr.rs index a804f0e..eb23cd2 100644 --- a/crates/parser/src/grammar/expr.rs +++ b/crates/parser/src/grammar/expr.rs @@ -3,7 +3,7 @@ use crate::parser::marker::CompletedMarker; use crate::parser::Parser; use lexer::TokenKind; -use syntax::SyntaxKind; +use syntax::SyntaxConstruct; enum BinaryOp { Add, @@ -43,7 +43,7 @@ fn literal(p: &mut Parser) -> CompletedMarker { let m = p.start(); p.bump(); - m.complete(p, SyntaxKind::Literal) + m.complete(p, SyntaxConstruct::Literal.into()) } fn variable_ref(p: &mut Parser) -> CompletedMarker { @@ -51,7 +51,7 @@ fn variable_ref(p: &mut Parser) -> CompletedMarker { let m = p.start(); p.bump(); - m.complete(p, SyntaxKind::VariableRef) + m.complete(p, SyntaxConstruct::VariableRef.into()) } fn prefix_expr(p: &mut Parser) -> CompletedMarker { @@ -67,7 +67,7 @@ fn prefix_expr(p: &mut Parser) -> CompletedMarker { expr_binding_power(p, right_binding_power); - m.complete(p, SyntaxKind::PrefixExpr) + m.complete(p, SyntaxConstruct::PrefixExpr.into()) } fn paren_expr(p: &mut Parser) -> CompletedMarker { @@ -80,7 +80,7 @@ fn paren_expr(p: &mut Parser) -> CompletedMarker { p.expect(TokenKind::RParen); - m.complete(p, SyntaxKind::ParenExpr) + m.complete(p, SyntaxConstruct::ParenExpr.into()) } fn lhs(p: &mut Parser) -> Option { @@ -136,7 +136,7 @@ fn expr_binding_power(p: &mut Parser, minimum_binding_power: u8) -> Option Option { if p.at(TokenKind::Identifier) { @@ -14,23 +16,25 @@ fn handle_variable(p: &mut Parser) -> CompletedMarker { p.bump(); if p.at(TokenKind::Equals) { - let var_def = lhs.complete(p, SyntaxKind::VariableRef).precede(p); + let var_def = lhs + .complete(p, SyntaxConstruct::VariableRef.into()) + .precede(p); p.bump(); expr::expr(p); - return var_def.complete(p, SyntaxKind::VariableDef); + return var_def.complete(p, SyntaxConstruct::VariableDef.into()); } if p.at_end() { - return lhs.complete(p, SyntaxKind::VariableRef); + return lhs.complete(p, SyntaxConstruct::VariableRef.into()); } - let lhs = lhs.complete(p, SyntaxKind::VariableRef); + let lhs = lhs.complete(p, SyntaxConstruct::VariableRef.into()); let m = lhs.precede(p); // get what it is and then p.bump(); expr::expr(p); - m.complete(p, SyntaxKind::InfixExpr) + m.complete(p, SyntaxConstruct::InfixExpr.into()) } #[cfg(test)] diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index a2953e7..ac8a0a8 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -9,7 +9,7 @@ use crate::source::Source; use lexer::{Token, TokenKind}; use marker::Marker; use std::mem; -use syntax::SyntaxKind; +use syntax::SyntaxConstruct; const RECOVERY_SET: [TokenKind; 0] = []; @@ -84,7 +84,7 @@ impl<'t, 'input> Parser<'t, 'input> { if !self.at_set(&RECOVERY_SET) && !self.at_end() { let m = self.start(); self.bump(); - m.complete(self, SyntaxKind::Error); + m.complete(self, SyntaxConstruct::Error.into()); } } diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 21fa45c..3e6e038 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -8,8 +8,8 @@ publish = false [dependencies] lexer = {path = "../lexer"} -num-derive = "0.3.3" -num-traits = "0.2.15" rowan = "0.15.11" strum = "0.24.1" strum_macros = "0.24.3" +num_enum = "0.6.1" +static_assertions = "1.1.0" \ No newline at end of file diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index ddc9397..e9ce40f 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -1,10 +1,12 @@ //! Defines the equivalence from Lexical tokens to Syntactical tokens. #![warn(clippy::pedantic)] -use lexer::TokenKind; -use num_derive::{FromPrimitive, ToPrimitive}; -use num_traits::{FromPrimitive, ToPrimitive}; -use strum_macros::EnumIter; +use std::fmt::Debug; + +pub use lexer::TokenKind; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use static_assertions::const_assert; +use strum::EnumCount; #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] pub enum OctaveLanguage {} @@ -16,89 +18,52 @@ impl rowan::Language for OctaveLanguage { type Kind = SyntaxKind; fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind { - Self::Kind::from_u16(raw.0).unwrap() + Self::Kind::try_from(raw.0).unwrap() } fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind { - rowan::SyntaxKind(kind.to_u16().unwrap()) + rowan::SyntaxKind(kind.into()) } } pub type SyntaxNode = rowan::SyntaxNode; -#[derive( - Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, FromPrimitive, ToPrimitive, EnumIter, -)] -#[repr(u16)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum SyntaxKind { - Comment, - Semicolon, - Newline, - Whitespace, + LexToken(TokenKind), + SyntaxConstruct(SyntaxConstruct), +} - // Statement Keywords - FnKw, - EndFnKw, - IfKw, - ElseIfKw, - ElseKw, - EndIfKw, - SwitchKw, - CaseKw, - OtherwiseKw, - EndSwitch, - WhileKw, - EndWhileKw, - DoKw, - UntilKw, - ForKw, - EndForKw, - BreakKw, - ContinueKw, - UnwindProtectKw, - UnwindProtectCleanupKw, - EndUnwindProtectKw, - TryKw, - CatchKw, - EndTryKw, - EndKw, +impl std::fmt::Debug for SyntaxKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::LexToken(token) => write!(f, "{:?}", token), + Self::SyntaxConstruct(construct) => write!(f, "{:?}", construct), + } + } +} - // Operators - Plus, - Minus, - Asterisk, - ElmtMult, - Slash, - ElmtDiv, - LeftDiv, - ElmtLeftDiv, - Caret, - ElmtPow, - Transpose, - ElmtTranspose, - Not, - And, - Or, - EqualsEquals, - NotEquals, - LessThan, - GreaterThan, - LessThanEquals, - GreaterThanEquals, - Equals, +impl From for SyntaxKind { + #[inline] + fn from(value: TokenKind) -> Self { + SyntaxKind::LexToken(value) + } +} - //Puntuaction - Colon, - LBrace, - RBrace, - LBracket, - RBracket, - LParen, - RParen, - Identifier, - Number, +impl From for SyntaxKind { + #[inline] + fn from(value: SyntaxConstruct) -> Self { + SyntaxKind::SyntaxConstruct(value) + } +} - // Syntax-level nodes - Error, +const_assert!(TokenKind::COUNT <= u8::MAX as usize); +#[derive( + Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, IntoPrimitive, TryFromPrimitive, +)] +#[repr(u8)] +#[cfg_attr(test, derive(strum_macros::EnumIter))] +pub enum SyntaxConstruct { + Error = TokenKind::COUNT as u8, Root, InfixExpr, ParenExpr, @@ -108,117 +73,30 @@ pub enum SyntaxKind { VariableDef, } -impl From for SyntaxKind { - fn from(token_kind: TokenKind) -> Self { - match token_kind { - TokenKind::Whitespace => Self::Whitespace, - TokenKind::Newline => Self::Newline, - TokenKind::Semicolon => Self::Semicolon, - - // Keywords - TokenKind::FnKw => Self::FnKw, - TokenKind::EndFnKw => Self::EndFnKw, - TokenKind::IfKw => Self::IfKw, - TokenKind::ElseIfKw => Self::ElseIfKw, - TokenKind::ElseKw => Self::ElseKw, - TokenKind::EndIfKw => Self::EndIfKw, - TokenKind::SwitchKw => Self::SwitchKw, - TokenKind::CaseKw => Self::CaseKw, - TokenKind::OtherwiseKw => Self::OtherwiseKw, - TokenKind::EndSwitchKw => Self::EndSwitch, - TokenKind::WhileKw => Self::WhileKw, - TokenKind::EndWhileKw => Self::EndWhileKw, - TokenKind::DoKw => Self::DoKw, - TokenKind::UntilKw => Self::UntilKw, - TokenKind::ForKw => Self::ForKw, - TokenKind::EndForKw => Self::EndForKw, - TokenKind::BreakKw => Self::BreakKw, - TokenKind::ContinueKw => Self::ContinueKw, - TokenKind::UnwindProtectKw => Self::UnwindProtectKw, - TokenKind::UnwindProtectCleanupKw => Self::UnwindProtectCleanupKw, - TokenKind::EndUnwindProtectKw => Self::EndUnwindProtectKw, - TokenKind::TryKw => Self::TryKw, - TokenKind::CatchKw => Self::CatchKw, - TokenKind::EndTryKw => Self::EndTryKw, - TokenKind::EndKw => Self::EndKw, - - TokenKind::Identifier => Self::Identifier, - TokenKind::Number => Self::Number, - - TokenKind::Plus => Self::Plus, - TokenKind::Minus => Self::Minus, - TokenKind::Asterisk => Self::Asterisk, - TokenKind::ElmtMult => Self::ElmtMult, - TokenKind::Slash => Self::Slash, - TokenKind::ElmtDiv => Self::ElmtDiv, - TokenKind::LeftDiv => Self::LeftDiv, - TokenKind::ElmtLeftDiv => Self::ElmtLeftDiv, - TokenKind::Caret => Self::Caret, - TokenKind::ElmtPow => Self::ElmtPow, - TokenKind::Transpose => Self::Transpose, - TokenKind::ElmtTranspose => Self::ElmtTranspose, - TokenKind::Not => Self::Not, - TokenKind::And => Self::And, - TokenKind::Or => Self::Or, - TokenKind::EqualsEquals => Self::EqualsEquals, - TokenKind::NotEquals => Self::NotEquals, - TokenKind::LessThan => Self::LessThan, - TokenKind::GreaterThan => Self::GreaterThan, - TokenKind::LessThanEquals => Self::LessThanEquals, - TokenKind::GreaterThanEquals => Self::GreaterThanEquals, - TokenKind::Equals => Self::Equals, - TokenKind::Colon => Self::Colon, - - TokenKind::LParen => Self::LParen, - TokenKind::RParen => Self::RParen, - TokenKind::LBracket => Self::LBracket, - TokenKind::RBracket => Self::RBracket, - TokenKind::LBrace => Self::LBrace, - TokenKind::RBrace => Self::RBrace, - TokenKind::Comment => Self::Comment, - - TokenKind::Error => Self::Error, - TokenKind::__LAST => unreachable!(r#"Tried to cast "__LAST": TokenKind to SyntaxKind"#), +impl From for u16 { + #[inline] + fn from(value: SyntaxKind) -> Self { + match value { + SyntaxKind::LexToken(value) => value as u16, + SyntaxKind::SyntaxConstruct(value) => value as u16, } } } -#[cfg(test)] -#[allow(clippy::semicolon_if_nothing_returned)] -#[allow(clippy::needless_pass_by_value)] -mod test { - use strum::IntoEnumIterator; - - use crate::SyntaxKind; - use crate::SyntaxKind::*; - - // Test with full coverage. An error here would be hard to debug - fn to_kw_or_not_to_kw_syntax() -> ([SyntaxKind; 8], Vec) { - let syntax_nodes = [ - Error, - Root, - InfixExpr, - Literal, - ParenExpr, - PrefixExpr, - VariableRef, - VariableDef, - ]; - - let rest = SyntaxKind::iter() - .filter(|x| !syntax_nodes.contains(x)) - .collect(); - - (syntax_nodes, rest) - } - - #[test] - fn full_coverage() { - use strum::IntoEnumIterator; - let (syntax_nodes, non_syntax_nodes) = to_kw_or_not_to_kw_syntax(); - assert_eq!( - syntax_nodes.len() + non_syntax_nodes.len(), - SyntaxKind::iter().count() - ) +impl TryFrom for SyntaxKind { + type Error = &'static str; + + fn try_from(value: u16) -> Result { + if (value as usize) < TokenKind::COUNT { + let v = TokenKind::try_from( + u8::try_from(value).expect("Tried to convert too big an integer into u8."), + ); + v.map(SyntaxKind::LexToken) + .map_err(|_impossible| "Should not exist") + } else { + let v = SyntaxConstruct::try_from(u8::try_from(value).expect("u16 value provided too big to convert to u8. Could not cast into u8 SyntaxConstruct")); + v.map(SyntaxKind::SyntaxConstruct) + .map_err(|_e| "u8 values should correspond to SyntaxConstruct variant. Found error") + } } } diff --git a/docs/graph.svg b/docs/graph.svg index 19e42890bfd825c151571f599d4aa390302bf896..41116459e623cde9be05a2460b9f44bb12e52678 100644 GIT binary patch literal 83458 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

;-n{6Z1ap@ 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 literal 72612 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