fix previous bugs

This commit is contained in:
Daniel Bulant 2022-02-20 20:01:42 +01:00
parent aa33fb90ea
commit e4cfaa54b5
4 changed files with 44 additions and 14 deletions

View file

@ -296,14 +296,14 @@ impl Tree {
let mut contents = Vec::new(); let mut contents = Vec::new();
loop { loop {
let token = self.get_next_token(); let token = self.get_next_token();
dbg!(token); dbg!(token, matches!(token, Tokens::End));
match token { match token {
Tokens::End => break, Tokens::End => break,
Tokens::Space => { self.inc(); },
_ => contents.push(self.get_expression(end).with_context(|| "Error getting contents for while expression")?) _ => contents.push(self.get_expression(end).with_context(|| "Error getting contents for while expression")?)
}; };
dbg!(&contents); dbg!(&contents);
} }
self.inc();
Ok(WhileExpression { condition: Box::new(condition), contents }) Ok(WhileExpression { condition: Box::new(condition), contents })
} }
@ -411,6 +411,7 @@ impl Tree {
Tokens::Space => {self.inc();}, Tokens::Space => {self.inc();},
Tokens::CommandEnd(_) => { if matches!(expr, Some(_)) { break }; self.inc();}, Tokens::CommandEnd(_) => { if matches!(expr, Some(_)) { break }; self.inc();},
Tokens::Literal(_) => if matches!(expr, Some(_)) { Tokens::Literal(_) => if matches!(expr, Some(_)) {
dbg!(expr);
bail!("Unexpected literal. After file redirect, you need to use a semicolon or newline."); bail!("Unexpected literal. After file redirect, you need to use a semicolon or newline.");
} else { } else {
expr = Some(self.parse_call(end)?); expr = Some(self.parse_call(end)?);
@ -492,6 +493,7 @@ impl Tree {
}, },
Tokens::Break => match expr { Tokens::Break => match expr {
None => { None => {
self.inc();
expr = Some(Expression::BreakExpression(BreakExpression { num: Box::new(self.get_value(end)?)})); expr = Some(Expression::BreakExpression(BreakExpression { num: Box::new(self.get_value(end)?)}));
}, },
Some(_) => bail!("Unexpected break") Some(_) => bail!("Unexpected break")

View file

@ -9,9 +9,7 @@ use crate::parser::tokens::{tokenize};
use anyhow::Result; use anyhow::Result;
pub fn exec(reader: &mut dyn std::io::BufRead, ctx: &mut vars::Context) -> Result<()> { pub fn exec(reader: &mut dyn std::io::BufRead, ctx: &mut vars::Context) -> Result<()> {
let tokens = tokenize(reader).unwrap(); let tokens = tokenize(reader)?;
dbg!(&tokens);
let expressions = build_tree(tokens)?; let expressions = build_tree(tokens)?;

View file

@ -1,4 +1,4 @@
use std::io; use anyhow::{Result, bail};
#[derive(Debug)] #[derive(Debug)]
pub enum Tokens { pub enum Tokens {
@ -46,6 +46,8 @@ impl Tokens {
"<" => Tokens::FileRead, "<" => Tokens::FileRead,
"|" => Tokens::RedirectInto, "|" => Tokens::RedirectInto,
"\r\n" | "\n" | ";" => Tokens::CommandEnd(str.chars().nth(0).unwrap()), "\r\n" | "\n" | ";" => Tokens::CommandEnd(str.chars().nth(0).unwrap()),
"&&" => Tokens::And,
"||" => Tokens::Or,
"=" => Tokens::ExportSet, "=" => Tokens::ExportSet,
"break" => Tokens::Break, "break" => Tokens::Break,
_ => Tokens::Literal(str) _ => Tokens::Literal(str)
@ -88,6 +90,7 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
let mut x = i; let mut x = i;
let mut buf = String::new(); let mut buf = String::new();
let parens_mode = text.chars().nth(x + 1).unwrap() == '{'; let parens_mode = text.chars().nth(x + 1).unwrap() == '{';
if parens_mode { x += 1 }
loop { loop {
x += 1; x += 1;
let letter: char = text.chars().nth(x).unwrap(); let letter: char = text.chars().nth(x).unwrap();
@ -106,7 +109,7 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
x += 1; x += 1;
break; break;
} }
_ => { if !parens_mode { break } else { panic!("Invalid variable name") } } l => { if !parens_mode { break } else { panic!("Invalid variable name (starting with '{:?}{:?}')", buf, l) } }
} }
} }
let token = match text.chars().nth(i).unwrap() { let token = match text.chars().nth(i).unwrap() {
@ -117,12 +120,12 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
(x - i - 1, token) (x - i - 1, token)
} }
pub fn tokenize(reader: &mut dyn std::io::BufRead) -> io::Result<Vec<Tokens>> { pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Tokens>> {
let mut quote_active = false; let mut quote_active = false;
let mut double_quote_active = false; let mut double_quote_active = false;
let mut escape_active = false; let mut escape_active = false;
let mut text = String::new(); let mut text = String::new();
reader.read_to_string(&mut text); reader.read_to_string(&mut text)?;
let mut text_length = text.len(); let mut text_length = text.len();
let mut tokens: Vec<Tokens> = Vec::new(); let mut tokens: Vec<Tokens> = Vec::new();
@ -162,13 +165,43 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> io::Result<Vec<Tokens>> {
token = Tokens::ArrayFunction(str.clone()); token = Tokens::ArrayFunction(str.clone());
} }
} }
_ => panic!("Cannot happen") _ => bail!("Cannot happen")
} }
tokens.push(token); tokens.push(token);
skipper = skippers; skipper = skippers;
buf_add = false; buf_add = false;
} }
}, },
';' | '\r' | '\n' => if !escape_active && !quote_active && !double_quote_active {
save_buf(&mut buf, &mut tokens);
tokens.push(Tokens::CommandEnd(letter.clone()));
let mut x = i;
while x < text.len() - 1 && matches!(text.chars().nth(x).unwrap(), '\n' | '\r' | ';' | ' ') {
x += 1;
}
skipper = x - i - 1;
buf_add = false;
},
'&' => if !escape_active && !quote_active && !double_quote_active {
save_buf(&mut buf, &mut tokens);
if i + 1 < text.len() && text.chars().nth(i+1).unwrap() == '&' {
tokens.push(Tokens::And);
skipper = 1;
} else {
tokens.push(Tokens::JobCommandEnd);
}
buf_add = false;
},
'|' => if !escape_active && !quote_active && !double_quote_active {
save_buf(&mut buf, &mut tokens);
if i + 1 < text.len() && text.chars().nth(i+1).unwrap() == '|' {
tokens.push(Tokens::Or);
skipper = 1;
} else {
tokens.push(Tokens::RedirectInto);
}
buf_add = false;
},
' ' => if !escape_active && !quote_active && !double_quote_active { ' ' => if !escape_active && !quote_active && !double_quote_active {
save_buf(&mut buf, &mut tokens); save_buf(&mut buf, &mut tokens);
tokens.push(Tokens::Space); tokens.push(Tokens::Space);
@ -207,9 +240,7 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> io::Result<Vec<Tokens>> {
buf.push(*letter); buf.push(*letter);
} }
} }
if buf.len() > 0 { save_buf(&mut buf, &mut tokens);
tokens.push(Tokens::Literal(buf));
}
Ok(tokens) Ok(tokens)
} }

View file

@ -1,4 +1,3 @@
echo test echo test
echo single; echo line echo single; echo line