mirror of
https://github.com/danbulant/rush
synced 2026-05-27 14:02:17 +00:00
attempt at adding pipes
This commit is contained in:
parent
333fd74db1
commit
1cda409a65
2 changed files with 104 additions and 28 deletions
111
src/parser.rs
111
src/parser.rs
|
|
@ -26,6 +26,42 @@ pub struct Command {
|
||||||
args: Vec<Value>
|
args: Vec<Value>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct CommandPipe {
|
||||||
|
lhs: Box<Statement>,
|
||||||
|
rhs: Box<Statement>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TargetFilePipe {
|
||||||
|
cmd: Option<Box<Statement>>,
|
||||||
|
target: Box<Value>,
|
||||||
|
overwrite: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SourceFilePipe {
|
||||||
|
cmd: Option<Box<Statement>>,
|
||||||
|
source: Box<Value>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct And {
|
||||||
|
lhs: Box<Statement>,
|
||||||
|
rhs: Box<Statement>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Or {
|
||||||
|
lhs: Box<Statement>,
|
||||||
|
rhs: Box<Statement>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Not {
|
||||||
|
value: Box<Statement>
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Set {
|
pub struct Set {
|
||||||
name: Box<Bindable>,
|
name: Box<Bindable>,
|
||||||
|
|
@ -78,6 +114,12 @@ pub enum Statement {
|
||||||
Return(Option<Value>),
|
Return(Option<Value>),
|
||||||
Break,
|
Break,
|
||||||
Continue,
|
Continue,
|
||||||
|
Or(Or),
|
||||||
|
And(And),
|
||||||
|
Not(Not),
|
||||||
|
CommandPipe(CommandPipe),
|
||||||
|
TargetFilePipe(TargetFilePipe),
|
||||||
|
SourceFilePipe(SourceFilePipe),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -131,7 +173,7 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
.ignored()
|
.ignored()
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
let direct_string = none_of("$()[]{}\\\"\n;")
|
let direct_string = none_of("$()[]{}\\\"\n;|&")
|
||||||
.and_is(text::whitespace().at_least(1).not())
|
.and_is(text::whitespace().at_least(1).not())
|
||||||
.ignored()
|
.ignored()
|
||||||
.or(escape.clone())
|
.or(escape.clone())
|
||||||
|
|
@ -164,6 +206,14 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
.or(comment.ignored())
|
.or(comment.ignored())
|
||||||
.or(eol.ignored());
|
.or(eol.ignored());
|
||||||
|
|
||||||
|
let and = just("&&");
|
||||||
|
let or = just("||");
|
||||||
|
let not = just('!');
|
||||||
|
let pipe = just('|');//.then(just('|').rewind().not());
|
||||||
|
// let pipe_target = just('>');
|
||||||
|
// let pipe_target_append = just(">>");
|
||||||
|
// let pipe_source = just('<');
|
||||||
|
|
||||||
recursive(|expr| {
|
recursive(|expr| {
|
||||||
let primitive = choice((
|
let primitive = choice((
|
||||||
number.map(Primitive::Number),
|
number.map(Primitive::Number),
|
||||||
|
|
@ -178,7 +228,6 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
let value = choice((
|
let value = choice((
|
||||||
group,
|
group,
|
||||||
primitive.clone().map(Value::Primitive),
|
primitive.clone().map(Value::Primitive),
|
||||||
// index.map(|i| Value::Primitive(Primitive::Index(i))),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
let index = value.clone()
|
let index = value.clone()
|
||||||
|
|
@ -197,10 +246,6 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
index,
|
index,
|
||||||
value,
|
value,
|
||||||
));
|
));
|
||||||
// let value = recursive(|newvalue: Recursive<dyn Parser<'_, &str, Value>>| {
|
|
||||||
|
|
||||||
// value
|
|
||||||
// });
|
|
||||||
|
|
||||||
let bindable = primitive.clone().map(Bindable::Primitive);
|
let bindable = primitive.clone().map(Bindable::Primitive);
|
||||||
|
|
||||||
|
|
@ -226,6 +271,7 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
just("continue"),
|
just("continue"),
|
||||||
just("return"),
|
just("return"),
|
||||||
just("fn"),
|
just("fn"),
|
||||||
|
just("!")
|
||||||
)).then(end()).not());
|
)).then(end()).not());
|
||||||
|
|
||||||
let args = value.clone()
|
let args = value.clone()
|
||||||
|
|
@ -345,10 +391,59 @@ pub fn parse<'a>() -> impl Parser<'a, &'a str, Vec<Statement>, chumsky::extra::D
|
||||||
just("break").to(Statement::Break),
|
just("break").to(Statement::Break),
|
||||||
just("continue").to(Statement::Continue),
|
just("continue").to(Statement::Continue),
|
||||||
command.map(Statement::Command),
|
command.map(Statement::Command),
|
||||||
|
)).padded_by(text::inline_whitespace().ignored().or(comment.ignored())).boxed();
|
||||||
|
|
||||||
|
let not = not.repeated().at_least(1)
|
||||||
|
.foldr(
|
||||||
|
text::inline_whitespace()
|
||||||
|
.ignore_then(statement.clone()),
|
||||||
|
|_, rhs| Statement::Not(Not {
|
||||||
|
value: Box::new(rhs)
|
||||||
|
})
|
||||||
|
).boxed();
|
||||||
|
|
||||||
|
let or = statement.clone()
|
||||||
|
.foldl(
|
||||||
|
or
|
||||||
|
.padded_by(text::inline_whitespace())
|
||||||
|
.ignore_then(statement.clone())
|
||||||
|
.repeated(),
|
||||||
|
|lhs, rhs| Statement::Or(Or {
|
||||||
|
lhs: Box::new(lhs),
|
||||||
|
rhs: Box::new(rhs)
|
||||||
|
})).boxed();
|
||||||
|
|
||||||
|
let and = statement.clone()
|
||||||
|
.foldl(
|
||||||
|
and
|
||||||
|
.padded_by(text::inline_whitespace())
|
||||||
|
.ignore_then(statement.clone())
|
||||||
|
.repeated(),
|
||||||
|
|lhs, rhs| Statement::And(And {
|
||||||
|
lhs: Box::new(lhs),
|
||||||
|
rhs: Box::new(rhs)
|
||||||
|
})).boxed();
|
||||||
|
|
||||||
|
let pipe = statement.clone()
|
||||||
|
.foldl(
|
||||||
|
pipe
|
||||||
|
.padded_by(text::inline_whitespace())
|
||||||
|
.ignore_then(statement.clone())
|
||||||
|
.repeated(),
|
||||||
|
|lhs, rhs| Statement::CommandPipe(CommandPipe {
|
||||||
|
lhs: Box::new(lhs),
|
||||||
|
rhs: Box::new(rhs)
|
||||||
|
})).boxed();
|
||||||
|
|
||||||
|
let statement_pair = choice((
|
||||||
|
or,
|
||||||
|
and,
|
||||||
|
not,
|
||||||
|
pipe,
|
||||||
|
statement
|
||||||
));
|
));
|
||||||
|
|
||||||
statement
|
statement_pair
|
||||||
.padded_by(text::inline_whitespace().ignored().or(comment.ignored()))
|
|
||||||
.separated_by(eol.repeated().at_least(1))
|
.separated_by(eol.repeated().at_least(1))
|
||||||
.at_least(1)
|
.at_least(1)
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1 @@
|
||||||
fn test() {}
|
! test
|
||||||
|
|
||||||
echo test
|
|
||||||
|
|
||||||
set test = test
|
|
||||||
|
|
||||||
if test { test } else test
|
|
||||||
|
|
||||||
while test { test }
|
|
||||||
|
|
||||||
for test in test { test }
|
|
||||||
|
|
||||||
loop {}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
|
|
||||||
break
|
|
||||||
continue
|
|
||||||
|
|
||||||
return $thing[property]
|
|
||||||
Loading…
Reference in a new issue