Fix painting

This commit is contained in:
Yehuda Katz
2019-06-23 13:35:43 -04:00
parent 6af4dafd87
commit cbab97174e
11 changed files with 133 additions and 312 deletions

View File

@ -524,6 +524,7 @@ impl Call {
#[derive(new, Debug, Eq, PartialEq, Clone)]
pub struct Pipeline {
crate commands: Vec<Expression>,
crate trailing: Span,
crate span: Span,
}

View File

@ -98,7 +98,10 @@ pub fn baseline_parse_next_expr(
vec![string],
);
let path = hir::RawExpression::Path(Box::new(path));
Spanned { item: path, span: first.span }
Spanned {
item: path,
span: first.span,
}
}
Spanned {
item: hir::RawExpression::Literal(hir::Literal::String(inner)),
@ -114,7 +117,10 @@ pub fn baseline_parse_next_expr(
vec![string],
);
let path = hir::RawExpression::Path(Box::new(path));
Spanned { item: path, span: first.span }
Spanned {
item: path,
span: first.span,
}
}
Spanned {
item: hir::RawExpression::Variable(..),
@ -157,6 +163,7 @@ pub fn baseline_parse_semantic_token(
TokenNode::Whitespace(_span) => unreachable!(),
TokenNode::Error(error) => Err(*error.item.clone()),
TokenNode::Path(_path) => unimplemented!(),
TokenNode::EOF(_span) => unimplemented!(),
}
}

View File

@ -3,6 +3,7 @@ crate mod files;
crate mod flag;
crate mod operator;
crate mod parser;
crate mod pipeline;
crate mod span;
crate mod text;
crate mod token_tree;
@ -10,5 +11,3 @@ crate mod token_tree_builder;
crate mod tokens;
crate mod unit;
crate mod util;
crate use token_tree::{PipelineElement, TokenNode};

View File

