diff options
author | Jesse Luehrs <doy@tozt.net> | 2022-01-08 17:28:58 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2022-01-08 17:28:58 -0500 |
commit | 27934e2a48254b4b948b846680afe213e61fdfc0 (patch) | |
tree | 4de94e29b90e35be9ebc972a099aa34b7443994f /src/parse/ast.rs | |
parent | bfc458a5ce75762624115feaa50cfd3a3edd7bc0 (diff) | |
download | nbsh-27934e2a48254b4b948b846680afe213e61fdfc0.tar.gz nbsh-27934e2a48254b4b948b846680afe213e61fdfc0.zip |
add parsing for control statements
Diffstat (limited to 'src/parse/ast.rs')
-rw-r--r-- | src/parse/ast.rs | 55 |
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, |