From 4b83b63ddb81817ea7cc418f1b61f687ba813085 Mon Sep 17 00:00:00 2001 From: Jonas Maier <> Date: Thu, 5 Mar 2026 07:26:59 +0100 Subject: begin of a parser --- src/parse.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/parse.rs (limited to 'src/parse.rs') diff --git a/src/parse.rs b/src/parse.rs new file mode 100644 index 0000000..cc495b1 --- /dev/null +++ b/src/parse.rs @@ -0,0 +1,84 @@ +pub enum Ast { + AssignVar(AssignVar), + Pipes(Pipes), +} + +pub struct AssignVar { + pub to: String, + // TODO: body +} + +pub struct Pipes { + pub cmds: Vec, +} + +pub struct Command { + pub path: String, + pub args: Vec, +} + +enum ParseError { + Incomplete, + UnexpectedPipe, + UnknownChar(char), +} + +type Result = std::result::Result; + +pub fn parse(x: &str) -> Result { + let chars: Vec = x.chars().collect(); + Ast::parse(&mut &chars[..]) +} + +trait Parse: Sized { + fn parse(b: &mut &[char]) -> Result; +} + +fn spaces(b: &mut &[char]) { + while let Some(' ' | '\t') = b.get(0) { + *b = &b[1..]; + } +} + +fn parse_quoted_string(b: &mut &[char], delim: char) -> Result { + // TODO: escape sequence stuff + + *b = &b[1..]; + let mut s = String::new(); + while b.len() > 0 { + if b[0] == delim { + *b = &b[1..]; + return Ok(s); + } + + s.push(b[0]); + *b = &b[1..]; + } + Err(ParseError::Incomplete) +} + +impl Parse for String { + fn parse(b: &mut &[char]) -> Result { + spaces(b); + if b.is_empty() { + return Err(ParseError::Incomplete); + } + let c = b[0]; + if c == '|' { + Err(ParseError::UnexpectedPipe) + } else if c == '\'' || c == '"' { + *b = &b[1..]; + parse_quoted_string(b, c) + } else if c.is_ascii_graphic() { + parse_quoted_string(b, ' ') + } else { + Err(ParseError::UnknownChar(c)) + } + } +} + +impl Parse for Ast { + fn parse(b: &mut &[char]) -> Result { + todo!() + } +} -- cgit v1.2.3