@ -1,8 +1,8 @@
#![allow(unused)]
use crate::parser::parse2::{
call_node::*, flag::*, operator::*, span::*, token_tree::*, token_tree_builder::*, tokens::*,
unit::*,
call_node::*, flag::*, operator::*, pipeline::*, span::*, token_tree::*, token_tree_builder::*,
tokens::*, unit::*,
};
use nom;
use nom::branch::*;
@ -429,34 +429,63 @@ pub fn node(input: NomSpan) -> IResult<NomSpan, TokenNode> {
)
}
pub fn eof(input: NomSpan) -> IResult<NomSpan, TokenNode> {
if input.input_len() == 0 {
Ok((input, TokenNode::EOF(Span::from(input))))
} else {
Err(Err::Error(error_position!(
input,
nom::error::ErrorKind::Eof
)))
}
}
pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
trace_step(input, "pipeline", |input| {
let start = input.offset;
let (input, head) = tuple((raw_call, opt(space1)))(input)?;
let (input, head) = opt(tuple((raw_call, opt(space1), opt(tag("|")))))(input)?;
let (input, items) = trace_step(
input,
"many0",
many0(tuple((tag("|"), opt(space1), raw_call, opt(space1)))),
many0(tuple((opt(space1), raw_call, opt(space1), opt(tag("|"))))),
)?;
let (input, tail) = tuple((opt(space1), eof))(input)?;
let end = input.offset;
Ok((
input,
TokenTreeBuilder::spanned_pipeline(make_call_list(head, items), (start, end)),
TokenTreeBuilder::spanned_pipeline(
(make_call_list(head, items), tail.0.map(Span::from)),
(start, end),
),
))
})
}
fn make_call_list(
head: (Spanned<CallNode>, Option<NomSpan>),
tail: Vec<(NomSpan, Option<NomSpan>, Spanned<CallNode>, Option<NomSpan>)>,
head: Option<(Spanned<CallNode>, Option<NomSpan>, Option<NomSpan>)>,
items: Vec<(
Option<NomSpan>,
Spanned<CallNode>,
Option<NomSpan>,
Option<NomSpan>,
)>,
) -> Vec<PipelineElement> {
let mut out = vec![];
let el = PipelineElement::new(None, head.0, head.1.map(Span::from));
out.push(el);
for (pipe, ws1, call, ws2) in tail {
let el = PipelineElement::new(ws1.map(Span::from), call, ws2.map(Span::from));
if let Some(head) = head {
let el = PipelineElement::new(None, head.0, head.1.map(Span::from), head.2.map(Span::from));
out.push(el);
}
for (ws1, call, ws2, pipe) in items {
let el = PipelineElement::new(
ws1.map(Span::from),
call,
ws2.map(Span::from),
pipe.map(Span::from),
);
out.push(el);
}

View File

@ -0,0 +1,18 @@
use crate::parser::{CallNode, Span, Spanned};
use derive_new::new;
use getset::Getters;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, new)]
pub struct Pipeline {
crate parts: Vec<PipelineElement>,
crate post_ws: Option<Span>,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
pub struct PipelineElement {
pub pre_ws: Option<Span>,
#[get = "crate"]
call: Spanned<CallNode>,
pub post_ws: Option<Span>,
pub post_pipe: Option<Span>,
}

View File

@ -1,9 +1,8 @@
use crate::errors::ShellError;
use crate::parser::parse2::{call_node::*, flag::*, operator::*, span::*, tokens::*};
use crate::parser::parse2::{call_node::*, flag::*, operator::*, pipeline::*, span::*, tokens::*};
use crate::Text;
use derive_new::new;
use enum_utils::FromStr;
use getset::Getters;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum TokenNode {
@ -11,7 +10,7 @@ pub enum TokenNode {
#[allow(unused)]
Call(Spanned<CallNode>),
Delimited(Spanned<DelimitedNode>),
Pipeline(Spanned<Vec<PipelineElement>>),
Pipeline(Spanned<Pipeline>),
Operator(Spanned<Operator>),
Flag(Spanned<Flag>),
Identifier(Span),
@ -19,6 +18,7 @@ pub enum TokenNode {
#[allow(unused)]
Error(Spanned<Box<ShellError>>),
Path(Spanned<PathNode>),
EOF(Span),
}
impl TokenNode {
@ -34,6 +34,7 @@ impl TokenNode {
TokenNode::Whitespace(s) => *s,
TokenNode::Error(s) => s.span,
TokenNode::Path(s) => s.span,
TokenNode::EOF(s) => *s,
}
}
@ -66,7 +67,7 @@ impl TokenNode {
}
}
pub fn as_pipeline(&self) -> Result<Vec<PipelineElement>, ShellError> {
pub fn as_pipeline(&self) -> Result<Pipeline, ShellError> {
match self {
TokenNode::Pipeline(Spanned { item, .. }) => Ok(item.clone()),
_ => Err(ShellError::string("unimplemented")),
@ -92,11 +93,3 @@ pub struct PathNode {
head: Box<TokenNode>,
tail: Vec<TokenNode>,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
pub struct PipelineElement {
pub pre_ws: Option<Span>,
#[get = "crate"]
call: Spanned<CallNode>,
pub post_ws: Option<Span>,
}

View File

@ -3,10 +3,9 @@ use crate::prelude::*;
use crate::parser::parse2::flag::{Flag, FlagKind};
use crate::parser::parse2::operator::Operator;
use crate::parser::parse2::pipeline::{Pipeline, PipelineElement};
use crate::parser::parse2::span::{Span, Spanned};
use crate::parser::parse2::token_tree::{
DelimitedNode, Delimiter, PathNode, PipelineElement, TokenNode,
};
use crate::parser::parse2::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
use crate::parser::parse2::tokens::{RawToken, Token};
use crate::parser::parse2::unit::Unit;
use crate::parser::CallNode;
@ -47,7 +46,7 @@ impl TokenTreeBuilder {
let mut out: Vec<PipelineElement> = vec![];
let mut input = input.into_iter();
let mut input = input.into_iter().peekable();
let (pre, call, post) = input
.next()
.expect("A pipeline must contain at least one element");
@ -55,33 +54,48 @@ impl TokenTreeBuilder {
let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b);
let post_span = post.map(|post| b.consume(&post));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new(
pre_span.map(Span::from),
call,
post_span.map(Span::from),
pipe,
));
for (pre, call, post) in input {
b.consume("|");
let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b);
let post_span = post.map(|post| b.consume(&post));
loop {
match input.next() {
None => break,
Some((pre, call, post)) => {
let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b);
let post_span = post.map(|post| b.consume(&post));
out.push(PipelineElement::new(
pre_span.map(Span::from),
call,
post_span.map(Span::from),
));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new(
pre_span.map(Span::from),
call,
post_span.map(Span::from),
pipe,
));
}
}
}
let end = b.pos;
TokenTreeBuilder::spanned_pipeline(out, (start, end))
TokenTreeBuilder::spanned_pipeline((out, None), (start, end))
})
}
pub fn spanned_pipeline(input: Vec<PipelineElement>, span: impl Into<Span>) -> TokenNode {
TokenNode::Pipeline(Spanned::from_item(input, span))
pub fn spanned_pipeline(
input: (Vec<PipelineElement>, Option<Span>),
span: impl Into<Span>,
) -> TokenNode {
TokenNode::Pipeline(Spanned::from_item(
Pipeline::new(input.0, input.1.into()),
span,
))
}
pub fn op(input: impl Into<Operator>) -> CurriedToken {