diff --git a/src/lexer.rs b/src/lexer.rs index 0001b7e..b47ab52 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -6,6 +6,10 @@ use std::fmt::{Display, Formatter, Result as FmtResult}; #[rustfmt::skip] #[derive(Logos, Clone, Copy, Debug, PartialEq)] +#[logos(subpattern decimal = r"[0-9][_'0-9]*")] +#[logos(subpattern hex = r"[0-9a-fA-F][_'0-9a-fA-F]*")] +#[logos(subpattern octal = r"[0-7][_'0-7]*")] +#[logos(subpattern binary = r"[01][_'01]*")] pub enum Token { // keywords #[token("struct")] Struct, @@ -61,18 +65,23 @@ pub enum Token { #[regex(r"[a-zA-Z_][a-zA-Z0-9_]*")] Identifier, - #[regex(r"0b_*[01][_'01]*")] + #[regex(r"0[bB](?&binary)")] BinaryInteger, - #[regex(r"0o_*[0-7][_'0-7]*")] + #[regex(r"0[oO](?&octal)")] OctalInteger, - #[regex(r"0x_*[0-9a-fA-F][_'0-9a-fA-F]*")] + #[regex(r"0[xX](?&hex)")] HexInteger, - #[regex(r"-?[0-9][_'0-9]*")] + // TODO this has a higher priority because the DecimalFloat regex matches + // even without a . (please help me I don't know regex) + #[regex(r"(?&decimal)", priority=2)] DecimalInteger, + #[regex(r"([0-9]+([.][0-9]*)?|[.][0-9]+)")] + DecimalFloat, + #[regex(r"//[^\n]*", logos::skip)] SingleLineComment, diff --git a/src/parse.rs b/src/parse.rs index ee65e2a..b3cd9d1 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -368,6 +368,7 @@ impl<'a> Expr<'a> { Token::OctalInteger => Self::Literal(Literal::OctalInteger(lexer.slice())), Token::HexInteger => Self::Literal(Literal::HexInteger(lexer.slice())), Token::DecimalInteger => Self::Literal(Literal::DecimalInteger(lexer.slice())), + Token::DecimalFloat => Self::Literal(Literal::DecimalFloat(lexer.slice())), Token::True => Self::Literal(Literal::Boolean(true)), Token::False => Self::Literal(Literal::Boolean(false)), Token::Semicolon | Token::BraceClose | Token::ParanClose => return (None, tok), @@ -475,6 +476,7 @@ pub enum Literal<'a> { OctalInteger(&'a str), HexInteger(&'a str), DecimalInteger(&'a str), + DecimalFloat(&'a str), Boolean(bool), } @@ -572,6 +574,11 @@ mod tests { parse_expr("0b1 + 0x2 - 0o3 * 0x4;"); } + #[test] + fn float_literals() { + parse_expr("0.1 + .1 * 1.;"); + } + #[test] fn locals() { parse_expr("local1 + local2 - local3;");