This commit is contained in:
JT 2021-07-02 19:15:30 +12:00
parent ba2e3d94eb
commit fb42c94b79
2 changed files with 88 additions and 21 deletions

View file

@ -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,30 +505,83 @@ impl ParserWorkingSet {
} }
} }
pub fn parse_arg( pub fn parse_dollar_expr(&mut self, span: Span) -> (Expression, Option<ParseError>) {
&mut self,
span: Span,
shape: SyntaxShape,
) -> (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 let Some(var_id) = self.find_variable(bytes) { if let Some(var_id) = self.find_variable(bytes) {
let ty = *self let ty = *self
.get_variable(var_id) .get_variable(var_id)
.expect("internal error: invalid VarId"); .expect("internal error: invalid VarId");
return (
(
Expression { Expression {
expr: Expr::Var(var_id), expr: Expr::Var(var_id),
ty, ty,
span, span,
}, },
None, None,
); )
} else { } else {
return (garbage(span), Some(ParseError::VariableNotFound(span))); (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(
&mut self,
span: Span,
shape: SyntaxShape,
) -> (Expression, Option<ParseError>) {
let bytes = self.get_span_contents(span);
if bytes.starts_with(b"$") {
return self.parse_dollar_expr(span);
} else if bytes.starts_with(b"(") {
return self.parse_full_column_path(span);
}
match shape { match shape {
SyntaxShape::Number => { SyntaxShape::Number => {
if let Ok(token) = String::from_utf8(bytes.into()) { if let Ok(token) = String::from_utf8(bytes.into()) {

View file

@ -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());
} }