mirror of
https://github.com/nushell/nushell
synced 2024-12-28 22:13:10 +00:00
parens
This commit is contained in:
parent
ba2e3d94eb
commit
fb42c94b79
2 changed files with 88 additions and 21 deletions
|
@ -101,6 +101,7 @@ pub enum Expr {
|
||||||
Call(Call),
|
Call(Call),
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
|
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), //lhs, op, rhs
|
||||||
|
Subexpression(Box<Block>),
|
||||||
Garbage,
|
Garbage,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,10 +147,10 @@ impl Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Import {}
|
pub enum Import {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub stmts: Vec<Statement>,
|
pub stmts: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
@ -190,13 +191,13 @@ impl Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VarDecl {
|
pub struct VarDecl {
|
||||||
var_id: VarId,
|
var_id: VarId,
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Pipeline(Pipeline),
|
Pipeline(Pipeline),
|
||||||
VarDecl(VarDecl),
|
VarDecl(VarDecl),
|
||||||
|
@ -205,7 +206,7 @@ pub enum Statement {
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Pipeline {}
|
pub struct Pipeline {}
|
||||||
|
|
||||||
impl Default for Pipeline {
|
impl Default for Pipeline {
|
||||||
|
@ -504,28 +505,81 @@ impl ParserWorkingSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_dollar_expr(&mut self, span: Span) -> (Expression, Option<ParseError>) {
|
||||||
|
let bytes = self.get_span_contents(span);
|
||||||
|
|
||||||
|
if let Some(var_id) = self.find_variable(bytes) {
|
||||||
|
let ty = *self
|
||||||
|
.get_variable(var_id)
|
||||||
|
.expect("internal error: invalid VarId");
|
||||||
|
|
||||||
|
(
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Var(var_id),
|
||||||
|
ty,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(garbage(span), Some(ParseError::VariableNotFound(span)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_full_column_path(&mut self, span: Span) -> (Expression, Option<ParseError>) {
|
||||||
|
// FIXME: assume for now a paren expr, but needs more
|
||||||
|
let bytes = self.get_span_contents(span);
|
||||||
|
let mut error = None;
|
||||||
|
|
||||||
|
let mut start = span.start;
|
||||||
|
let mut end = span.end;
|
||||||
|
|
||||||
|
if bytes.starts_with(b"(") {
|
||||||
|
start += 1;
|
||||||
|
}
|
||||||
|
if bytes.ends_with(b")") {
|
||||||
|
end -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let span = Span {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
file_id: span.file_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let source = self.get_file_contents(span.file_id);
|
||||||
|
|
||||||
|
let (output, err) = lex(&source[..end], span.file_id, start, crate::LexMode::Normal);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
println!("parsing subexpression: {:?} {:?}", output, error);
|
||||||
|
|
||||||
|
let (output, err) = lite_parse(&output);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let (output, err) = self.parse_block(&output);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
(
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Subexpression(Box::new(output)),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_arg(
|
pub fn parse_arg(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
shape: SyntaxShape,
|
shape: SyntaxShape,
|
||||||
) -> (Expression, Option<ParseError>) {
|
) -> (Expression, Option<ParseError>) {
|
||||||
let bytes = self.get_span_contents(span);
|
let bytes = self.get_span_contents(span);
|
||||||
if !bytes.is_empty() && bytes[0] == b'$' {
|
if bytes.starts_with(b"$") {
|
||||||
if let Some(var_id) = self.find_variable(bytes) {
|
return self.parse_dollar_expr(span);
|
||||||
let ty = *self
|
} else if bytes.starts_with(b"(") {
|
||||||
.get_variable(var_id)
|
return self.parse_full_column_path(span);
|
||||||
.expect("internal error: invalid VarId");
|
|
||||||
return (
|
|
||||||
Expression {
|
|
||||||
expr: Expr::Var(var_id),
|
|
||||||
ty,
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (garbage(span), Some(ParseError::VariableNotFound(span)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match shape {
|
match shape {
|
||||||
|
|
|
@ -156,6 +156,19 @@ impl ParserWorkingSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_file_contents(&self, file_id: usize) -> &[u8] {
|
||||||
|
if let Some(permanent_state) = &self.permanent_state {
|
||||||
|
let num_permanent_files = permanent_state.num_files();
|
||||||
|
if file_id < num_permanent_files {
|
||||||
|
&permanent_state.get_file_contents(file_id)
|
||||||
|
} else {
|
||||||
|
&self.files[file_id - num_permanent_files].1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
&self.files[file_id].1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enter_scope(&mut self) {
|
pub fn enter_scope(&mut self) {
|
||||||
self.scope.push(ScopeFrame::new());
|
self.scope.push(ScopeFrame::new());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue