this doesn't work but I wanna switch computers

main
Jordan Orelli 2 years ago committed by Jordan Orelli
parent 845679eebc
commit 1715ba037f

@ -19,7 +19,7 @@ use anyhow::Result;
fn main() -> Result<()> { fn main() -> Result<()> {
let mut shell = Shell::new()?; let mut shell = Shell::new()?;
let log_path = shell.expand_path("~/wash.log"); let log_path = shell.expand_path("~/clyde.log");
match Log::file(log_path) { match Log::file(log_path) {
Ok(f) => { Ok(f) => {
let target = Box::leak(Box::new(f)); let target = Box::leak(Box::new(f));
@ -63,7 +63,7 @@ fn main() -> Result<()> {
info!("◇ {}", s); info!("◇ {}", s);
let tree = parse::parse(&s)?; let tree = parse::parse(&s)?;
debug!(" {:?}", tree); debug!(" {:?}", tree);
shell.exec(tree)?; shell.exec(tree.into())?;
// Some commands don't leave the terminal in a clean state, so we use reset // Some commands don't leave the terminal in a clean state, so we use reset
// to ensure that our input and output modes are what we expect them to be. // to ensure that our input and output modes are what we expect them to be.
shell.reset()?; shell.reset()?;

@ -1,4 +1,8 @@
use log::debug; use log::debug;
use std::{
cell::RefCell,
rc::Rc,
};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -104,42 +108,178 @@ impl<'text> Lexer<'text> {
} }
} }
struct Parser { // struct Parser {
state: Node, // state: Tree,
// }
//
// impl Parser {
// fn new() -> Self {
// Self {
// state: Tree::new(),
// }
// }
//
// fn parse(mut self, tokens: Vec<Token>) -> Result<Node, Error> {
// Ok(Node::empty())
// // for token in tokens {
// // self.take(token);
// // }
// // let t = self.state.replace(Node::empty());
// // Ok(t.root())
// }
// }
#[derive(Debug, PartialEq, Clone)]
pub enum Element {
Empty,
Command(String),
Literal(String),
} }
impl Parser { #[derive(Debug)]
fn new() -> Self { pub struct Node {
pub elem: Element,
pub parent: Option<Rc<RefCell<Node>>>,
pub children: Vec<Rc<RefCell<Node>>>,
}
impl Node {
pub fn new(elem: Element) -> Self {
Self { Self {
state: Node::Empty, elem,
parent: None,
children: Vec::new(),
} }
} }
fn parse(mut self, tokens: Vec<Token>) -> Result<Node, Error> { pub fn empty() -> Self {
for token in tokens { Self::new(Element::Empty)
match (self.state, token) { }
(Node::Empty, Token::Ident(name)) => {
self.state = Node::Command{name, args: vec!()}; pub fn child_of(parent: Rc<RefCell<Self>>, elem: Element) -> Self {
}, Self {
(Node::Command{name, mut args}, Token::Ident(s)) => { elem,
args.push(s); parent: Some(parent),
self.state = Node::Command{name, args}; children: Vec::new(),
},
_ => return Err(Error::UnexpectedToken),
}
} }
Ok(self.state)
} }
pub fn visit(self) -> Tree {
self.into()
}
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Node { pub struct Tree {
Empty, target: Rc<RefCell<Node>>,
Command { }
name: String,
args: Vec<String>, impl Tree {
}, fn new() -> Self {
Node::empty().into()
}
/// Adds an element as a node as a child of the current node, then descends the tree to select
/// that child node. This is similar to how pushing a value changes the top element of a stack.
fn push(self, elem: Element) -> Self {
if self.is_empty() {
self.target.replace(Node::new(elem));
self
} else {
let child = Node::child_of(Rc::clone(&self.target), elem);
Tree{target: Rc::new(RefCell::new(child))}
}
}
/// Adds a child node with a given element value to the currently selected node without chaning
/// our selection.
fn append(self, elem: Element) -> Self {
if self.is_empty() {
self.target.replace(Node::new(elem));
} else {
let node = Node::child_of(Rc::clone(&self.target), elem);
let child = Rc::new(RefCell::new(node));
self.target.borrow_mut().children.push(child);
}
self
}
/// Tells us whether or not the currently selected node is an empty node
fn is_empty(&self) -> bool {
self.target.borrow().elem == Element::Empty
}
fn parent(&self) -> Option<Self> {
self.target.borrow().parent.as_ref().map(|parent| Self {
target: Rc::clone(parent),
})
}
fn is_root(&self) -> bool {
self.parent().is_none()
}
pub fn root(self) -> Self {
match self.parent() {
Some(parent) => parent.root(),
None => self,
}
}
fn peek(&self) -> Element {
self.target.borrow().elem.clone()
}
fn into_node(self) -> Node {
self.into()
}
fn children(&self) -> ChildIter {
ChildIter {
target: Rc::clone(&self.target),
idx: 0,
last: None,
}
}
}
pub struct ChildIter<'n> {
/// pointer to the node in the tree whose children we are looking at.
target: Rc<RefCell<Node>>,
idx: usize,
last: Option<&'n Node>,
}
impl <'n> Iterator for ChildIter<'n> {
type Item = &'n Node;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.target.borrow().children.len() {
None
} else {
let child = Rc::clone(&self.target.borrow().children[self.idx]);
self.idx += 1;
self.last = Some(&child.as_ref().borrow());
None
//Some(&child.as_ref().borrow())
//Some(&*child.borrow())
}
}
}
impl From<Tree> for Node {
fn from(value: Tree) -> Self {
value.target.replace(Node::empty())
}
}
impl From<Node> for Tree {
fn from(value: Node) -> Self {
Self {
target: Rc::new(RefCell::new(value)),
}
}
} }
// I don't know how to write a parser lol // I don't know how to write a parser lol
@ -167,11 +307,20 @@ pub enum Node {
// ] // ]
// } // }
pub fn parse<S: AsRef<str>>(text: S) -> Result<Node, Error> { pub fn parse<S: AsRef<str>>(text: S) -> Result<Tree, Error> {
let tokens = lex(text)?; let mut tree = Tree::new();
let parser = Parser::new(); for token in lex(text)? {
debug!(" {:?}", tokens); match (tree.peek(), token) {
parser.parse(tokens) (Element::Empty, Token::Ident(cmd)) => {
tree = tree.push(Element::Command(cmd));
}
(Element::Command(_), Token::Ident(arg)) => {
tree = tree.append(Element::Literal(arg));
}
_ => todo!(),
}
}
Ok(tree.root())
} }
#[cfg(test)] #[cfg(test)]
@ -241,4 +390,68 @@ mod tests {
"one |two" "one |two"
ident("one") Pipe ident("two"); ident("one") Pipe ident("two");
} }
#[test]
fn empty_tree() {
let root = Tree::new().root();
assert!(root.is_root());
assert_eq!(root.peek(), Element::Empty);
assert_eq!(root.children().count(), 0);
}
#[test]
fn tree_root() {
let root = Tree::new()
.push(Element::Command(String::from("ls")))
.root();
assert!(root.is_root());
assert_eq!(root.children().count(), 0);
assert_eq!(root.into_node().elem, Element::Command(String::from("ls")));
}
#[test]
fn tree_push() {
let tree = Tree::new()
.push(Element::Command(String::from("ls")));
assert_eq!(tree.peek(), Element::Command(String::from("ls")));
let tree = Tree::new()
.push(Element::Command(String::from("ls")))
.append(Element::Command(String::from("one")));
assert_eq!(tree.peek(), Element::Command(String::from("ls")));
}
#[test]
fn test_parse() {
let res = parse("ls one two");
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")));
}
/*
#[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(".")));
}
*/
} }

@ -9,6 +9,7 @@ use crate::{
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::Rc;
use anyhow::Result; use anyhow::Result;
use dirs; use dirs;
@ -97,16 +98,17 @@ impl Shell {
} }
} }
pub fn exec(&mut self, mut node: Node) -> Result<bool> { pub fn exec(&mut self, root: Node) -> Result<bool> {
loop { // match &tree.elem {
match node { // Node::Command(name) => {
Node::Empty => break, // let args: Vec<&str> = tree.children.iter().map(|t| match &t.elem {
Node::Command{name, args} => { // Node::Literal(arg) => arg.as_str(),
self.eval(name, args.iter().map(|s| s.as_str()).collect())?; // _ => todo!(),
node = Node::Empty; // }).collect();
}, // self.eval(name.to_string(), args)?;
} // },
} // _ => todo!(),
// }
Ok(true) Ok(true)
} }

Loading…
Cancel
Save