mirror of
https://github.com/danbulant/rush
synced 2026-05-19 04:18:35 +00:00
fix previous bugs
This commit is contained in:
parent
aa33fb90ea
commit
e4cfaa54b5
4 changed files with 44 additions and 14 deletions
|
|
@ -296,14 +296,14 @@ impl Tree {
|
|||
let mut contents = Vec::new();
|
||||
loop {
|
||||
let token = self.get_next_token();
|
||||
dbg!(token);
|
||||
dbg!(token, matches!(token, Tokens::End));
|
||||
match token {
|
||||
Tokens::End => break,
|
||||
Tokens::Space => { self.inc(); },
|
||||
_ => contents.push(self.get_expression(end).with_context(|| "Error getting contents for while expression")?)
|
||||
};
|
||||
dbg!(&contents);
|
||||
}
|
||||
self.inc();
|
||||
Ok(WhileExpression { condition: Box::new(condition), contents })
|
||||
}
|
||||
|
||||
|
|
@ -411,6 +411,7 @@ impl Tree {
|
|||
Tokens::Space => {self.inc();},
|
||||
Tokens::CommandEnd(_) => { if matches!(expr, Some(_)) { break }; self.inc();},
|
||||
Tokens::Literal(_) => if matches!(expr, Some(_)) {
|
||||
dbg!(expr);
|
||||
bail!("Unexpected literal. After file redirect, you need to use a semicolon or newline.");
|
||||
} else {
|
||||
expr = Some(self.parse_call(end)?);
|
||||
|
|
@ -492,6 +493,7 @@ impl Tree {
|
|||
},
|
||||
Tokens::Break => match expr {
|
||||
None => {
|
||||
self.inc();
|
||||
expr = Some(Expression::BreakExpression(BreakExpression { num: Box::new(self.get_value(end)?)}));
|
||||
},
|
||||
Some(_) => bail!("Unexpected break")
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ use crate::parser::tokens::{tokenize};
|
|||
use anyhow::Result;
|
||||
|
||||
pub fn exec(reader: &mut dyn std::io::BufRead, ctx: &mut vars::Context) -> Result<()> {
|
||||
let tokens = tokenize(reader).unwrap();
|
||||
|
||||
dbg!(&tokens);
|
||||
let tokens = tokenize(reader)?;
|
||||
|
||||
let expressions = build_tree(tokens)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::io;
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Tokens {
|
||||
|
|
@ -46,6 +46,8 @@ impl Tokens {
|
|||
"<" => Tokens::FileRead,
|
||||
"|" => Tokens::RedirectInto,
|
||||
"\r\n" | "\n" | ";" => Tokens::CommandEnd(str.chars().nth(0).unwrap()),
|
||||
"&&" => Tokens::And,
|
||||
"||" => Tokens::Or,
|
||||
"=" => Tokens::ExportSet,
|
||||
"break" => Tokens::Break,
|
||||
_ => Tokens::Literal(str)
|
||||
|
|
@ -88,6 +90,7 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
|
|||
let mut x = i;
|
||||
let mut buf = String::new();
|
||||
let parens_mode = text.chars().nth(x + 1).unwrap() == '{';
|
||||
if parens_mode { x += 1 }
|
||||
loop {
|
||||
x += 1;
|
||||
let letter: char = text.chars().nth(x).unwrap();
|
||||
|
|
@ -106,7 +109,7 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
|
|||
x += 1;
|
||||
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() {
|
||||
|
|
@ -117,12 +120,12 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Tokens) {
|
|||
(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 double_quote_active = false;
|
||||
let mut escape_active = false;
|
||||
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 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());
|
||||
}
|
||||
}
|
||||
_ => panic!("Cannot happen")
|
||||
_ => bail!("Cannot happen")
|
||||
}
|
||||
tokens.push(token);
|
||||
skipper = skippers;
|
||||
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 {
|
||||
save_buf(&mut buf, &mut tokens);
|
||||
tokens.push(Tokens::Space);
|
||||
|
|
@ -207,9 +240,7 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> io::Result<Vec<Tokens>> {
|
|||
buf.push(*letter);
|
||||
}
|
||||
}
|
||||
if buf.len() > 0 {
|
||||
tokens.push(Tokens::Literal(buf));
|
||||
}
|
||||
save_buf(&mut buf, &mut tokens);
|
||||
|
||||
Ok(tokens)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
echo test
|
||||
|
||||
echo single; echo line
|
||||
|
|
|
|||
Loading…
Reference in a new issue