Added Integer Literal Parser
1. Added Integer Literal Parser 2. Removed Unused imports. 3. Fixed issues reported by Clippy
This commit is contained in:
parent
2863ad8aa4
commit
631c2d8b1a
|
@ -263,7 +263,7 @@ fn lookup_ident(ident: &str) -> Token {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Lexer, Literal, Token, TokenType};
|
use super::{Lexer, Token, TokenType};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl Let {
|
||||||
}
|
}
|
||||||
|
|
||||||
let literal = String::try_from(parser.current_token.clone().unwrap().value.unwrap())?;
|
let literal = String::try_from(parser.current_token.clone().unwrap().value.unwrap())?;
|
||||||
let name = Identifier::new(Token::new(TokenType::Let), &literal);
|
let name = Identifier::new(Token::new(TokenType::Let), literal.into());
|
||||||
|
|
||||||
if !parser.expect_peek(Token::new(TokenType::Assign)) {
|
if !parser.expect_peek(Token::new(TokenType::Assign)) {
|
||||||
return Err(ParseError::new("expected =, Could not find it"));
|
return Err(ParseError::new("expected =, Could not find it"));
|
||||||
|
@ -58,8 +58,8 @@ impl Return {
|
||||||
Return {
|
Return {
|
||||||
return_value: Expression::Ident(Identifier::new(
|
return_value: Expression::Ident(Identifier::new(
|
||||||
Token::new(TokenType::Return),
|
Token::new(TokenType::Return),
|
||||||
"return",
|
"return".into(),
|
||||||
)), //TODO FIX THIS
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,10 @@ impl Return {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Identifier is used to represent variable names and other user created identifiers.
|
||||||
|
// `Literal` can be an int as well. So, Identifier can be a Integer Literal
|
||||||
|
// The wording sounds a little confusing, maybe?
|
||||||
|
// TODO: possible @refactor
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Identifier {
|
pub struct Identifier {
|
||||||
name: Token,
|
name: Token,
|
||||||
|
@ -79,11 +83,8 @@ pub struct Identifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
pub fn new(token: Token, name: &str) -> Identifier {
|
pub fn new(name: Token, value: Literal) -> Identifier {
|
||||||
Identifier {
|
Identifier { name, value }
|
||||||
name: token,
|
|
||||||
value: name.into(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ impl<'a> Parser<'a> {
|
||||||
prefix_parse_fns,
|
prefix_parse_fns,
|
||||||
};
|
};
|
||||||
parser.register_prefix_fn(TokenType::Ident, Parser::parse_identifier);
|
parser.register_prefix_fn(TokenType::Ident, Parser::parse_identifier);
|
||||||
|
parser.register_prefix_fn(TokenType::Int, Parser::parse_integer_literal);
|
||||||
parser
|
parser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +60,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expression(&mut self, priority: ExpressionPriority) -> Result<Expression, ParseError> {
|
fn parse_expression(
|
||||||
|
&mut self,
|
||||||
|
_priority: ExpressionPriority,
|
||||||
|
) -> Result<Expression, ParseError> {
|
||||||
let current_token = if let Some(token) = &self.current_token {
|
let current_token = if let Some(token) = &self.current_token {
|
||||||
token
|
token
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,7 +87,16 @@ impl<'a> Parser<'a> {
|
||||||
let ct = parser.current_token.clone().unwrap();
|
let ct = parser.current_token.clone().unwrap();
|
||||||
Ok(Expression::Ident(Identifier::new(
|
Ok(Expression::Ident(Identifier::new(
|
||||||
ct.clone(), // TODO: Correction needed, Can be a source of subtle error in some cases
|
ct.clone(), // TODO: Correction needed, Can be a source of subtle error in some cases
|
||||||
&String::try_from(ct.value.unwrap())?,
|
String::try_from(ct.value.unwrap())?.into(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_integer_literal(parser: &mut Parser) -> Result<Expression, ParseError> {
|
||||||
|
let v = parser.current_token.clone().unwrap();
|
||||||
|
|
||||||
|
Ok(Expression::Ident(Identifier::new(
|
||||||
|
v.clone(),
|
||||||
|
v.value.unwrap(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ mod tests {
|
||||||
let expected_out = Program {
|
let expected_out = Program {
|
||||||
statements: vec![
|
statements: vec![
|
||||||
Statement::Let(Let::new(
|
Statement::Let(Let::new(
|
||||||
Identifier::new(Token::new(TokenType::Let), "yr"),
|
Identifier::new(Token::new(TokenType::Let), "yr".into()),
|
||||||
None
|
None
|
||||||
// Some(Expression::Ident(Identifier::new(
|
// Some(Expression::Ident(Identifier::new(
|
||||||
// Token::new(TokenType::Let),
|
// Token::new(TokenType::Let),
|
||||||
|
@ -54,7 +54,7 @@ mod tests {
|
||||||
// ))),
|
// ))),
|
||||||
)),
|
)),
|
||||||
Statement::Let(Let::new(
|
Statement::Let(Let::new(
|
||||||
Identifier::new(Token::new(TokenType::Let), "qq"),
|
Identifier::new(Token::new(TokenType::Let), "qq".into()),
|
||||||
None
|
None
|
||||||
// Some(Expression::Ident(Identifier::new(
|
// Some(Expression::Ident(Identifier::new(
|
||||||
// Token::new(TokenType::Let),
|
// Token::new(TokenType::Let),
|
||||||
|
@ -62,7 +62,7 @@ mod tests {
|
||||||
// ))),
|
// ))),
|
||||||
)),
|
)),
|
||||||
Statement::Let(Let::new(
|
Statement::Let(Let::new(
|
||||||
Identifier::new(Token::new(TokenType::Let), "foobar"),
|
Identifier::new(Token::new(TokenType::Let), "foobar".into()),
|
||||||
None
|
None
|
||||||
// Some(Expression::Ident(Identifier::new(
|
// Some(Expression::Ident(Identifier::new(
|
||||||
// Token::new(TokenType::Let),
|
// Token::new(TokenType::Let),
|
||||||
|
@ -103,7 +103,7 @@ mod tests {
|
||||||
Some(Token::with_value(TokenType::Ident, "foobar".into())),
|
Some(Token::with_value(TokenType::Ident, "foobar".into())),
|
||||||
Expression::Ident(Identifier::new(
|
Expression::Ident(Identifier::new(
|
||||||
Token::with_value(TokenType::Ident, "foobar".into()),
|
Token::with_value(TokenType::Ident, "foobar".into()),
|
||||||
"foobar",
|
"foobar".into(),
|
||||||
)),
|
)),
|
||||||
))],
|
))],
|
||||||
};
|
};
|
||||||
|
@ -112,4 +112,24 @@ mod tests {
|
||||||
assert_eq!(as_tree.statements.len(), 1);
|
assert_eq!(as_tree.statements.len(), 1);
|
||||||
assert_eq!(as_tree, expected_out);
|
assert_eq!(as_tree, expected_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn integer_literal_expression() {
|
||||||
|
let ip = "5;";
|
||||||
|
|
||||||
|
let lexer = Lexer::new(ip);
|
||||||
|
let as_tree = Program::parse(lexer);
|
||||||
|
let expected_out = Program {
|
||||||
|
statements: vec![Statement::ExpressionStatement(ExpressionStatement::new(
|
||||||
|
Some(Token::with_value(TokenType::Int, 5.into())),
|
||||||
|
Expression::Ident(Identifier::new(
|
||||||
|
Token::with_value(TokenType::Int, 5.into()),
|
||||||
|
5.into(),
|
||||||
|
)),
|
||||||
|
))],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(as_tree.statements.len(), 1);
|
||||||
|
assert_eq!(as_tree, expected_out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user