mirror of
https://github.com/danbulant/rush
synced 2026-05-27 05:52:09 +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();
|
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")
|
||||||
|
|
|
||||||
|
|
@ -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)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
echo test
|
echo test
|
||||||
|
|
||||||
echo single; echo line
|
echo single; echo line
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue