maybe i should figure out how to glob

main
Jordan Orelli 2 years ago
parent 05793bd42c
commit 522668be28

@ -1,10 +1,4 @@
use log::debug; use std::{cell::RefCell, fmt, rc::Rc};
use std::{
fmt,
ops::Deref,
cell::RefCell,
rc::Rc,
};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -17,6 +11,7 @@ pub enum Error {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Token { pub enum Token {
Ident(String), Ident(String),
Glob(String),
Pipe, Pipe,
} }
@ -28,6 +23,7 @@ fn lex<S: AsRef<str>>(text: S) -> Result<Vec<Token>, Error> {
struct Lexer<'text> { struct Lexer<'text> {
chars: std::str::Chars<'text>, chars: std::str::Chars<'text>,
peeked: Option<char>, peeked: Option<char>,
kept: Vec<char>,
} }
impl<'text> Lexer<'text> { impl<'text> Lexer<'text> {
@ -35,6 +31,7 @@ impl<'text> Lexer<'text> {
Self { Self {
chars: text.chars(), chars: text.chars(),
peeked: None, peeked: None,
kept: Vec::new(),
} }
} }
@ -48,6 +45,9 @@ impl<'text> Lexer<'text> {
tokens.push(Token::Pipe); tokens.push(Token::Pipe);
self.skip(); self.skip();
} }
Some('*') => {
tokens.push(self.glob());
}
Some(_) => { Some(_) => {
tokens.push(self.ident()); tokens.push(self.ident());
} }
@ -92,50 +92,66 @@ impl<'text> Lexer<'text> {
} }
} }
fn keep(&mut self) {
match self.peeked {
Some(c) => {
self.kept.push(c);
self.peeked = None;
}
None => match self.chars.next() {
Some(c) => self.kept.push(c),
None => todo!(),
},
}
}
fn ident(&mut self) -> Token { fn ident(&mut self) -> Token {
let mut kept: Vec<char> = vec![];
loop { loop {
match self.peek() { match self.peek() {
None => break, None => break,
Some('*') => {
self.keep();
self.glob();
},
Some(c) => { Some(c) => {
if c.is_whitespace() { if c.is_whitespace() {
break; break;
} }
kept.push(c); self.keep();
self.skip();
} }
} }
} }
Token::Ident(kept.iter().collect()) Token::Ident(self.pop())
} }
}
// struct Parser { fn glob(&mut self) -> Token {
// state: Tree, loop {
// } match self.peek() {
// None => break,
// impl Parser { Some(c) => {
// fn new() -> Self { if c.is_whitespace() {
// Self { break;
// state: Tree::new(), }
// } self.keep();
// } }
// }
// fn parse(mut self, tokens: Vec<Token>) -> Result<Node, Error> { }
// Ok(Node::empty()) Token::Glob(self.pop())
// // for token in tokens { }
// // self.take(token);
// // } fn pop(&mut self) -> String {
// // let t = self.state.replace(Node::empty()); let s: String = self.kept.iter().collect();
// // Ok(t.root()) self.kept.clear();
// } s
// } }
}
#[derive(PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub enum Element { pub enum Element {
Empty, Empty,
Command(String), Command(String),
Literal(String), Literal(String),
Glob(String),
} }
impl fmt::Debug for Element { impl fmt::Debug for Element {
@ -144,6 +160,7 @@ impl fmt::Debug for Element {
Element::Empty => write!(f, "()"), Element::Empty => write!(f, "()"),
Element::Command(cmd) => write!(f, "cmd<{}>", cmd), Element::Command(cmd) => write!(f, "cmd<{}>", cmd),
Element::Literal(lit) => write!(f, "lit<{}>", lit), Element::Literal(lit) => write!(f, "lit<{}>", lit),
Element::Glob(glob) => write!(f, "glob<{}>", glob),
} }
} }
} }
@ -211,7 +228,9 @@ impl Tree {
self self
} else { } else {
let child = Node::child_of(Rc::clone(&self.target), elem); let child = Node::child_of(Rc::clone(&self.target), elem);
Tree{target: Rc::new(RefCell::new(child))} Tree {
target: Rc::new(RefCell::new(child)),
}
} }
} }
@ -287,7 +306,7 @@ impl Iterator for ChildIter {
} else { } else {
let child = Rc::clone(&self.parent.borrow().children[self.idx]); let child = Rc::clone(&self.parent.borrow().children[self.idx]);
self.idx += 1; self.idx += 1;
Some(Tree{target: child}) Some(Tree { target: child })
} }
} }
} }
@ -306,31 +325,6 @@ impl From<Node> for Tree {
} }
} }
// I don't know how to write a parser lol
// ls
// Command{name: "ls"}
// echo one two three
// Command{name: "echo", args: [Lit("one"), Lit("two"), Lit("three")]}
// echo *.rs
// Command{name: "echo", args: [Glob("*.rs")]}
// Command{name: "echo", args: [Path("main.rs"), Path("parse.rs"), ...]}
// cat main.rs | wc -l
// Pipe{
// src: Command{name: "cat", args: [Lit("main.rs")]}
// dest: Command{name: "wc", args: [Lit("-l")]}
// }
// echo one ; echo two
// Sequence{
// children: [
// Command{Name:
// ]
// }
pub fn parse<S: AsRef<str>>(text: S) -> Result<Tree, Error> { pub fn parse<S: AsRef<str>>(text: S) -> Result<Tree, Error> {
let mut tree = Tree::new(); let mut tree = Tree::new();
for token in lex(text)? { for token in lex(text)? {
@ -435,8 +429,7 @@ mod tests {
#[test] #[test]
fn tree_push() { fn tree_push() {
let tree = Tree::new() let tree = Tree::new().push(Element::Command(String::from("ls")));
.push(Element::Command(String::from("ls")));
assert_eq!(tree.peek(), Element::Command(String::from("ls"))); assert_eq!(tree.peek(), Element::Command(String::from("ls")));
let tree = Tree::new() let tree = Tree::new()
@ -455,9 +448,18 @@ mod tests {
assert_eq!(tree.children().count(), 3); assert_eq!(tree.children().count(), 3);
let mut args = tree.children(); let mut args = tree.children();
assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("one"))); assert_eq!(
assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("two"))); args.next().unwrap().peek(),
assert_eq!(args.next().unwrap().peek(), Element::Literal(String::from("three"))); 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()); assert!(args.next().is_none());
} }
} }

@ -4,12 +4,10 @@ use crate::{
line::Line, line::Line,
log::*, log::*,
output, output,
// parse::parse,
parse::{Element, Node}, parse::{Element, Node},
}; };
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::Rc;
use anyhow::Result; use anyhow::Result;
use dirs; use dirs;
@ -116,6 +114,7 @@ impl Shell {
) )
} }
Element::Literal(_) => todo!(), Element::Literal(_) => todo!(),
Element::Glob(_) => todo!(),
} }
} }

Loading…
Cancel
Save