summaryrefslogtreecommitdiffstats
path: root/src/parse/ast.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-01-08 17:28:58 -0500
committerJesse Luehrs <doy@tozt.net>2022-01-08 17:28:58 -0500
commit27934e2a48254b4b948b846680afe213e61fdfc0 (patch)
tree4de94e29b90e35be9ebc972a099aa34b7443994f /src/parse/ast.rs
parentbfc458a5ce75762624115feaa50cfd3a3edd7bc0 (diff)
downloadnbsh-27934e2a48254b4b948b846680afe213e61fdfc0.tar.gz
nbsh-27934e2a48254b4b948b846680afe213e61fdfc0.zip
add parsing for control statements
Diffstat (limited to 'src/parse/ast.rs')
-rw-r--r--src/parse/ast.rs55
1 files changed, 48 insertions, 7 deletions
diff --git a/src/parse/ast.rs b/src/parse/ast.rs
index ba13bc1..2216dcb 100644
--- a/src/parse/ast.rs
+++ b/src/parse/ast.rs
@@ -8,7 +8,7 @@ struct Shell;
#[derive(Debug, PartialEq, Eq)]
pub struct Commands {
- pipelines: Vec<Pipeline>,
+ commands: Vec<Command>,
input_string: String,
}
@@ -25,8 +25,8 @@ impl Commands {
))
}
- pub fn pipelines(&self) -> &[Pipeline] {
- &self.pipelines
+ pub fn commands(&self) -> &[Command] {
+ &self.commands
}
pub fn input_string(&self) -> &str {
@@ -37,16 +37,57 @@ impl Commands {
assert!(matches!(commands.as_rule(), Rule::commands));
let input_string = commands.as_str().to_string();
Self {
- pipelines: commands
- .into_inner()
- .map(Pipeline::build_ast)
- .collect(),
+ commands: commands.into_inner().map(Command::build_ast).collect(),
input_string,
}
}
}
#[derive(Debug, PartialEq, Eq)]
+pub enum Command {
+ Pipeline(Pipeline),
+ If(Pipeline),
+ While(Pipeline),
+ For(String, Pipeline),
+ End,
+}
+
+impl Command {
+ fn build_ast(command: pest::iterators::Pair<Rule>) -> Self {
+ assert!(matches!(command.as_rule(), Rule::command));
+ let next = command.into_inner().next().unwrap();
+ match next.as_rule() {
+ Rule::pipeline => Self::Pipeline(Pipeline::build_ast(next)),
+ Rule::command => {
+ let control = next.into_inner().next().unwrap();
+ assert!(matches!(control.as_rule(), Rule::control));
+ let ty = control.into_inner().next().unwrap();
+ match ty.as_rule() {
+ Rule::control_if => Self::If(Pipeline::build_ast(
+ ty.into_inner().next().unwrap(),
+ )),
+ Rule::control_while => Self::While(Pipeline::build_ast(
+ ty.into_inner().next().unwrap(),
+ )),
+ Rule::control_for => {
+ let mut inner = ty.into_inner();
+ let var = inner.next().unwrap();
+ assert!(matches!(var.as_rule(), Rule::bareword));
+ Self::For(
+ var.as_str().to_string(),
+ Pipeline::build_ast(inner.next().unwrap()),
+ )
+ }
+ Rule::control_end => Self::End,
+ _ => unreachable!(),
+ }
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
+#[derive(Debug, PartialEq, Eq)]
pub struct Pipeline {
exes: Vec<Exe>,
input_string: String,