82 lines
2.1 KiB
Rust
82 lines
2.1 KiB
Rust
|
use crate::lst_parser::{error::SyntaxError, syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||
|
|
||
|
use self::{collection::collection, instruction::instr, lit::literal, pipeline::PIPES};
|
||
|
|
||
|
mod collection;
|
||
|
mod instruction;
|
||
|
mod lit;
|
||
|
mod pipeline {
|
||
|
use enumset::enum_set;
|
||
|
|
||
|
use crate::lst_parser::{
|
||
|
error::SyntaxError,
|
||
|
syntax_kind::{SyntaxKind::*, TokenSet},
|
||
|
CompletedMarker, Parser,
|
||
|
};
|
||
|
|
||
|
use super::expression;
|
||
|
|
||
|
pub fn pipeline(p: &mut Parser, start_expr: CompletedMarker) -> Option<CompletedMarker> {
|
||
|
if !pipe(p) {
|
||
|
return Some(start_expr);
|
||
|
}
|
||
|
let pipeline_marker = start_expr.precede(p, "pipeline_start");
|
||
|
|
||
|
loop {
|
||
|
if expression(p, true).is_none() {
|
||
|
return Some(pipeline_marker.complete_err(p, SyntaxError::PipelineNeedsSink));
|
||
|
}
|
||
|
if !pipe(p) {
|
||
|
return Some(pipeline_marker.complete(p, PIPELINE));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub const PIPES: TokenSet = enum_set!(PIPE | MAPPING_PIPE | NULL_PIPE);
|
||
|
|
||
|
fn pipe(p: &mut Parser) -> bool {
|
||
|
if PIPES.contains(p.current()) {
|
||
|
p.do_bump();
|
||
|
true
|
||
|
} else {
|
||
|
false
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn expression(p: &mut Parser, in_pipe: bool) -> Option<CompletedMarker> {
|
||
|
let expr = p.start("expr");
|
||
|
|
||
|
if atom(p).or_else(|| instr(p)).is_none() {
|
||
|
expr.abandon(p);
|
||
|
return None;
|
||
|
}
|
||
|
|
||
|
let r = expr.complete(p, EXPR);
|
||
|
|
||
|
if PIPES.contains(p.current()) && !in_pipe {
|
||
|
pipeline::pipeline(p, r)
|
||
|
} else {
|
||
|
Some(r)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn atom(p: &mut Parser) -> Option<CompletedMarker> {
|
||
|
literal(p)
|
||
|
.or_else(|| collection(p))
|
||
|
.or_else(|| parenthesized_expr(p))
|
||
|
}
|
||
|
|
||
|
pub fn parenthesized_expr(p: &mut Parser) -> Option<CompletedMarker> {
|
||
|
if p.eat(L_PAREN) {
|
||
|
let par_expr = p.start("parenthesized");
|
||
|
expression(p, false);
|
||
|
if !p.eat(R_PAREN) {
|
||
|
return Some(par_expr.complete_err(p, SyntaxError::Expected(vec![R_PAREN])));
|
||
|
}
|
||
|
|
||
|
return Some(par_expr.complete(p, PARENTHESIZED_EXPR));
|
||
|
}
|
||
|
None
|
||
|
}
|