|
|
@ -129,7 +129,7 @@ impl<'text> Tokenizer<'text> {
|
|
|
|
_ if next.is_glob() => Some(self.lex_glob(vec![next])),
|
|
|
|
_ if next.is_glob() => Some(self.lex_glob(vec![next])),
|
|
|
|
'@' => Some(self.lex_var(vec![next])),
|
|
|
|
'@' => Some(self.lex_var(vec![next])),
|
|
|
|
'\'' => Some(self.lex_raw_string(vec![next])),
|
|
|
|
'\'' => Some(self.lex_raw_string(vec![next])),
|
|
|
|
'"' => Some(self.lex_interp_string(vec![next])),
|
|
|
|
'"' => Some(self.lex_string_literal(vec![])),
|
|
|
|
';' => Some(Ok(Token::Semi(next))),
|
|
|
|
';' => Some(Ok(Token::Semi(next))),
|
|
|
|
_ => Some(Err(LexError::UnexpectedCharacter(next))),
|
|
|
|
_ => Some(Err(LexError::UnexpectedCharacter(next))),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -188,11 +188,24 @@ impl<'text> Tokenizer<'text> {
|
|
|
|
))
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn lex_interp_string(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
|
|
|
|
fn lex_string_literal(&mut self, mut progress: Vec<Glyph>) -> Result<Token, LexError> {
|
|
|
|
Err(LexError::not_yet(
|
|
|
|
while let Some(next) = self.source.peek() {
|
|
|
|
self.source.next_position,
|
|
|
|
match next.glyph {
|
|
|
|
"interpreted strings not done yet",
|
|
|
|
_ if next.glyph.is_whitespace() => progress.push(self.source.pop()?),
|
|
|
|
))
|
|
|
|
_ if next.is_word() => progress.push(self.source.pop()?),
|
|
|
|
|
|
|
|
_ if next.is_glob() => progress.push(self.source.pop()?),
|
|
|
|
|
|
|
|
'"' => {
|
|
|
|
|
|
|
|
self.source.pop()?;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if progress.is_empty() {
|
|
|
|
|
|
|
|
Err(LexError::UnexpectedEOF(self.source.next_position))
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Ok(Token::Word(progress.into()))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn lex_var(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
|
|
|
|
fn lex_var(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
|
|
|
@ -331,8 +344,6 @@ mod tests {
|
|
|
|
// Single-quoted strings arne't done yet
|
|
|
|
// Single-quoted strings arne't done yet
|
|
|
|
strings: r"echo 'one' two";
|
|
|
|
strings: r"echo 'one' two";
|
|
|
|
|
|
|
|
|
|
|
|
// Single-quoted strings arne't done yet
|
|
|
|
|
|
|
|
double_quoted_strings: r#"echo "one" two"#;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
accept! {
|
|
|
|
accept! {
|
|
|
@ -342,6 +353,11 @@ mod tests {
|
|
|
|
identifier_2 " a" [ word("a") ]
|
|
|
|
identifier_2 " a" [ word("a") ]
|
|
|
|
identifier_3 "a " [ word("a") ]
|
|
|
|
identifier_3 "a " [ word("a") ]
|
|
|
|
identifier_4 " a " [ word("a") ]
|
|
|
|
identifier_4 " a " [ word("a") ]
|
|
|
|
|
|
|
|
double_quoted_strings r#"echo "one" two"# [
|
|
|
|
|
|
|
|
word("echo")
|
|
|
|
|
|
|
|
word("one")
|
|
|
|
|
|
|
|
word("two")
|
|
|
|
|
|
|
|
]
|
|
|
|
file_name "poop.exe" [ word("poop.exe") ]
|
|
|
|
file_name "poop.exe" [ word("poop.exe") ]
|
|
|
|
multi_idents "one two three four " [
|
|
|
|
multi_idents "one two three four " [
|
|
|
|
word("one")
|
|
|
|
word("one")
|
|
|
|