diff --git a/src/parse.rs b/src/parse.rs index c2e3dd1..ead60bb 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,5 +1,7 @@ use log::debug; use std::{ + fmt, + ops::Deref, cell::RefCell, rc::Rc, }; @@ -129,14 +131,23 @@ impl<'text> Lexer<'text> { // } // } -#[derive(Debug, PartialEq, Clone)] +#[derive(PartialEq, Clone)] pub enum Element { Empty, Command(String), Literal(String), } -#[derive(Debug)] +impl fmt::Debug for Element { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Element::Empty => write!(f, "()"), + Element::Command(cmd) => write!(f, "cmd<{}>", cmd), + Element::Literal(lit) => write!(f, "lit<{}>", lit), + } + } +} + pub struct Node { pub elem: Element, pub parent: Option>>, @@ -169,7 +180,20 @@ impl Node { } } -#[derive(Debug)] +impl fmt::Debug for Node { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{:?}", self.elem)?; + if self.children.len() > 0 { + write!(f, "[")?; + for child in self.children.iter() { + write!(f, "{:?}", child.borrow())?; + } + write!(f, "]")?; + } + Ok(()) + } +} + pub struct Tree { target: Rc>, } @@ -236,34 +260,34 @@ impl Tree { fn children(&self) -> ChildIter { ChildIter { - target: Rc::clone(&self.target), + parent: Rc::clone(&self.target), idx: 0, - last: None, } } } -pub struct ChildIter<'n> { +impl fmt::Debug for Tree { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{:?}", self.target.borrow()) + } +} + +pub struct ChildIter { /// pointer to the node in the tree whose children we are looking at. - target: Rc>, + parent: Rc>, idx: usize, - last: Option<&'n Node>, } -impl <'n> Iterator for ChildIter<'n> { - type Item = &'n Node; +impl Iterator for ChildIter { + type Item = Tree; fn next(&mut self) -> Option { - if self.idx >= self.target.borrow().children.len() { + if self.idx >= self.parent.borrow().children.len() { None } else { - let child = Rc::clone(&self.target.borrow().children[self.idx]); + let child = Rc::clone(&self.parent.borrow().children[self.idx]); self.idx += 1; - self.last = Some(&child.as_ref().borrow()); - None - - //Some(&child.as_ref().borrow()) - //Some(&*child.borrow()) + Some(Tree{target: child}) } } } @@ -359,8 +383,8 @@ mod tests { ident("one"); two_tokens: - "one two" - ident("one") ident("two"); + "ls one two" + ident("ls") ident("one") ident("two"); leading_whitespace: " one" @@ -421,37 +445,19 @@ mod tests { assert_eq!(tree.peek(), Element::Command(String::from("ls"))); } - #[test] - fn test_parse() { - let res = parse("ls one two"); + fn parse_args() { + let res = parse("ls one two three"); assert!(res.is_ok()); let tree = res.unwrap(); assert_eq!(tree.peek(), Element::Command(String::from("ls"))); - assert_eq!(tree.children().count(), 2); - - let args = tree.children(); - // assert_eq!(args.next().unwrap(), Element::Literal(String::from("one"))); - } + assert_eq!(tree.children().count(), 3); - /* - #[test] - fn tree_command() { - /* - Command(ls) - Literal(.) - */ - let root = Tree::new() - .push(Element::Command(String::from("ls"))) - .push(Element::Literal(String::from("."))) - .root(); - - assert!(root.is_root()); - assert_eq!(root.children().count(), 1); - // assert_eq!(root.elem, Element::Command(String::from("ls"))); - // assert_eq!(root.children.len(), 1); - // assert_eq!(root.children[0].borrow(), Element::Literal(String::from("."))); + let mut args = tree.children(); + assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("one"))); + assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("two"))); + assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("three"))); + assert!(args.next().is_none()); } - */ } diff --git a/src/shell.rs b/src/shell.rs index 554607b..9a0edb8 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -2,10 +2,10 @@ use crate::{ ext::{Command, Echo, Printenv, Tail, Which}, input, line::Line, - parse::Node, log::*, output, // parse::parse, + parse::{Element, Node}, }; use std::path::{Path, PathBuf}; @@ -99,17 +99,24 @@ impl Shell { } pub fn exec(&mut self, root: Node) -> Result { - // match &tree.elem { - // Node::Command(name) => { - // let args: Vec<&str> = tree.children.iter().map(|t| match &t.elem { - // Node::Literal(arg) => arg.as_str(), - // _ => todo!(), - // }).collect(); - // self.eval(name.to_string(), args)?; - // }, - // _ => todo!(), - // } - Ok(true) + match root.elem { + Element::Empty => Ok(true), + Element::Command(cmd) => { + let args: Vec = root + .children + .iter() + .map(|node| match &node.borrow().elem { + Element::Literal(v) => v.clone(), + _ => todo!(), + }) + .collect(); + self.eval( + cmd.to_string(), + args.iter().map(|arg| arg.as_str()).collect(), + ) + } + Element::Literal(_) => todo!(), + } } pub fn eval(&mut self, cmd: String, args: Vec<&str>) -> Result {