This commit is contained in:
me 2025-12-20 15:43:52 +02:00
parent e29b8e1620
commit d959cd9e21
6 changed files with 74 additions and 31 deletions

View file

@ -334,15 +334,30 @@ fn parse_string(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
}
fn parse_number(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
if let Some(LocatedToken {
token: Token::Number(number),
..
}) = tokens.next_if(&Token::Number(0))
{
Ok(Some(ast::Expr::Value(ast::Value::Int(number.into()))))
} else {
Ok(None)
}
tokens.one_of(vec![
|t| {
if let Some(LocatedToken {
token: Token::Int(number),
..
}) = t.next_if(&Token::Int(0))
{
Ok(Some(ast::Expr::Value(ast::Value::Int(number.into()))))
} else {
Ok(None)
}
},
|t| {
if let Some(LocatedToken {
token: Token::Float(number),
..
}) = t.next_if(&Token::Float(0.0))
{
Ok(Some(ast::Expr::Value(ast::Value::Float(number.into()))))
} else {
Ok(None)
}
},
])
}
fn parse_identifier(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
@ -441,7 +456,7 @@ mod tests {
}
#[test]
fn if_then() {
let program = "if !(3 < 2) { \"Hello\" }".to_string();
let program = "if !(3.23 < 2.34) { \"Hello\" }".to_string();
let result = parse(&mut scan(program), parse_expr);
insta::assert_debug_snapshot!(result);
}

View file

@ -339,11 +339,37 @@ fn lex_number(scanner: &mut Scanner, start: Pos, c: &char) -> LocatedToken {
break;
}
}
let i = str.parse::<i32>().unwrap();
LocatedToken {
start,
end: scanner.cursor(),
token: Token::Number(i),
if let Some(ch) = scanner.peek()
&& *ch == '.'
{
scanner.pop();
str.push('.');
loop {
if let Some(ch) = scanner.peek()
&& !ch.is_numeric()
{
break;
}
if let Some(ch) = scanner.pop() {
str.push(*ch);
} else {
break;
}
}
let i = str.parse::<f32>().unwrap();
LocatedToken {
start,
end: scanner.cursor(),
token: Token::Float(i),
}
} else {
let i = str.parse::<i32>().unwrap();
LocatedToken {
start,
end: scanner.cursor(),
token: Token::Int(i),
}
}
}

View file

@ -7,16 +7,16 @@ Ok(
condition: Not(
Op {
lhs: Value(
Int(
3,
Float(
3.23,
),
),
op: Compare(
Lt,
),
rhs: Value(
Int(
2,
Float(
2.34,
),
),
},

View file

@ -8,7 +8,7 @@ expression: result
"x",
),
Equals,
Number(
Int(
108,
),
Semicolon,

View file

@ -28,7 +28,7 @@ expression: result
"x",
),
Colon,
Number(
Int(
10,
),
Comma,
@ -36,7 +36,7 @@ expression: result
"y",
),
Colon,
Number(
Int(
20,
),
CloseCurly,
@ -93,15 +93,15 @@ expression: result
"clear",
),
OpenParen,
Number(
Int(
0,
),
Comma,
Number(
Int(
0,
),
Comma,
Number(
Int(
0,
),
CloseParen,

View file

@ -1,4 +1,4 @@
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub struct LocatedToken {
pub start: Pos,
pub end: Pos,
@ -16,7 +16,7 @@ impl std::fmt::Display for Pos {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Token {
Let,
Fn,
@ -38,7 +38,8 @@ pub enum Token {
Equals,
Not,
Op(Op),
Number(i32),
Int(i32),
Float(f32),
String(String),
Identifier(String),
Label(String),
@ -63,7 +64,7 @@ pub enum Op {
BinOr,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub struct Tokens(pub Vec<LocatedToken>);
impl From<Vec<LocatedToken>> for Tokens {
@ -88,7 +89,8 @@ impl Tokens {
let t = self.0.pop_if(|t| match (t.token.clone(), token) {
(a, b) if a == *b => true,
(Token::Identifier(_), Token::Identifier(_)) => true,
(Token::Number(_), Token::Number(_)) => true,
(Token::Int(_), Token::Int(_)) => true,
(Token::Float(_), Token::Float(_)) => true,
(Token::String(_), Token::String(_)) => true,
(Token::Label(_), Token::Label(_)) => true,
(Token::Op(_), Token::Op(_)) => true,
@ -176,7 +178,7 @@ impl Tokens {
pub type Parser<T> = fn(&mut Tokens) -> ParseResult<T>;
pub type ParseResult<T> = Result<Option<T>, Error>;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
UnexpectedToken {
expected: Token,