diff options
| author | Jonas Maier <jonas@x77.dev> | 2026-05-08 19:00:39 +0200 |
|---|---|---|
| committer | Jonas Maier <jonas@x77.dev> | 2026-05-08 19:00:39 +0200 |
| commit | f4b69eb87ca61f408323ab9d24938859f7c4ceb3 (patch) | |
| tree | d74bdb4869eb7ce0ee2899ec92244a484ff5b4f4 /src/parse/mod.rs | |
| parent | 5697ecb492579413a7ce9589df6847a3e205c647 (diff) | |
| download | pish-f4b69eb87ca61f408323ab9d24938859f7c4ceb3.tar.gz | |
while loops
Diffstat (limited to 'src/parse/mod.rs')
| -rw-r--r-- | src/parse/mod.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 47aff20..dcb5790 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -80,6 +80,7 @@ pub enum Ast<T: Stage> { VarAssign(VarAssign<T>), Pipes(Pipes<T>), If(If<T>), + While(While), } #[allow(unused)] @@ -99,6 +100,12 @@ pub struct If<T: Stage> { parse_progress: IfParseProgress, } +#[derive(Debug, Clone, PartialEq)] +pub struct While { + pub condition: Pipes<PreExpansion>, + pub block: Block, +} + impl If<PreExpansion> { fn expand<E: Expander>(self, e: &mut E) -> Res<If<PostExpansion>, E::Error> { Ok(If { @@ -140,6 +147,13 @@ pub fn cond( }) } +pub fn whil(condition: Ast<PreExpansion>, block: Block) -> Ast<PreExpansion> { + let Ast::Pipes(condition) = condition else { + panic!() + }; + Ast::While(While { condition, block }) +} + pub fn estr(x: &[u8]) -> ExpString { ExpString { parts: vec![StringPart::Boring(x.to_vec())], @@ -243,6 +257,13 @@ impl CmdDisplay for Ast<PreExpansion> { i.false_block.cdisplay(w)?; write!(w, ")")?; } + Ast::While(l) => { + write!(w, "whil(")?; + Ast::Pipes(l.condition.clone()).cdisplay(w)?; + write!(w, ", ")?; + l.block.cdisplay(w)?; + write!(w, ")")?; + } } Ok(()) } @@ -328,6 +349,7 @@ impl Ast<PreExpansion> { Ast::Pipes(pipes) => Ok(Ast::Pipes(pipes.expand(e)?)), Ast::FunDecl(fd) => Ok(Ast::FunDecl(fd.expand(e)?)), Ast::If(i) => Ok(Ast::If(i.expand(e)?)), + Ast::While(w) => Ok(Ast::While(w)), } } } @@ -478,7 +500,7 @@ pub struct Pipes<T: Stage> { } impl Pipes<PreExpansion> { - fn expand<E: Expander>(self, e: &mut E) -> Res<Pipes<PostExpansion>, E::Error> { + pub fn expand<E: Expander>(self, e: &mut E) -> Res<Pipes<PostExpansion>, E::Error> { let mut cmds = Vec::with_capacity(self.cmds.len()); for cmd in self.cmds.into_iter() { cmds.push(cmd.expand(e)?); @@ -1117,6 +1139,8 @@ pub enum ParseError { NotABlock, NotAnIf, + + NotAWhile, } type Result<T> = std::result::Result<T, ParseError>; @@ -1177,6 +1201,7 @@ impl Ast<PreExpansion> { Ast::VarAssign(va) => va.val.completion(e, CompletionKind::Argument), Ast::Pipes(p) => p.completion(e), Ast::If(i) => i.completion(e), + Ast::While(_) => todo!(), } } } @@ -1422,6 +1447,21 @@ impl Parse for If<PreExpansion> { } } +impl Parse for While { + fn parse(b: &mut Cursor<'_>) -> Result<Self> { + b.spaces(); + if !b.buf.starts_with(b"while ") || b.buf.starts_with(b"while\t") { + return Err(ParseError::NotAWhile); + } + b.advance(6); + b.spaces(); + let condition = Pipes::parse(b)?; + let block = Block::parse(b)?; + + Ok(Self { condition, block }) + } +} + impl Parse for Ast<PreExpansion> { fn parse(b: &mut Cursor<'_>) -> Result<Self> { b.spaces(); @@ -1435,6 +1475,14 @@ impl Parse for Ast<PreExpansion> { } let orig_len = b.buf.len(); + let x = While::parse(b); + if let Ok(x) = x { + return Ok(Self::While(x)); + } else if b.buf.len() != orig_len { + x?; + } + + let orig_len = b.buf.len(); let x = VarAssign::parse(b); if let Ok(va) = x { return Ok(Self::VarAssign(va)); |
