Lex strings and string concatenation
This commit is contained in:
parent
f5e822e916
commit
097b09b6e3
@ -108,6 +108,8 @@ impl<'a> Lexer<'a> {
|
|||||||
match c {
|
match c {
|
||||||
'0'..='9' => self.lex_number()?,
|
'0'..='9' => self.lex_number()?,
|
||||||
'a'..='z' | 'A'..='Z' => self.lex_alphabetical()?,
|
'a'..='z' | 'A'..='Z' => self.lex_alphabetical()?,
|
||||||
|
'"' => self.lex_string('"')?,
|
||||||
|
'\'' => self.lex_string('\'')?,
|
||||||
'+' => {
|
'+' => {
|
||||||
self.position += 1;
|
self.position += 1;
|
||||||
(Token::Plus, (self.position - 1, self.position))
|
(Token::Plus, (self.position - 1, self.position))
|
||||||
@ -253,6 +255,27 @@ impl<'a> Lexer<'a> {
|
|||||||
|
|
||||||
Ok((token, (start_pos, self.position)))
|
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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -277,6 +300,34 @@ impl From<ParseIntError> for LexError {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn r#true() {
|
fn r#true() {
|
||||||
let input = "true";
|
let input = "true";
|
||||||
|
@ -14,6 +14,7 @@ pub enum Token {
|
|||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Integer(i64),
|
Integer(i64),
|
||||||
|
String(String),
|
||||||
|
|
||||||
// Keywords
|
// Keywords
|
||||||
IsEven,
|
IsEven,
|
||||||
@ -40,6 +41,7 @@ impl Display for Token {
|
|||||||
Token::Boolean(boolean) => write!(f, "{boolean}"),
|
Token::Boolean(boolean) => write!(f, "{boolean}"),
|
||||||
Token::Float(float) => write!(f, "{float}"),
|
Token::Float(float) => write!(f, "{float}"),
|
||||||
Token::Integer(integer) => write!(f, "{integer}"),
|
Token::Integer(integer) => write!(f, "{integer}"),
|
||||||
|
Token::String(string) => write!(f, "{string}"),
|
||||||
Token::IsEven => write!(f, "is_even"),
|
Token::IsEven => write!(f, "is_even"),
|
||||||
Token::IsOdd => write!(f, "is_odd"),
|
Token::IsOdd => write!(f, "is_odd"),
|
||||||
Token::Length => write!(f, "length"),
|
Token::Length => write!(f, "length"),
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use std.io
|
write_line("Hello, world!")
|
||||||
|
write_line("Enter your name...")
|
||||||
|
|
||||||
io.write_line("Hello, world!")
|
name = read_line()
|
||||||
io.write_line("Enter your name...")
|
|
||||||
|
|
||||||
message = io.read_line()
|
write_line("Hello " + name + "!")
|
||||||
|
|
||||||
io.write_line("Hello " + message + "!")
|
|
||||||
|
Loading…
Reference in New Issue
Block a user