diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs index 836046f..ce22cfb 100644 --- a/src/lexer/mod.rs +++ b/src/lexer/mod.rs @@ -263,7 +263,7 @@ fn lookup_ident(ident: &str) -> Token { #[cfg(test)] mod tests { - use super::{Lexer, Literal, Token, TokenType}; + use super::{Lexer, Token, TokenType}; use std::collections::HashMap; #[test] diff --git a/src/parser/ast/mod.rs b/src/parser/ast/mod.rs index 5e89ae5..74ed96c 100644 --- a/src/parser/ast/mod.rs +++ b/src/parser/ast/mod.rs @@ -33,7 +33,7 @@ impl Let { } 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)) { return Err(ParseError::new("expected =, Could not find it")); @@ -58,8 +58,8 @@ impl Return { Return { return_value: Expression::Ident(Identifier::new( Token::new(TokenType::Return), - "return", - )), //TODO FIX THIS + "return".into(), + )), } } @@ -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)] pub struct Identifier { name: Token, @@ -79,11 +83,8 @@ pub struct Identifier { } impl Identifier { - pub fn new(token: Token, name: &str) -> Identifier { - Identifier { - name: token, - value: name.into(), - } + pub fn new(name: Token, value: Literal) -> Identifier { + Identifier { name, value } } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 21d4d03..5cb1f0a 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -39,6 +39,7 @@ impl<'a> Parser<'a> { prefix_parse_fns, }; parser.register_prefix_fn(TokenType::Ident, Parser::parse_identifier); + parser.register_prefix_fn(TokenType::Int, Parser::parse_integer_literal); parser } @@ -59,7 +60,10 @@ impl<'a> Parser<'a> { } } - fn parse_expression(&mut self, priority: ExpressionPriority) -> Result { + fn parse_expression( + &mut self, + _priority: ExpressionPriority, + ) -> Result { let current_token = if let Some(token) = &self.current_token { token } else { @@ -83,7 +87,16 @@ impl<'a> Parser<'a> { let ct = parser.current_token.clone().unwrap(); Ok(Expression::Ident(Identifier::new( 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 { + let v = parser.current_token.clone().unwrap(); + + Ok(Expression::Ident(Identifier::new( + v.clone(), + v.value.unwrap(), ))) } diff --git a/src/parser/program.rs b/src/parser/program.rs index 87bcdaf..7e361a3 100644 --- a/src/parser/program.rs +++ b/src/parser/program.rs @@ -46,7 +46,7 @@ mod tests { let expected_out = Program { statements: vec![ Statement::Let(Let::new( - Identifier::new(Token::new(TokenType::Let), "yr"), + Identifier::new(Token::new(TokenType::Let), "yr".into()), None // Some(Expression::Ident(Identifier::new( // Token::new(TokenType::Let), @@ -54,7 +54,7 @@ mod tests { // ))), )), Statement::Let(Let::new( - Identifier::new(Token::new(TokenType::Let), "qq"), + Identifier::new(Token::new(TokenType::Let), "qq".into()), None // Some(Expression::Ident(Identifier::new( // Token::new(TokenType::Let), @@ -62,7 +62,7 @@ mod tests { // ))), )), Statement::Let(Let::new( - Identifier::new(Token::new(TokenType::Let), "foobar"), + Identifier::new(Token::new(TokenType::Let), "foobar".into()), None // Some(Expression::Ident(Identifier::new( // Token::new(TokenType::Let), @@ -103,7 +103,7 @@ mod tests { Some(Token::with_value(TokenType::Ident, "foobar".into())), Expression::Ident(Identifier::new( 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, 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); + } }