aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse/mod.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-12 12:17:15 +0100
committerJonas Maier <>2026-03-12 12:17:15 +0100
commitad9572cc6e89634a4d029cc8d311bb51626c17c3 (patch)
tree944c79c7e627b54ab1bc4cbb793e64c9ebd708bd /src/parse/mod.rs
parent8dea55071464739bd1b8ef33ed5c294183d4780a (diff)
downloadpish-ad9572cc6e89634a4d029cc8d311bb51626c17c3.tar.gz
start of better parsing for proper blocks
Diffstat (limited to 'src/parse/mod.rs')
-rw-r--r--src/parse/mod.rs65
1 files changed, 53 insertions, 12 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index a15ad84..93d2de8 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -33,19 +33,19 @@ pub trait Expander {
}
#[derive(Debug, Clone, PartialEq)]
+pub struct Block {
+ pub commands: Vec<Ast<PreExpansion>>,
+}
+
+#[derive(Debug, Clone, PartialEq)]
pub enum Ast<T: Stage> {
FunDecl(FunDecl<T>),
VarAssign(VarAssign<T>),
Pipes(Pipes<T>),
}
-pub fn decl(name: ExpString, body: Ast<PreExpansion>) -> Ast<PreExpansion> {
- Ast::FunDecl(FunDecl {
- name,
- body: FunBody {
- body: Box::new(body),
- },
- })
+pub fn decl(name: ExpString, body: Block) -> Ast<PreExpansion> {
+ Ast::FunDecl(FunDecl { name, body })
}
pub fn assign(var: ExpString, val: ExpString) -> Ast<PreExpansion> {
@@ -106,6 +106,27 @@ pub fn cmd<const N: usize>(x: [ExpString; N]) -> Command<PreExpansion> {
}
}
+pub fn block<const N: usize>(x: [Ast<PreExpansion>; N]) -> Block {
+ Block {
+ commands: x.to_vec(),
+ }
+}
+
+impl CmdDisplay for Block {
+ fn cdisplay(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
+ write!(w, "block([")?;
+ let mut prev = false;
+ for cmd in self.commands.iter() {
+ if prev {
+ write!(w, ",")?;
+ }
+ prev = true;
+ cmd.cdisplay(w)?;
+ }
+ write!(w, "])")
+ }
+}
+
impl CmdDisplay for Ast<PreExpansion> {
fn cdisplay(&self, w: &mut dyn std::io::Write) -> std::io::Result<()> {
match self {
@@ -113,7 +134,7 @@ impl CmdDisplay for Ast<PreExpansion> {
write!(w, "decl(")?;
fun_decl.name.cdisplay(w)?;
write!(w, ", ")?;
- fun_decl.body.body.cdisplay(w)?;
+ fun_decl.body.cdisplay(w)?;
write!(w, ")")?;
}
Ast::VarAssign(var_assign) => {
@@ -256,7 +277,13 @@ impl Parse for FunBody {
#[derive(Debug, Clone, PartialEq)]
pub struct FunDecl<S: Stage> {
pub name: S::Str,
- pub body: FunBody,
+ pub body: Block,
+}
+
+impl Parse for Block {
+ fn parse(b: &mut Cursor<'_>) -> Result<Self> {
+ todo!()
+ }
}
impl Parse for FunDecl<PreExpansion> {
@@ -267,7 +294,7 @@ impl Parse for FunDecl<PreExpansion> {
b.advance(4);
b.spaces();
let name = ExpString::parse(b)?;
- let body = FunBody::parse(b)?;
+ let body = Block::parse(b)?;
Ok(Self { name, body })
}
}
@@ -648,7 +675,11 @@ impl Parse for ExpString {
continue;
}
- if delim == b' ' && x == b'~' && p.is_empty() && (!b.has() || b" /".contains(&b.peek())) {
+ if delim == b' '
+ && x == b'~'
+ && p.is_empty()
+ && (!b.has() || b" /".contains(&b.peek()))
+ {
p.push(StringPart::Var(Var {
name: VarName {
name: b"HOME".to_vec(),
@@ -752,10 +783,20 @@ impl CompletionContext {
}
}
+impl Block {
+ fn completion<E: Expander>(&self, e: &mut E) -> CompletionContext {
+ if let Some(cmd) = self.commands.last() {
+ cmd.completion(e)
+ } else {
+ CompletionContext::none()
+ }
+ }
+}
+
impl Ast<PreExpansion> {
fn completion<E: Expander>(&self, e: &mut E) -> CompletionContext {
match self {
- Ast::FunDecl(fd) => fd.body.body.completion(e),
+ Ast::FunDecl(fd) => fd.body.completion(e),
Ast::VarAssign(va) => va.val.completion(e, CompletionKind::Argument),
Ast::Pipes(p) => p.completion(e),
}