Added Integer Literal Parser

1. Added Integer Literal Parser
2. Removed Unused imports.
3. Fixed issues reported by Clippy
This commit is contained in:
Ishan Jain 2019-09-13 01:08:09 +05:30
parent 2863ad8aa4
commit 631c2d8b1a
4 changed files with 49 additions and 15 deletions

View File

@ -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]

View File

@ -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(),
}
} }
} }

View File

@ -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(),
))) )))
} }

View File

@ -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);
}
} }