floats
This commit is contained in:
parent
e29b8e1620
commit
d959cd9e21
6 changed files with 74 additions and 31 deletions
|
|
@ -334,15 +334,30 @@ fn parse_string(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
|||
}
|
||||
|
||||
fn parse_number(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||
tokens.one_of(vec![
|
||||
|t| {
|
||||
if let Some(LocatedToken {
|
||||
token: Token::Number(number),
|
||||
token: Token::Int(number),
|
||||
..
|
||||
}) = tokens.next_if(&Token::Number(0))
|
||||
}) = 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -339,11 +339,37 @@ fn lex_number(scanner: &mut Scanner, start: Pos, c: &char) -> LocatedToken {
|
|||
break;
|
||||
}
|
||||
}
|
||||
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::Number(i),
|
||||
token: Token::Int(i),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ expression: result
|
|||
"x",
|
||||
),
|
||||
Equals,
|
||||
Number(
|
||||
Int(
|
||||
108,
|
||||
),
|
||||
Semicolon,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue