diff --git a/src/eval/force.rs b/src/eval/force.rs index bc3cf08..cf842dd 100644 --- a/src/eval/force.rs +++ b/src/eval/force.rs @@ -142,18 +142,13 @@ impl Elang { res } } - ExprType::Mod { numer, denom, int } => { + ExprType::Mod { numer, denom } => { let numer = num(self, numer)?; let denom_ = num(self, denom)?; if *denom_ == BigRational::zero() { return self.error(denom, ErrorType::DivideByZero).ctx(ctx); } - let res = &*numer % &*denom_; - if int { - res.trunc() - } else { - res - } + &*numer % &*denom_ } ExprType::Neg { val } => (*num(self, val)?).clone().neg(), _ => unreachable!(), @@ -489,7 +484,6 @@ impl Elang { | ExprType::Mod { numer: lhs, denom: rhs, - int: _, } | ExprType::Gt { lhs, rhs } | ExprType::Lt { lhs, rhs } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 4c7045e..95e0021 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -136,19 +136,6 @@ impl Elang { numer, denom ), - ExprType::Mod { - numer, - denom, - int: true, - } => bin!( - |numer, denom| ExprType::Mod { - numer, - denom, - int: true - }, - numer, - denom - ), ExprType::Div { numer, denom, @@ -165,12 +152,10 @@ impl Elang { ExprType::Mod { numer, denom, - int: false, } => bin!( |numer, denom| ExprType::Mod { numer, denom, - int: false }, numer, denom diff --git a/src/lexer.rs b/src/lexer.rs index b0068da..4f0ab2a 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -127,7 +127,6 @@ impl<'a, 'b> Lexer<'a, 'b> { } } - /// fn lex_one_(&mut self, (cur_pos, cur): (u32, u8)) -> Result { // Step 1: Strings if cur == b'"' { @@ -264,7 +263,6 @@ impl<'a, 'b> Lexer<'a, 'b> { keyword!(b"else", Else); keyword!(b"or", Or); keyword!(b"int/", IntSlash); - keyword!(b"int%", IntPercent); if let Some((t, skip)) = tkn { self.chars.skip(skip); diff --git a/src/parser.rs b/src/parser.rs index 9b55e3f..3893d4d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -104,8 +104,7 @@ impl<'a> Parser<'a> { Token::Star => Op::Mul, Token::Slash => Op::Div(false), Token::IntSlash => Op::Div(true), - Token::Percent => Op::Mod(false), - Token::IntPercent => Op::Mod(true), + Token::Percent => Op::Mod, Token::PlusPlus => Op::Concat, Token::QuestionMark => Op::Test, Token::Dot => Op::Select, diff --git a/src/types/op.rs b/src/types/op.rs index 808ac1c..f503f66 100644 --- a/src/types/op.rs +++ b/src/types/op.rs @@ -18,7 +18,7 @@ pub enum Op { Mul, Div(bool), /// `%` - Mod(bool), + Mod, /// Unary minus. The argument is the index of the `!` in the codemap. UnMin(u32), /// `++` @@ -58,7 +58,7 @@ impl Op { Op::Mul => 7, Op::Div(..) => 7, - Op::Mod(..) => 7, + Op::Mod => 7, Op::UnMin(..) => 8, Op::Concat => 9, @@ -85,7 +85,7 @@ impl Op { Op::Sub => true, Op::Mul => true, Op::Div(..) => true, - Op::Mod(..) => true, + Op::Mod => true, Op::UnMin(..) => false, Op::Concat => false, Op::Test => false, diff --git a/src/types/stack.rs b/src/types/stack.rs index cc32759..bd8b90a 100644 --- a/src/types/stack.rs +++ b/src/types/stack.rs @@ -113,20 +113,14 @@ impl Stack { denom, int: true, }, - Op::Mod(true) => |numer, denom| ExprType::Mod { - numer, - denom, - int: true, - }, Op::Div(false) => |numer, denom| ExprType::Div { numer, denom, int: false, }, - Op::Mod(false) => |numer, denom| ExprType::Mod { + Op::Mod => |numer, denom| ExprType::Mod { numer, denom, - int: false, }, Op::Concat => |lhs, rhs| ExprType::Concat { lhs, rhs }, Op::Apl => |func, arg| ExprType::Apl { func, arg }, diff --git a/src/types/token.rs b/src/types/token.rs index b943b36..5ded86d 100644 --- a/src/types/token.rs +++ b/src/types/token.rs @@ -32,7 +32,6 @@ pub enum Token { If, In, Inherit, - IntPercent, IntSlash, LeftAngle, LeftAngleEquals, @@ -60,56 +59,115 @@ pub enum Token { True, } -#[derive(Copy, Clone, Eq, PartialEq, Debug)] +/// The type of a token +/// +/// Identifiers, strings, and numbers carry associated data. The variants of this enum do +/// not carry that data. +/// +/// This type is used for diagnostic purposes only. +#[derive(Copy, Clone, Eq, PartialEq)] pub enum TokenType { + /// `&&` AmpersandAmpersand, + /// `@` At, + /// `\\` BackslashBackslash, + /// `||` BarBar, + /// `:` Colon, + /// `,` Comma, + /// `.` Dot, + /// `..` DotDot, + /// `else` Else, + /// `=` Equals, + /// `==` EqualsEquals, + /// `!` ExclamationMark, + /// `!=` ExclamationMarkEquals, + /// `false` False, + /// An identifier Ident, + /// `if` If, + /// `in` In, + /// `inherit` Inherit, - IntPercent, + /// `int/` IntSlash, + /// `<` LeftAngle, + /// `<=` LeftAngleEquals, + /// `{` LeftBrace, + /// `[` LeftBracket, + /// `(` LeftParen, + /// `let` Let, + /// `-` Minus, + /// `null` Null, + /// A number Number, + /// `or` Or, + /// `%` Percent, + /// `+` Plus, + /// `++` PlusPlus, + /// `?` QuestionMark, + /// `rec` Rec, + /// `>` RightAngle, + /// `>=` RightAngleEquals, + /// `}` RightBrace, + /// `]` RightBracket, + /// `)` RightParen, + /// `/` Slash, + /// `*` Star, + /// A string String, + /// `then` Then, + /// `true` True, } impl TokenType { + /// Returns the textual representation of the token type + /// + /// For symbol-like tokens and keywords, this is simply their representation in source + /// code. For example, `AmpersandAmpersand => "&&"`. + /// + /// There are three special cases: + /// + /// * `Ident => "identifier"`, + /// * `Number => "number"`, + /// * `String => "string"`, pub fn as_str(self) -> &'static str { match self { TokenType::AmpersandAmpersand => "&&", @@ -130,7 +188,6 @@ impl TokenType { TokenType::If => "if", TokenType::Inherit => "inherit", TokenType::In => "in", - TokenType::IntPercent => "int%", TokenType::IntSlash => "int/", TokenType::LeftAngle => "<", TokenType::LeftAngleEquals => "<=", @@ -162,9 +219,7 @@ impl TokenType { } impl Token { - /// Returns whether this token starts an expression. - /// - /// = Remarks + /// Returns whether this token starts an expression /// /// We use this to find out if an expression has just ended. If a token does not start /// an expression, then it combines a subsequent token with the current expression. @@ -180,7 +235,7 @@ impl Token { /// f x + 1 /// ``` /// - /// the `x` (an identifier) starts a new expressiond and this will be parsed as a + /// the `x` (an identifier) starts a new expression and this will be parsed as a /// function application: `f(x + 1)`. pub fn starts_expr(self) -> bool { match self { @@ -233,7 +288,6 @@ impl Token { Token::AmpersandAmpersand => false, Token::BarBar => false, Token::IntSlash => false, - Token::IntPercent => false, } } @@ -257,7 +311,6 @@ impl Token { Token::If => TokenType::If, Token::Inherit => TokenType::Inherit, Token::In => TokenType::In, - Token::IntPercent => TokenType::IntPercent, Token::IntSlash => TokenType::IntSlash, Token::LeftAngleEquals => TokenType::LeftAngleEquals, Token::LeftAngle => TokenType::LeftAngle, @@ -295,3 +348,9 @@ impl Debug for Token { write!(f, "{}", self.ty().as_str()) } } + +impl Debug for TokenType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} diff --git a/src/types/tree.rs b/src/types/tree.rs index e8f7c7c..e5fc732 100644 --- a/src/types/tree.rs +++ b/src/types/tree.rs @@ -115,7 +115,6 @@ pub enum ExprType { Mod { numer: ExprId, denom: ExprId, - int: bool, }, /// `lhs * rhs` Mul { lhs: ExprId, rhs: ExprId }, diff --git a/src/util/graphviz.rs b/src/util/graphviz.rs index 5223bfe..f92b6d0 100644 --- a/src/util/graphviz.rs +++ b/src/util/graphviz.rs @@ -126,11 +126,6 @@ fn print_tree_( denom, int: true, } => binary!("int/", numer, denom), - ExprType::Mod { - numer, - denom, - int: true, - } => binary!("int%", numer, denom), ExprType::Div { numer, denom, @@ -139,7 +134,6 @@ fn print_tree_( ExprType::Mod { numer, denom, - int: false, } => binary!("%", numer, denom), ExprType::Gt { lhs, rhs } => binary!(">", lhs, rhs), ExprType::Lt { lhs, rhs } => binary!("<", lhs, rhs),