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> { fn parse_number(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
if let Some(LocatedToken { tokens.one_of(vec![
token: Token::Number(number), |t| {
.. if let Some(LocatedToken {
}) = tokens.next_if(&Token::Number(0)) token: Token::Int(number),
{ ..
Ok(Some(ast::Expr::Value(ast::Value::Int(number.into())))) }) = t.next_if(&Token::Int(0))
} else { {
Ok(None) 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> { fn parse_identifier(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
@ -441,7 +456,7 @@ mod tests {
} }
#[test] #[test]
fn if_then() { 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); let result = parse(&mut scan(program), parse_expr);
insta::assert_debug_snapshot!(result); insta::assert_debug_snapshot!(result);
} }

View file

@ -339,11 +339,37 @@ fn lex_number(scanner: &mut Scanner, start: Pos, c: &char) -> LocatedToken {
break; break;
} }
} }
let i = str.parse::<i32>().unwrap(); if let Some(ch) = scanner.peek()
LocatedToken { && *ch == '.'
start, {
end: scanner.cursor(), scanner.pop();
token: Token::Number(i), 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( condition: Not(
Op { Op {
lhs: Value( lhs: Value(
Int( Float(
3, 3.23,
), ),
), ),
op: Compare( op: Compare(
Lt, Lt,
), ),
rhs: Value( rhs: Value(
Int( Float(
2, 2.34,
), ),
), ),
}, },

View file

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

View file

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

View file

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