diff --git a/schala-lang/language/src/parser.rs b/schala-lang/language/src/parser.rs index 0b1ad2c..8a4e234 100644 --- a/schala-lang/language/src/parser.rs +++ b/schala-lang/language/src/parser.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use nom::IResult; use nom::character::complete::{one_of, space0}; -use nom::bytes::complete::{tag, take_while}; +use nom::bytes::complete::{tag, take_while, take_until}; use nom::combinator::{map, map_res, value, opt}; use nom::multi::many1; use nom::error::{ParseError, ErrorKind}; @@ -27,11 +27,11 @@ fn parse_binop(input: &str) -> IResult<&str, BinOp> { fn parse_bool_literal(input: &str) -> IResult<&str, ExpressionKind> { - let (rest, value) = alt(( + let p = alt(( value(true, tag("true")), value(false, tag("false")) - ))(input)?; - Ok((rest, ExpressionKind::BoolLiteral(value))) + )); + map(p, ExpressionKind::BoolLiteral)(input) } fn parse_number_literal(input: &str) -> IResult<&str, ExpressionKind> { @@ -71,9 +71,10 @@ fn parse_hex_literal(input: &str) -> IResult<&str, ExpressionKind> { } fn parse_string_literal(text: &str) -> IResult<&str, ExpressionKind> { - let (text, _) = nom::character::complete::char('"')(text)?; - let (text, string_output) = nom::bytes::complete::take_until("\"")(text)?; - let (text, _) = nom::character::complete::char('"')(text)?; + use nom::character::complete::char; + let (text, string_output) = delimited( + char('"'), take_until("\""), char('"') + )(text)?; let expr = ExpressionKind::StringLiteral(Rc::new(string_output.to_string())); Ok((text, expr)) } @@ -88,45 +89,28 @@ fn parse_literal(input: &str) -> IResult<&str, ExpressionKind> { ))(input) } -fn paren_expr(input: &str) -> IResult<&str, ExpressionKind> { - let (rest, _) = nom::character::complete::char('(')(input)?; - let (rest, inner) = expression_kind(rest)?; - let (rest, _) = nom::character::complete::char(')')(rest)?; - Ok((rest, inner)) +fn paren_expr(text: &str) -> IResult<&str, ExpressionKind> { + use nom::character::complete::char; + delimited(char('('), expression_kind, char(')'))(text) } fn prefix_op(input: &str) -> IResult<&str, PrefixOp> { use nom::character::complete::char; - let (rest, sigil) = alt(( - char('+'), - char('-'), - char('!') - ))(input)?; - let op = PrefixOp::from_str(&sigil.to_string()).unwrap(); - Ok((rest, op)) - - /* - alt(( - value(Plus, char('+')), - value(Minus, char('-')), - value(Bang, char('!')) - ))(input) - */ + let p = alt((char('+'), char('-'), char('!'))); + map(p, |sigil| PrefixOp::from_str(&sigil.to_string()).unwrap())(input) } -fn prefix_expr(input: &str) -> IResult<&str, ExpressionKind> { - let (rest, _) = space0(input)?; - let (rest, pfx) = opt(prefix_op)(rest)?; - let (rest, _) = space0(rest)?; - let (rest, result) = alt(( +fn prefix_expr(text: &str) -> IResult<&str, ExpressionKind> { + let (text, pfx) = delimited(space0, opt(prefix_op), space0)(text)?; + let (text, result) = alt(( paren_expr, parse_literal - ))(rest)?; + ))(text)?; match pfx { - None => Ok((rest, result)), + None => Ok((text, result)), Some(pfx) => { let exp = Expression { id: ItemId::new(0), kind: result, type_anno: None }; - Ok((rest, ExpressionKind::PrefixExp(pfx, Box::new(exp)))) + Ok((text, ExpressionKind::PrefixExp(pfx, Box::new(exp)))) } } }