aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-05 07:26:59 +0100
committerJonas Maier <>2026-03-05 07:26:59 +0100
commit4b83b63ddb81817ea7cc418f1b61f687ba813085 (patch)
tree02dfad0d4235d44545a930a1bd2304b2c6d36031 /src/parse.rs
parentd4050c3a8cfabd4ae77d001d665573729d28a096 (diff)
downloadpish-4b83b63ddb81817ea7cc418f1b61f687ba813085.tar.gz
begin of a parser
Diffstat (limited to 'src/parse.rs')
-rw-r--r--src/parse.rs84
1 files changed, 84 insertions, 0 deletions
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<Command>,
+}
+
+pub struct Command {
+ pub path: String,
+ pub args: Vec<String>,
+}
+
+enum ParseError {
+ Incomplete,
+ UnexpectedPipe,
+ UnknownChar(char),
+}
+
+type Result<T> = std::result::Result<T, ParseError>;
+
+pub fn parse(x: &str) -> Result<Ast> {
+ let chars: Vec<char> = x.chars().collect();
+ Ast::parse(&mut &chars[..])
+}
+
+trait Parse: Sized {
+ fn parse(b: &mut &[char]) -> Result<Self>;
+}
+
+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<String> {
+ // 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<Self> {
+ 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<Self> {
+ todo!()
+ }
+}