use parser::assignments::parse_assignment;
use parser::{pipelines, ArgumentSplitter};
use shell::flow_control::{ElseIf, Statement};
#[pub]
parse_ -> Statement
= let_
/ if_
/ else_if_
/ else_
/ for_
/ while_
/ fn_
/ end_
/ break_
/ continue_
/ pipelines
#[pub]
let_ -> Statement
= whitespace* "let" whitespace? value:$(.*) {
Statement::Let { expression: parse_assignment(value) }
}
#[pub]
break_ -> Statement
= whitespace* "break" { Statement::Break }
#[pub]
continue_ -> Statement
= whitespace* "continue" { Statement::Continue }
#[pub]
if_ -> Statement
= whitespace* "if" whitespace? command:$(.*) {?
let mut possible_error = None;
let pipeline = pipelines::collect(&mut possible_error, command);
match possible_error {
Some(error) => Err(error),
None => Ok(Statement::If {
expression: pipeline,
success: Vec::new(),
else_if: Vec::new(),
failure: Vec::new()
})
}
}
#[pub]
else_if_ -> Statement
= whitespace* "else" whitespace? "if" whitespace? command:$(.*) {?
let mut possible_error = None;
let pipeline = pipelines::collect(&mut possible_error, command);
match possible_error {
Some(error) => Err(error),
None => Ok(Statement::ElseIf(ElseIf {
expression: pipeline,
success: Vec::new(),
}))
}
}
#[pub]
else_ -> Statement
= whitespace* "else" whitespace* { Statement::Else }
#[pub]
end_ -> Statement
= whitespace* "end" whitespace* { Statement ::End }
#[pub]
fn_ -> Statement
= whitespace* "fn " n:_name whitespace* args:_args whitespace* description:_description? {
Statement::Function {
description: description.unwrap_or("".into()),
name: n.into(),
args: args,
statements: Vec::new(),
}
}
_description -> String
= "--" whitespace* description:$([^\r\n]*) { description.into() }
_name -> String
= n:$([A-z0-9_]+) { n.into() }
_args -> Vec<String>
= _arg ** " "
_arg -> String
= n:$([A-z0-9]+) { n.into() }
#[pub]
for_ -> Statement
= whitespace* "for" whitespace? n:_name whitespace? "in" whitespace? expr:$(.*) {
Statement::For {
variable: n.into(),
values: ArgumentSplitter::new(expr).map(String::from).collect(),
statements: Vec::new(),
}
}
#[pub]
while_ -> Statement
= whitespace* "while" whitespace? command:$(.*) {?
let mut possible_error = None;
let pipeline = pipelines::collect(&mut possible_error, command);
match possible_error {
Some(error) => Err(error),
None => Ok(Statement::While {
expression: pipeline,
statements: Vec::new()
})
}
}
pub pipelines -> Statement
= (unused* newline)* [#] .* { Statement::Default }
/ [ \n\t\r]* pipeline:_pipelines { pipeline }
/ (unused*) ** newline { Statement::Default }
// Converts the pipeline string into a statement, handling redirection, piping, and backgrounds.
_pipelines -> Statement
= command:$(.+) {?
let mut possible_error = None;
let pipeline = pipelines::collect(&mut possible_error, command);
match possible_error {
Some(error) => Err(error),
None => Ok(Statement::Pipeline(pipeline))
}
}
unused -> ()
= whitespace comment? { () }
/ comment { () }
comment -> ()
= [#] [^\r\n]*
whitespace -> ()
= [ \t]+
job_ending -> ()
= [;]
/ newline
newline -> ()
= [\r\n]