From 097b09b6e3b76ac31fd990eb7a346caeb6f0d373 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 8 Aug 2024 13:08:53 -0400 Subject: [PATCH] Lex strings and string concatenation --- dust-lang/src/lex.rs | 51 ++++++++++++++++++++++++++++++++++++ dust-lang/src/token.rs | 2 ++ dust_examples/hello_world.ds | 10 +++---- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/dust-lang/src/lex.rs b/dust-lang/src/lex.rs index 2ec2f94..8e871e8 100644 --- a/dust-lang/src/lex.rs +++ b/dust-lang/src/lex.rs @@ -108,6 +108,8 @@ impl<'a> Lexer<'a> { match c { '0'..='9' => self.lex_number()?, 'a'..='z' | 'A'..='Z' => self.lex_alphabetical()?, + '"' => self.lex_string('"')?, + '\'' => self.lex_string('\'')?, '+' => { self.position += 1; (Token::Plus, (self.position - 1, self.position)) @@ -253,6 +255,27 @@ impl<'a> Lexer<'a> { Ok((token, (start_pos, self.position))) } + + fn lex_string(&mut self, delimiter: char) -> Result<(Token, Span), LexError> { + let start_pos = self.position; + + self.next_char(); + + while let Some(c) = self.peek_char() { + if c == delimiter { + self.next_char(); + break; + } else { + self.next_char(); + } + } + + let string = &self.source[start_pos + 1..self.position - 1]; + Ok(( + Token::String(string.to_string()), + (start_pos, self.position), + )) + } } #[derive(Debug, PartialEq, Clone)] @@ -277,6 +300,34 @@ impl From for LexError { mod tests { use super::*; + #[test] + fn string_concatenation() { + let input = "'Hello, ' + 'world!'"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::String("Hello, ".to_string()), (0, 9)), + (Token::Plus, (10, 11)), + (Token::String("world!".to_string()), (12, 20)), + (Token::Eof, (20, 20)), + ]) + ) + } + + #[test] + fn string() { + let input = "'Hello, world!'"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::String("Hello, world!".to_string()), (0, 15)), + (Token::Eof, (15, 15)), + ]) + ) + } + #[test] fn r#true() { let input = "true"; diff --git a/dust-lang/src/token.rs b/dust-lang/src/token.rs index 5b44181..f27c79e 100644 --- a/dust-lang/src/token.rs +++ b/dust-lang/src/token.rs @@ -14,6 +14,7 @@ pub enum Token { Boolean(bool), Float(f64), Integer(i64), + String(String), // Keywords IsEven, @@ -40,6 +41,7 @@ impl Display for Token { Token::Boolean(boolean) => write!(f, "{boolean}"), Token::Float(float) => write!(f, "{float}"), Token::Integer(integer) => write!(f, "{integer}"), + Token::String(string) => write!(f, "{string}"), Token::IsEven => write!(f, "is_even"), Token::IsOdd => write!(f, "is_odd"), Token::Length => write!(f, "length"), diff --git a/dust_examples/hello_world.ds b/dust_examples/hello_world.ds index 3bab54d..85167e5 100644 --- a/dust_examples/hello_world.ds +++ b/dust_examples/hello_world.ds @@ -1,8 +1,6 @@ -use std.io +write_line("Hello, world!") +write_line("Enter your name...") -io.write_line("Hello, world!") -io.write_line("Enter your name...") +name = read_line() -message = io.read_line() - -io.write_line("Hello " + message + "!") +write_line("Hello " + name + "!")