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::{
fmt,
ops::Deref,
cell::RefCell,
rc::Rc,
};
use std::{cell::RefCell, fmt, rc::Rc};
use thiserror::Error;
#[derive(Debug, Error)]
@ -17,6 +11,7 @@ pub enum Error {
#[derive(Debug, PartialEq)]
pub enum Token {
Ident(String),
Glob(String),
Pipe,
}
@ -28,6 +23,7 @@ fn lex<S: AsRef<str>>(text: S) -> Result<Vec<Token>, Error> {
struct Lexer<'text> {
chars: std::str::Chars<'text>,
peeked: Option<char>,
kept: Vec<char>,
}
impl<'text> Lexer<'text> {
@ -35,6 +31,7 @@ impl<'text> Lexer<'text> {
Self {
chars: text.chars(),
peeked: None,
kept: Vec::new(),
}
}
@ -48,6 +45,9 @@ impl<'text> Lexer<'text> {
tokens.push(Token::Pipe);
self.skip();
}
Some('*') => {
tokens.push(self.glob());
}
Some(_) => {
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 {
let mut kept: Vec<char> = vec![];
loop {
match self.peek() {
None => break,
Some('*') => {
self.keep();
self.glob();
},
Some(c) => {
if c.is_whitespace() {
break;
}
kept.push(c);
self.skip();
self.keep();
}
}
}
Token::Ident(self.pop())
}
fn glob(&mut self) -> Token {
loop {
match self.peek() {
None => break,
Some(c) => {
if c.is_whitespace() {
break;
}
self.keep();
}
}
Token::Ident(kept.iter().collect())
}
Token::Glob(self.pop())
}
// struct Parser {
// 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())
// }
// }
fn pop(&mut self) -> String {
let s: String = self.kept.iter().collect();
self.kept.clear();
s
}
}
#[derive(PartialEq, Clone)]
pub enum Element {
Empty,
Command(String),
Literal(String),
Glob(String),
}
impl fmt::Debug for Element {
@ -144,6 +160,7 @@ impl fmt::Debug for Element {
Element::Empty => write!(f, "()"),
Element::Command(cmd) => write!(f, "cmd<{}>", cmd),
Element::Literal(lit) => write!(f, "lit<{}>", lit),
Element::Glob(glob) => write!(f, "glob<{}>", glob),
}
}
}
@ -211,7 +228,9 @@ impl Tree {
self
} else {
let child = Node::child_of(Rc::clone(&self.target), elem);
Tree{target: Rc::new(RefCell::new(child))}
Tree {
target: Rc::new(RefCell::new(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> {
let mut tree = Tree::new();
for token in lex(text)? {
@ -435,8 +429,7 @@ mod tests {
#[test]
fn tree_push() {
let tree = Tree::new()
.push(Element::Command(String::from("ls")));
let tree = Tree::new().push(Element::Command(String::from("ls")));
assert_eq!(tree.peek(), Element::Command(String::from("ls")));
let tree = Tree::new()
@ -455,9 +448,18 @@ mod tests {
assert_eq!(tree.children().count(), 3);
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_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());
}
}

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

Loading…
Cancel
Save