Skip to content

Commit

Permalink
Simplify final parsing, make compile with MSRV.
Browse files Browse the repository at this point in the history
  • Loading branch information
01mf02 committed Jun 28, 2024
1 parent 08947bd commit 9cc0187
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 29 deletions.
3 changes: 1 addition & 2 deletions jaq-syn/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,14 @@ impl From<&parse::Def<&str, parse::Term<&str>>> for Def {

impl From<&parse::Term<&str>> for Main {
fn from(tm: &parse::Term<&str>) -> Self {
use alloc::string::ToString;
match tm {
parse::Term::Def(defs, tm) => Main {
defs: defs.iter().map(Def::from).collect(),
body: ((&**tm).into(), 0..42),
},
tm => Main {
defs: Vec::new(),
body: ((&*tm).into(), 0..42),
body: (tm.into(), 0..42),
},
}
}
Expand Down
19 changes: 11 additions & 8 deletions jaq-syn/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,19 +206,19 @@ impl From<&parse::Term<&str>> for Filter {
})),
Arr(a) => Self::Array(a.as_deref().map(span)),
Obj(o) => Self::Object(o.iter().map(from_obj).collect()),
Neg(tm) => Self::Neg(span(&*tm)),
Neg(tm) => Self::Neg(span(tm)),
Pipe(l, v, r) => Self::Binary(
span(&*l),
span(l),
BinaryOp::Pipe(v.map(|v| v[1..].to_string())),
span(&*r),
span(r),
),
BinOp(head, tail) => {
let head = *span(head);
let tail = tail.iter().map(|(op, tm)| (from_op(op), *span(tm)));
prec_climb::climb(head, tail).0
}

Label(v, ..) | Break(v) => unimplemented!("label-break is not supported yet"),
Label(_v, ..) | Break(_v) => unimplemented!("label-break is not supported yet"),

Fold(fold, xs, v, args) => {
let fold_type = match *fold {
Expand All @@ -227,12 +227,15 @@ impl From<&parse::Term<&str>> for Filter {
"for" => FoldType::For,
_ => panic!(),
};
let [init, update] = &args[..] else { panic!() };
let (init, update) = match &args[..] {
[init, update] => (init, update),
_ => todo!(),
};
let fold = self::Fold {
xs: span(&*xs),
xs: span(xs),
x: v[1..].to_string(),
init: span(&init),
f: span(&update),
init: span(init),
f: span(update),
};
Self::Fold(fold_type, fold)
}
Expand Down
33 changes: 20 additions & 13 deletions jaq-syn/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ impl<'a> Parser<'a> {
}
}

pub fn verify_last(&mut self, last: &'a str) {
fn verify_last(&mut self, last: &'a str) -> Result<'a, ()> {
let last_char = || last.chars().next().unwrap();
match (self.i.as_slice(), last) {
([], "") => (),
([Token::Char(c)], last) if *c == last => (),
([], _) => self.e.push((Expect::Char(last_char()), None)),
([next, ..], "") => self.e.push((Expect::Nothing, Some(next))),
([next, ..], _) => self.e.push((Expect::Char(last_char()), Some(next))),
([], "") => Ok(()),
([Token::Char(c)], last) if *c == last => Ok(()),
([], _) => Err((Expect::Char(last_char()), None)),
([next, ..], "") => Err((Expect::Nothing, Some(next))),
([next, ..], _) => Err((Expect::Char(last_char()), Some(next))),
}
}

Expand All @@ -93,19 +93,26 @@ impl<'a> Parser<'a> {
y
}

pub fn ok_or_default<T: Default>(&mut self, y: Result<'a, T>) -> T {
y.unwrap_or_else(|e| {
self.e.push(e);
T::default()
})
pub fn finish<T: Default, F>(&mut self, last: &'a str, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<'a, T>,
{
f(self)
.and_then(|y| {
self.verify_last(last)?;
Ok(y)
})
.unwrap_or_else(|e| {
self.e.push(e);
T::default()
})
}

fn with<T: Default, F>(&mut self, tokens: &'a [Token<&'a str>], last: &'a str, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<'a, T>,
{
let y = self.with_tok(tokens, |p| f(p).inspect(|_| p.verify_last(last)));
self.ok_or_default(y)
self.with_tok(tokens, |p| p.finish(last, f))
}

fn maybe<T>(&mut self, f: impl Fn(&mut Self) -> Option<T>) -> Option<T> {
Expand Down
8 changes: 2 additions & 6 deletions jaq/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,7 @@ fn parse(filter_str: &str, vars: Vec<String>) -> Result<Filter, Vec<ParseError>>
let (tokens, lex_errs) = jaq_syn::lex::Lexer::new(std).lex();
assert!(lex_errs.is_empty());
let mut parser = jaq_syn::parse::Parser::new(&tokens);
let std = parser
.module(|p| p.defs())
.inspect(|_| parser.verify_last(""));
let std = parser.ok_or_default(std);
let std = parser.finish("", |p| p.module(|p| p.defs()));
assert!(parser.e.is_empty());
let std: Vec<_> = std.body.iter().map(jaq_syn::Def::from).collect();
defs.insert_defs(std);
Expand All @@ -272,8 +269,7 @@ fn parse(filter_str: &str, vars: Vec<String>) -> Result<Filter, Vec<ParseError>>
let (tokens, lex_errs) = jaq_syn::lex::Lexer::new(filter_str).lex();
if lex_errs.is_empty() {
let mut parser = jaq_syn::parse::Parser::new(&tokens);
let main = parser.module(|p| p.term()).inspect(|_| parser.verify_last(""));
let main = parser.ok_or_default(main);
let main = parser.finish("", |p| p.module(|p| p.term()));
std::println!("{:?}", main);
std::println!("{:?}", jaq_syn::Main::from(&main.body));
std::println!("{:?}", parser.e);
Expand Down

0 comments on commit 9cc0187

Please sign in to comment.