Fix parsing vars and funcs

This commit is contained in:
Richard Feldman 2019-04-19 20:53:14 -04:00
parent 5c9c77dbe0
commit 6c84cb43fc
2 changed files with 34 additions and 46 deletions

View file

@ -44,8 +44,7 @@ parser! {
), ),
string_literal(), string_literal(),
number_literal(), number_literal(),
var(), func_or_var(),
func(),
)).skip(spaces()).and( )).skip(spaces()).and(
// Optionally follow the expression with an operator, // Optionally follow the expression with an operator,
// //
@ -79,21 +78,20 @@ where I: Stream<Item = char>,
)) ))
} }
pub fn var<I>() -> impl Parser<Input = I, Output = Expr> pub fn func_or_var<I>() -> impl Parser<Input = I, Output = Expr>
where I: Stream<Item = char>,
I::Error: ParseError<I::Item, I::Range, I::Position>
{
ident().map(|str| Expr::Var(str))
}
pub fn func<I>() -> impl Parser<Input = I, Output = Expr>
where I: Stream<Item = char>, where I: Stream<Item = char>,
I::Error: ParseError<I::Item, I::Range, I::Position> I::Error: ParseError<I::Item, I::Range, I::Position>
{ {
ident() ident()
.skip(many1::<Vec<_>, _>(space())) .and(optional(
.and(expr()) many1::<Vec<_>, _>(space())
.map(|(str, arg)| Expr::Func(str, Box::new(arg))) .with(expr())
)).map(|(str, opt_arg)|
match opt_arg {
Some(arg) => Expr::Func(str, Box::new(arg)),
None => Expr::Var(str),
}
)
} }
pub fn ident<I>() -> impl Parser<Input = I, Output = String> pub fn ident<I>() -> impl Parser<Input = I, Output = String>

View file

@ -8,6 +8,7 @@ extern crate roc;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use roc::expr::Expr::*; use roc::expr::Expr::*;
use roc::expr::Expr;
use roc::expr::Operator::*; use roc::expr::Operator::*;
use roc::parse; use roc::parse;
use combine::{Parser}; use combine::{Parser};
@ -246,7 +247,6 @@ mod tests {
} }
fn expect_parsed_var_error<'a>(actual_str: &'a str) { fn expect_parsed_var_error<'a>(actual_str: &'a str) {
// TODO someday, this should work! It should parse as a variant.
assert!( assert!(
parse::expr().parse(actual_str).is_err(), parse::expr().parse(actual_str).is_err(),
"Expected parsing error" "Expected parsing error"
@ -286,39 +286,29 @@ mod tests {
// TODO try it with operators, e.g. foo bar + baz qux // TODO try it with operators, e.g. foo bar + baz qux
// fn expect_parsed_func<'a>(expected_str: &'a str) { fn expect_parsed_func<'a>(parse_str: &'a str, func_str: &'a str, expr: Expr) {
// let expected = expected_str.to_string(); assert_eq!(
Ok((Func(func_str.to_string(), Box::new(expr)), "")),
parse::expr().parse(parse_str)
);
}
// assert_eq!(Ok((Var(expected), "")), parse::expr().parse(expected_str)); fn expect_parsed_func_error<'a>(actual_str: &'a str) {
// } assert!(
parse::expr().parse(actual_str).is_err(),
"Expected parsing error"
);
}
// fn expect_parsed_func_error<'a>(actual_str: &'a str) { #[test]
// // TODO someday, this should work! It should parse as a variant. fn parse_func() {
// assert!( expect_parsed_func("f 1", "f", Int(1));
// parse::expr().parse(actual_str).is_err(), expect_parsed_func("foo bar", "foo", Var("bar".to_string()));
// "Expected parsing error" expect_parsed_func("foo \"hi\"", "foo", String("hi".to_string()));
// ); }
// }
// #[test] #[test]
// fn parse_var() { fn parse_invalid_func() {
// expect_parsed_var("x"); expect_parsed_func_error("1 f");
// expect_parsed_var("x2"); }
// expect_parsed_var("foo");
// expect_parsed_var("foo2furious");
// }
// #[test]
// fn parse_invalid_var() {
// expect_parsed_var_error("5x");
// expect_parsed_var_error("2foo2furious");
// expect_parsed_var_error("2Foo2Furious");
// // TODO someday, capitalized vars should parse successfully as variants.
// // At that point, turn these into variant tests!
// expect_parsed_var_error("X");
// expect_parsed_var_error("X2");
// expect_parsed_var_error("Foo");
// expect_parsed_var_error("Foo2Furious");
// }
} }