mirror of
https://github.com/danbulant/rush
synced 2026-06-06 00:01:45 +00:00
refactor: first part of moving to results
This commit is contained in:
parent
a4fc18f8fe
commit
e8b943a8d5
2 changed files with 95 additions and 5 deletions
|
|
@ -294,12 +294,15 @@ impl Tree {
|
||||||
Tokens::StringFunction(_) => panic!("Unexpected string function"),
|
Tokens::StringFunction(_) => panic!("Unexpected string function"),
|
||||||
Tokens::ParenthesisStart => panic!("Parenthesis not yet implemented"),
|
Tokens::ParenthesisStart => panic!("Parenthesis not yet implemented"),
|
||||||
Tokens::SubStart => {
|
Tokens::SubStart => {
|
||||||
let mut len = 1;
|
let mut len = 0;
|
||||||
let mut lvl = 1;
|
let mut lvl = 1;
|
||||||
self.inc();
|
self.inc();
|
||||||
for token in &self.tokens[self.i..] {
|
for token in &self.tokens[self.i..] {
|
||||||
match token {
|
match token {
|
||||||
Tokens::SubStart => lvl += 1,
|
Tokens::SubStart => lvl += 1,
|
||||||
|
Tokens::StringFunction(_) => lvl += 1,
|
||||||
|
Tokens::ArrayFunction(_) => lvl += 1,
|
||||||
|
Tokens::ParenthesisStart => lvl += 1,
|
||||||
Tokens::ParenthesisEnd => lvl -= 1,
|
Tokens::ParenthesisEnd => lvl -= 1,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -312,9 +315,13 @@ impl Tree {
|
||||||
}
|
}
|
||||||
// self.inc();
|
// self.inc();
|
||||||
if lvl != 0 {
|
if lvl != 0 {
|
||||||
panic!("Sub not ended properly");
|
panic!("Parenthesis do not match");
|
||||||
}
|
}
|
||||||
return Value::Expressions(self.parse_sub(self.i + len));
|
dbg!(&self, len);
|
||||||
|
let val = Value::Expressions(self.parse_sub(self.i + len));
|
||||||
|
self.inc();
|
||||||
|
dbg!(self);
|
||||||
|
return val;
|
||||||
},
|
},
|
||||||
Tokens::Else => buf.push(Value::Literal(token.to_str())),
|
Tokens::Else => buf.push(Value::Literal(token.to_str())),
|
||||||
Tokens::End => buf.push(Value::Literal(token.to_str())),
|
Tokens::End => buf.push(Value::Literal(token.to_str())),
|
||||||
|
|
@ -361,7 +368,7 @@ impl Tree {
|
||||||
} else {
|
} else {
|
||||||
expr = Some(self.parse_call(end));
|
expr = Some(self.parse_call(end));
|
||||||
},
|
},
|
||||||
Tokens::ExportSet => panic!("Unexpected token EXPORT_SET (=)"),
|
Tokens::ExportSet => panic!("Unexpected token EXPORT SET (=)"),
|
||||||
Tokens::Function => return Expression::Function(self.parse_function(end)),
|
Tokens::Function => return Expression::Function(self.parse_function(end)),
|
||||||
Tokens::FileRead => expr = Some(self.parse_read(expr, end)),
|
Tokens::FileRead => expr = Some(self.parse_read(expr, end)),
|
||||||
Tokens::FileWrite => expr = Some(self.parse_write(expr, end)),
|
Tokens::FileWrite => expr = Some(self.parse_write(expr, end)),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Child, Command, Stdio};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use crate::parser::ast::{AndExpression, CommandValue, Expression, FileSourceExpression, FileTargetExpression, LetExpression, OrExpression, RedirectTargetExpression, Value};
|
use crate::parser::ast::{AndExpression, CommandValue, Expression, FileSourceExpression, FileTargetExpression, LetExpression, OrExpression, RedirectTargetExpression, Value};
|
||||||
|
|
@ -15,6 +15,89 @@ trait GetValue {
|
||||||
fn get(self, ctx: &mut vars::Context) -> Variable;
|
fn get(self, ctx: &mut vars::Context) -> Variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ExecResult {
|
||||||
|
cmd: Option<Command>,
|
||||||
|
child: Option<Child>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecResult {
|
||||||
|
fn new(cmd: Option<Command>, child: Option<Child>) -> Self {
|
||||||
|
Self { cmd, child }
|
||||||
|
}
|
||||||
|
/// Spawns the result, running the command (if any). Non-command results won't be spawned (like let statements)
|
||||||
|
fn spawn(&mut self) -> &mut Self {
|
||||||
|
if !self.started() {
|
||||||
|
match &mut self.cmd {
|
||||||
|
None => {},
|
||||||
|
Some(cmd) => {
|
||||||
|
self.child = Some(cmd.spawn().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Checks if the result was spawned before by checking the child property. Non-command results won't ever be spawned (like let statements)
|
||||||
|
fn started(&self) -> bool {
|
||||||
|
matches!(self.child, Some(_))
|
||||||
|
}
|
||||||
|
/// A simple wrapper for redirecting current result (self) into STDIO (files or streams).
|
||||||
|
///
|
||||||
|
/// Does spawn the current result
|
||||||
|
fn redirect_into<T: std::io::Write>(mut self, into: &mut T) -> &mut T {
|
||||||
|
match &mut self.cmd {
|
||||||
|
None => {},
|
||||||
|
Some(cmd) => {
|
||||||
|
cmd.stdout(Stdio::piped());
|
||||||
|
self.spawn();
|
||||||
|
let child = self.child.unwrap();
|
||||||
|
let mut stdout = child.stdout.unwrap();
|
||||||
|
io::copy(&mut stdout, into);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
into
|
||||||
|
}
|
||||||
|
/// A shorthand for redirecting current result into the next one
|
||||||
|
///
|
||||||
|
/// Uses `redirect_from_result` of the next result. Spawns this result, but not the next one.
|
||||||
|
fn redirect_into_result(&mut self, into: &mut ExecResult) -> &mut Self {
|
||||||
|
into.redirect_from_result(self);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// Redirects the `from` into the current pending result
|
||||||
|
///
|
||||||
|
/// Doesn't spawn the current result
|
||||||
|
fn redirect_from<T: Into<Stdio>>(&mut self, from: T) -> &mut Self {
|
||||||
|
match &mut self.cmd {
|
||||||
|
None => {},
|
||||||
|
Some(cmd) => {
|
||||||
|
cmd.stdin(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/// A shortcut for redirecting a previous result into the current one
|
||||||
|
///
|
||||||
|
/// Spawns the previous result to obtain the output, but not the current one (self)
|
||||||
|
fn redirect_from_result(&mut self, into: &mut ExecResult) -> io::Result<&mut Self> {
|
||||||
|
if matches!(self.cmd, None) {
|
||||||
|
return Ok(self);
|
||||||
|
}
|
||||||
|
match &mut self.cmd {
|
||||||
|
None => {},
|
||||||
|
Some(source) => {
|
||||||
|
source.stdout(Stdio::piped());
|
||||||
|
match &mut into.cmd {
|
||||||
|
None => {},
|
||||||
|
Some(target) => {
|
||||||
|
target.stdin(source.spawn()?.stdout.unwrap());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GetValue for CommandValue {
|
impl GetValue for CommandValue {
|
||||||
fn get(self, ctx: &mut vars::Context) -> Variable {
|
fn get(self, ctx: &mut vars::Context) -> Variable {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue