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> {
|
fn parse_number(tokens: &mut Tokens) -> ParseResult<ast::Expr> {
|
||||||
|
tokens.one_of(vec![
|
||||||
|
|t| {
|
||||||
if let Some(LocatedToken {
|
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()))))
|
Ok(Some(ast::Expr::Value(ast::Value::Int(number.into()))))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,11 +339,37 @@ fn lex_number(scanner: &mut Scanner, start: Pos, c: &char) -> LocatedToken {
|
||||||
break;
|
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();
|
let i = str.parse::<i32>().unwrap();
|
||||||
LocatedToken {
|
LocatedToken {
|
||||||
start,
|
start,
|
||||||
end: scanner.cursor(),
|
end: scanner.cursor(),
|
||||||
token: Token::Number(i),
|
token: Token::Int(i),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ expression: result
|
||||||
"x",
|
"x",
|
||||||
),
|
),
|
||||||
Equals,
|
Equals,
|
||||||
Number(
|
Int(
|
||||||
108,
|
108,
|
||||||
),
|
),
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue